Agents

Define, deploy, and run Lunnoa agents with @lunnoa/client.

Use @lunnoa/client to build agents as code and run them from your own apps. You author a typed definition, deploy it into a project, then open chat tasks over the Public API. Lunnoa owns runtime, authorisation, connections, and audit logging so engineers can focus on the agent’s behaviour.

Coding agents (Cursor, Claude Code, and similar) can drive this flow with the packaged skills. See For agents.

Goal

By the end of this guide you will:

  1. Define an agent with defineAgent
  2. Deploy it with the CLI (agents deploy)
  3. Run a chat turn with agentChat.streamMessage

Requirements

  • Node.js 20 or newer
  • A Lunnoa Automate deployment URL
  • A workspace API key (lna_…) with permission to manage and use agents in the target project
  • A project id (LUNNOA_PROJECT_ID)
  • An AI connection already configured in Automate (deploy does not create connections)

1. Define the agent locally

defineAgent is pure typed config. Nothing is written to the platform until you deploy.

agents/support-triage.ts
import {  defineAction,  defineAgent,  defineAiConnection,} from '@lunnoa/client';export default defineAgent({  slug: 'support-triage',  name: 'Support triage',  model: 'gpt-4o',  instructions:    'Triage inbound support requests. Be concise. Escalate policy exceptions.',  aiConnection: defineAiConnection({    id: process.env.AI_CONNECTION_ID,  }),  tools: [    defineAction({ id: 'http_action_send-request' }),  ],});

Upsert identity is the project-scoped slug. Nested defineWorkflow tools are supported: deploy creates those workflows first, then links them via workflowIds. Full factory table: Define locally.

Omit aiConnection when the workspace has a sole usable or default AI connection. Otherwise pass the connection UUID. Credentials stay on Lunnoa; never put secrets in the definition file.

2. Deploy into Automate

Prefer the CLI happy path. The agent appears in the Automate UI with managedByCode set.

deploy-agent.sh
npx @lunnoa/client agents deploy ./agents/support-triage.ts \  --url https://lunnoa.your-company.example \  --api-key "$LUNNOA_API_KEY" \  --project-id "$LUNNOA_PROJECT_ID"

Flags and env fallbacks: --url / LUNNOA_URL, --api-key / LUNNOA_API_KEY, --project-id / LUNNOA_PROJECT_ID. Optional lunnoa.config.ts in the working directory can supply the same values.

For TypeScript definition files, run under Node with --experimental-strip-types (Node 22+) or use tsx.

Details, catalogue discovery, and workflow deploy: CLI.

3. Run the agent (chat)

After deploy, resolve the agent id (Automate UI, agents.list, or codegen) and stream a turn. A task is one conversation thread. Client-generated UUIDs are fine; the first message creates the task.

run-agent.ts
import { LunnoaClient } from '@lunnoa/client';const lunnoa = new LunnoaClient({  baseUrl: process.env.LUNNOA_URL!,  apiKey: process.env.LUNNOA_API_KEY!, // server-side only});const agentId = process.env.AGENT_ID!;const taskId = crypto.randomUUID();const stream = await lunnoa.agentChat.streamMessage(  agentId,  taskId,  'Summarise open tickets for customer ACME.',);for await (const chunk of stream) {  if (chunk.type === 'text-delta') process.stdout.write(chunk.delta);}// History (UIMessage format)const task = await lunnoa.tasks.get(taskId, { expansion: ['messages'] });

For React UIs, prefer useAgentChat from @lunnoa/client/react. Resume and stop helpers, chunk types, and proxy notes: Agent chat.

With deployment codegen you can call agents by generated name (for example lunnoa.agents.supportTriage.streamMessage(...)). See Codegen.

What Lunnoa handles for you

ConcernPlatform behaviour
RuntimeModel calls, tool rounds, and streaming run on Automate
AuthorisationAPI keys / JWTs and RBAC decide who may deploy, list, and chat
ConnectionsSecrets and app credentials stay in workspace connections
Logging and auditChat turns and tool use are persisted on the deployment
ReuseCatalogue actions and connections are shared across agents and workflows

Your job is the agent definition, tools, and the product UI. Lunnoa is the control plane.

Auth patterns

PatternWhen
A. Backend holds lna_…Server scripts, BFF, background jobs
B. End-user JWTBrowser apps where per-user agent shares and task history matter

Never ship an API key to the browser. Full detail: Authentication and API authentication.

Related

GuideWhen
For agentsCursor / Claude skills and playbook
Define locallydefineAgent / defineWorkflow / defineAction
CLIDiscover tools, then upsert by slug
Agent chatSSE streaming depth
WorkflowsTrigger and wait on workflow runs
API referenceFull Public API operation list