Guides
Agents
Write agents as Markdown files or let your users build them in the dashboard.
An agent is a set of instructions, a provider and model, and the tools it may call. You write the agents your app depends on as files, so they are reviewed and versioned with your code. Your users build their own agents in the dashboard.
Writing an Agent in Code
Each Markdown file in server/agents is an agent. The file name is its slug, the first heading is
its name, and the rest is its instructions:
---
provider: 'anthropic'
model: 'claude-sonnet-5-5'
tools: ['customer_list', 'customer_get', 'web_fetch']
---
# Support
Answer questions about customers and their plans, clearly and briefly.
## Boundaries
- Never change customer records. Hand changes to the account manager.
- Say so when you cannot find a customer instead of guessing.
| Setting | Values | Default |
|---|---|---|
provider | openai, anthropic, google, or mock | anthropic |
model | The provider's model ID | claude-sonnet-5-5 |
tools | Tool names: your tools, model tools, integration actions, and web_fetch | none |
tool_choice | auto, required, or none | auto |
runtime | api, or codex or claude for local CLIs | api |
local_model | Model name for the local CLI, such as sonnet; empty uses the CLI's default | '' |
status | active or draft | active |
Invalid tool names and settings fail at startup. The error includes the file path, such as
server/agents/support.md:. Code agents are read-only in the dashboard. Each workspace gets its
own copy and run history; the copy updates when the source file changes.
The Nuxt layer generates types from these files, so useDurableAgent('support') accepts only
slugs that exist.
Letting Users Build Agents
Users create agents at /dashboard/agents: name, instructions, model, and tools, with autosave
and a test run panel. They can enable integration actions that the workspace has connected and
granted.
Running an Agent from Your Own Page
useDurableAgent() starts a run and follows it live:
const { agent, start, output, status, error, cancel } = useDurableAgent('support')
await start('Which customers are on the pro plan?')
start() resolves when the run is accepted. Read status and output for progress. Durable runs
continue after the tab closes and pause at waiting for approval.
To follow a run selected elsewhere, call useAgentRun(agentId, runId) and invoke follow() from
your selection handler. When the selected agent or workspace changes, call refresh() before
showing its data. See app/pages/support.vue in the starter for a complete example.
For a quick answer inside one request, useAgent('support') from the free module streams a run
from the same agent and tools without storing it. Under Pro, it runs as the signed-in user.
Running an Agent from the Server
Your own server routes start runs through the services:
export default defineEventHandler(async (event) => {
const { agents, runs } = await useAgentic(event)
const support = await agents.code('support')
return runs.start(support.id, { runId: crypto.randomUUID(), payload: await readBody(event) })
})
runId names the run: up to 100 letters, digits, hyphens, or underscores. See
Server Logic for the other services.
Setting Provider Keys
Each provider reads its key from an environment variable:
| Provider | Environment variable |
|---|---|
| OpenAI | OPENAI_API_KEY |
| Anthropic | ANTHROPIC_API_KEY |
GOOGLE_AI_API_KEY |
The mock provider needs no key. It replies Mock response: <payload>, or follows a script in
the run payload, so tool calls and approvals work in tests and demos:
{
"mock": {
"turns": [{ "calls": [{ "name": "customer_list", "input": {} }] }, { "text": "Done." }]
}
}
Running on Codex or Claude Locally
To test without a provider API key, select Codex CLI or Claude Code in the model picker
during pnpm dev. For a code agent, set runtime to the CLI name instead.
These runs use your CLI login, with tools, plugins, web search, and shell access disabled. The
bridge runs only on localhost during development. Configure it with agentic.localRuntimes (Nuxt)
or voidAgentic({ localRuntimes }) (Void), or disable it. See
Configuration.