N AgentNava
AgentNava · Documentation

Build agents.
Put them in your product.

Describe an agent in one object and run it on a managed runtime. It executes the loop, calls the tools, works with files, and streams typed events back for you to render anywhere.

Install

npm install @cerebro-labs/agentnava-sdk
# or: bun add @cerebro-labs/agentnava-sdk
# or: pnpm add @cerebro-labs/agentnava-sdk

Node 18 or later. Works in any runtime with fetch.

Hand it to a coding agent

If you use Claude Code, Codex or Cursor, paste this and it will install the SDK, write a real agent, run it and stream the first reply.

One prompt → working agent
Paste this into Claude Code, Codex, or Cursor. It installs the SDK, scaffolds a real agent end-to-end as TypeScript, runs it, and streams the first reply.
Set up @cerebro-labs/agentnava-sdk in this project end-to-end. There is no CLI and nothing runs locally: agents run on the AgentNava backend and you talk to them over the SDK.

Step 0: Naming. Ask me what the agent should do in one sentence, and what to call it. Use my answer for `name` and for the filenames below.

Step 1: Package manager. Detect from the lockfile (bun.lockb → bun, pnpm-lock.yaml → pnpm, yarn.lock → yarn, otherwise npm). Use it consistently.

Step 2: Install `@cerebro-labs/agentnava-sdk`.

Step 3: API key. Confirm `AGENTNAVA_API_KEY` is set in `.env`. If not, stop and tell me to generate one at https://console.agentnava.com. Do not proceed until I confirm.

Step 4: Write the agent. One object, no separate spec file:

    import { AgentNava } from '@cerebro-labs/agentnava-sdk';

    const ws = new AgentNava();

    const agent = await ws.agents.create({
      name: '<Display Name>',
      instructions: `<who the agent is, what it is for, how it should answer>`,
      workflows: [
        {
          name: '<procedure name>',
          when: '<the condition that makes this the right procedure>',
          content: `<numbered steps, the way you would write them for a new hire>`,
        },
      ],
    });

Rules for what you write there:
  • `instructions` is who the agent is. Keep it short and specific.
  • `when` on a workflow is the condition that makes the procedure the right one. "A customer reports a late delivery", not "Refund handling". It is the only thing the agent reads to decide the procedure applies.
  • Do not invent fields. The full set is name, instructions, id, greeting, grade, filesystem, tools, workflows, connections, secrets, parameters, triggers, mcpServers, httpTools.

Step 5: Start a conversation and stream one turn.

    const conversation = await agent.start();

    for await (const event of conversation.ask('<a realistic first question>')) {
      if (event.type === 'text') process.stdout.write(event.text);
      if (event.type === 'done') console.log('\n', conversation.id);
    }

Step 6: Run it. `bun run <file>.ts`, or `tsx <file>.ts` for npm/pnpm. Wait for the reply to stream.

Step 7: Print a short summary: the agent id, the conversation id, and what to try next. Tell me to store both, because `ws.agent(id)` and `ws.conversation(id)` are how you come back to them later without a round trip.

Do not deploy anything, there is no deploy step. Do not modify unrelated files. Ask before any ambiguous choice.

Reference: https://docs.agentnava.com

Authenticate

import { AgentNava } from '@cerebro-labs/agentnava-sdk';

const ws = new AgentNava();                   // reads AGENTNAVA_API_KEY
const ws = new AgentNava({ apiKey: '...' });  // or pass it

An API key belongs to exactly one workspace, so the object you construct is that workspace. Everything you create is created in it, and no call takes a workspace argument.

await ws.get();     // { id, name, credits, createdAt }

credits is your remaining balance. A turn costs one credit at standard grade and five at premium.

Three calls

const agent = await ws.agents.create({
  name: 'Refund checker',
  instructions: 'You help a support agent decide whether a refund is warranted.',
});

const conversation = await agent.start();

console.log(await conversation.ask('Order 4471 was nine days late. Refund?'));

No deploy step. An agent is usable the moment you create it. There is no spec to push, no version to promote and nothing running on your machine: agents run on our runtime and you talk to them over the SDK.

Streaming

The same call, iterated instead of awaited:

for await (const e of conversation.ask('Order 4471 was nine days late. Refund?')) {
  if (e.type === 'text')     process.stdout.write(e.text);
  if (e.type === 'progress') showSteps(e.steps);
  if (e.type === 'done')     console.log('\n', e.reply);
}

Ask once: the message is sent when you call ask, not when you await or iterate. See Conversations for every event.

Coming back to it

Store agent.id and conversation.id in your own database. You do not hold the objects between requests, and you do not need to:

const conversation = ws.conversation(row.conversationId);   // no network call
await conversation.ask(message);

Which id you stored decides what you get. An agent id gives you a new conversation; a conversation id continues an existing one.

Where to go next

If you want to
Tell it how to do a specific jobWorkflows
Give it documents to answer fromKnowledge and files
Let it reach Gmail, or your own APIConnections and Tools
Run it on a scheduleTriggers
Put several agents on one goalProjects
See the whole surface at onceTypes and errors