Agents
Apps can define AI agents that execute autonomously in response to events, cron schedules, or manual triggers. Agents run in the same sandboxed environment as server routes but are driven by an AI model that can call tools.
Key Concepts
Agents are defined in informer.yaml and deployed alongside the app. Each agent has:
- Instructions — a system prompt guiding the AI's behavior
- Tools — app-scoped tools from the
tools/directory - Toolkits — external toolkit integrations (e.g., custom toolkits)
- Assistants — Informer assistants whose instructions are merged into the agent's system prompt
- Triggers — events, cron schedules, or manual invocation
Runs are individual executions of an agent. Each run tracks status, steps, token usage, and errors.
Events are the primary trigger mechanism. Server route handlers or other agents can emit events via emit(), and agents listening for those events execute automatically.
Agent API Endpoints
GET /api/apps/{id}/agents
List all agents for an app.
Authentication: Required
Permissions Required: Member+ role (write permission)
Response:
[
{
"id": "agent-uuid",
"appId": "app-uuid",
"name": "order-processor",
"description": "Processes new orders and sends confirmations",
"instructions": "You process incoming orders...",
"model": "go_everyday",
"tools": ["send-email", "update-inventory"],
"toolkits": ["admin:crm-toolkit"],
"assistants": ["assistant-uuid"],
"triggers": {
"on": ["order_created"]
},
"status": "active",
"nextRunAt": null,
"createdAt": "2025-03-01T10:00:00.000Z",
"updatedAt": "2025-03-01T10:00:00.000Z"
}
]
GET /api/apps/{id}/agents/{agentId}
Get a single agent's details.
Authentication: Required
Permissions Required: Member+ role (write permission)
Response: Same shape as the array item above, plus instructionsOverride if set.
PUT /api/apps/{id}/agents/{agentId}
Update an agent's runtime settings. Only certain fields can be changed via API — the core definition comes from informer.yaml on deploy.
Authentication: Required
Permissions Required: Member+ role (write permission)
Payload:
| Field | Type | Description |
|---|---|---|
instructionsOverride | string | null | Override the YAML-defined instructions (set to null to revert) |
status | string | "active" or "stopped" |
model | string | AI model slug (e.g., "go_everyday") |
GET /api/apps/{id}/agents/{agentId}/runs
List execution history for an agent.
Authentication: Required
Permissions Required: Member+ role (write permission)
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | number | 20 | Max results |
offset | number | 0 | Pagination offset |
Response:
[
{
"id": "run-uuid",
"agentId": "agent-uuid",
"trigger": "order_created",
"status": "completed",
"tokens": 1250,
"cost": 0,
"steps": [
{
"index": 0,
"type": "tool_call",
"toolCalls": [
{
"name": "update-inventory",
"args": { "productId": "SKU-123", "quantity": -1 },
"result": { "success": true }
}
]
},
{
"index": 1,
"type": "text",
"text": "Order processed successfully. Inventory updated and confirmation sent."
}
],
"context": { "orderId": "ORD-456" },
"error": null,
"completedAt": "2025-03-01T10:00:05.000Z",
"createdAt": "2025-03-01T10:00:00.000Z"
}
]
GET /api/apps/{id}/agents/{agentId}/runs/{runId}
Get details for a single run.
Authentication: Required
Permissions Required: Member+ role (write permission)
POST /api/apps/{id}/agents/{agentId}/_trigger
Manually trigger an agent. Useful for testing or one-off executions.
Authentication: Required
Permissions Required: Member+ role (write permission)
Payload:
{
"event": "manual",
"payload": { "orderId": "ORD-789" }
}
| Field | Type | Required | Description |
|---|---|---|---|
event | string | No | Event name (default: "manual") |
payload | object | No | Data passed to the agent as trigger context |
Response:
Returns the created run record (status will be "running" initially).
Defining Agents in informer.yaml
Agents are declared in the agents section of informer.yaml:
agents:
order-processor:
description: Processes new orders
instructions: |
You are an order processing agent. When triggered by an order_created event,
verify the order details, update inventory, and send a confirmation email.
tools:
- send-email
- update-inventory
on: order_created
model: go_everyday
daily-report:
description: Generates daily summary
instructions: Generate a summary of today's orders and email it to the team.
tools:
- send-email
cron: "0 17 * * 1-5"
model: go_everyday
smart-assistant:
description: Customer support agent with toolkit and assistant tools
instructions: Help customers with their questions using CRM data.
toolkits:
- admin:crm-toolkit
assistants:
- admin:support-persona
on: support_request
webSearch: true
Agent Fields
| Field | Type | Required | Description |
|---|---|---|---|
description | string | No | Human-readable description |
instructions | string | No | System prompt for the AI |
tools | string[] | No | App tool names (from tools/ directory) |
toolkits | string[] | No | Toolkit natural IDs to attach |
assistants | string[] | No | Assistant natural IDs — instructions are merged into the agent's system prompt |
on | string | string[] | No | Event name(s) that trigger this agent |
cron | string | No | Cron schedule (5-field format: min hour dom mon dow) |
webSearch | boolean | No | Enable web search tool |
model | string | No | AI model slug (default: "go_everyday") |
Trigger Types
Agents can be triggered in three ways (any combination):
- Events (
on) — fires when the named event is emitted viaemit()in a server route or webhook handler - Cron (
cron) — fires on a schedule (e.g.,"0 3 * * *"for 3 AM daily) - Manual — via
POST /agents/{agentId}/_trigger
App Tools
Agents can call tools defined in the app's tools/ directory. Each tool is a JavaScript file that exports a handler:
// tools/send-email.js
export const description = 'Send an email to a recipient';
export const schema = {
properties: {
to: { type: 'string', description: 'Recipient email' },
subject: { type: 'string', description: 'Email subject' },
body: { type: 'string', description: 'Email body' }
},
required: ['to', 'subject', 'body']
};
export default async function ({ to, subject, body }, { query, fetch, emit, crypto, markdown, log }) {
const result = await fetch('integrations/sendgrid/request', {
method: 'POST',
body: {
url: '/v3/mail/send',
method: 'POST',
data: { to, subject, body }
}
});
return { sent: result.status === 202 };
}
Tools are bundled with esbuild during deploy and executed in V8 isolates. They have access to the same query, fetch, emit, crypto, markdown, and log callbacks as server routes.
Toolkit Integration
Agents can reference external toolkits that provide additional tool definitions. Toolkits are resolved during deploy — the app creates junction rows in app_toolkit linking the app to each referenced toolkit.
At execution time, the agent executor:
- Loads the app's toolkit references from
app_toolkit - Calls
toolkit.getToolDefinitions()for each toolkit - Merges toolkit tools into the agent's available tools
- Appends
toolkit.getSystemInstructions()to the system prompt
agents:
crm-agent:
description: Handles CRM operations
instructions: Use CRM tools to look up and update customer records.
toolkits:
- admin:crm-toolkit
on: customer_update
If a referenced toolkit doesn't exist, deploy fails with a 400 error.
Assistant Integration
Agents can reference Informer assistants to inherit their instructions. Each referenced assistant's system prompt is merged into the agent's own instructions, allowing you to compose agent behavior from reusable assistant personas.
agents:
support-agent:
description: Handles customer support with a specialized persona
instructions: Process support tickets and escalate as needed.
assistants:
- admin:support-persona
on: support_request
Assistant references are resolved at deploy time — if a referenced assistant doesn't exist, deploy fails with a 400 error. Use either the assistant's naturalId (owner:slug) or UUID.
At execution time, the agent executor:
- Loads each referenced assistant by ID
- Collects the assistant's
instructionsfield - Appends assistant instructions to the agent's system prompt (before toolkit instructions)
Events
Events are the glue between server routes and agents. Declare event types in informer.yaml:
events:
order_created:
description: Fired when a new order is submitted
order_shipped:
description: Fired when an order ships
agents:
order-processor:
instructions: Process new orders.
on: order_created
Emit events from server routes:
// server/orders/index.js
export async function POST({ query, emit, request }) {
const [order] = await query(
'INSERT INTO orders (customer, total) VALUES ($1, $2) RETURNING *',
[request.body.customer, request.body.total]
);
// This triggers the order-processor agent
await emit('order_created', { orderId: order.id, total: order.total });
return { status: 201, body: order };
}
Event Dispatch
Events are dispatched in two ways:
- Real-time — a Redis pub/sub listener picks up events immediately
- Sweep — a periodic scan (every 10 seconds) catches any missed events
Events use atomic claiming (FOR UPDATE SKIP LOCKED) to prevent duplicate execution in clustered environments.
Execution Model
When an agent is triggered:
- A
runrecord is created with status"running" - A workspace database connection is acquired
- The AI model is resolved (default:
go_everyday) - App tools are loaded from bundled code in
_bundles/tools/ - Assistant instructions are loaded and merged into the system prompt
- Toolkit tools are loaded from the app's toolkit references
- The AI loop runs with
stepCountIs(20)as the stop condition - Each tool call executes in a V8 isolate with
query,fetch, andemitcallbacks - The run record is updated with status, steps, and token usage
Tool callbacks available to agents:
| Callback | Description |
|---|---|
query(sql, params) | Execute SQL against the app's workspace |
fetch(path, options) | Make authenticated API calls (whitelist enforced) |
emit(event, payload) | Create app events (can chain-trigger other agents) |
crypto.hmac(algorithm, key, data, encoding?) | HMAC digest computation |
markdown(text) | Convert markdown to HTML |
log(message, data?) | Structured logging (also log.info, log.warn, log.error, log.debug) |