Agents
An agent is a Firestore-backed record that binds a persona, a model, a tool allowlist, and memory into something that can be invoked.
An agent is the smallest unit of intent in Nova Admin. Every run starts by picking an agent (or letting the router pick one) and handing it a task.
What an agent record contains
Agents live in the agents/{name} Firestore collection. The interesting fields:
| Field | Purpose |
|---|---|
name | Unique slug. Also the document ID. |
description | Short blurb shown in the agent picker. |
model | The Claude model to use. Routing can override this per-run based on task complexity. |
systemPrompt | Persona, rules, and operating constraints. |
tools | Allowlist of tool names the agent may call, like slack_post_message or gw_gmail_list_messages. |
skills | Skill slugs the agent can invoke with /skill-name. |
memory | Persistent notes the agent can read and write across runs. |
taxonomy | Tags used by routing: "auto" to pick the right agent for a task. |
Creating an agent
From Agents → New Agent in the dashboard, or programmatically via the seed system:
// packages/cli/src/seeds/data/agents/support.ts
export const supportAgent = {
name: "support",
description: "Triages incoming support email and Slack messages.",
model: "claude-sonnet-4-6",
systemPrompt: "You are the support triage agent...",
tools: ["gw_gmail_list_messages", "slack_post_message"],
skills: ["draft-reply", "lookup-user"],
};Then bun packages/cli/src/index.ts seed run --all upserts the agent into Firestore.
How agents are invoked
Three entry points:
- Manual — click Run in the dashboard or send
@novaa message in Slack. - Flows — a flow node binds a step to an agent and a task prompt.
- Delegation — another agent calls
delegate_to_agentwith a target name and task.
Smart model routing
When routing is enabled, the runtime inspects the task and picks Haiku, Sonnet, or Opus based on complexity. Cheap and fast for simple lookups, expensive and slow for code generation. Override per-agent if you need a fixed model.