Daemion docs

How do I create an agent extension?

An agent extension is a named Claude identity with a system prompt and model assignment that shapes how Claude responds when operating in that role.


When would I use an agent extension?

Use an agent when you want Claude to consistently adopt a specific persona, expertise, or behavioral style across conversations. Good candidates:

  • Domain specialists — a researcher agent that web-searches before every response, or a coder agent that always asks for tests
  • Tone and style — a brief agent that caps responses at three sentences, or a teacher agent that explains with analogies
  • Model routing — a fast agent pinned to Haiku for quick lookups, a thorough agent pinned to Opus for deep analysis
  • Project-specific context — a daemion-dev agent seeded with architecture knowledge specific to this codebase

Agents are Claude operating in a role — not separate AIs. The system prompt in src/gateway/agent.ts:36 always begins: “You are Claude, operating as a Daemion agent.” This is a licensing requirement from Anthropic. Agent extensions add identity and specialization on top of that foundation.


How do I create one by chatting?

Describe the agent you want. Daemion writes the extension record:

You: Create an agent called researcher that specializes in web research

Daemion: I’ll set up a researcher agent for you.

The researcher agent is ready. It’s configured with a system prompt that emphasizes sourcing claims, searching before answering, and citing URLs. It’s pinned to Sonnet for a balance of speed and quality. Want to adjust the model or add any specific instructions?

You: Add an instruction to always list sources at the end of every response

Daemion: Updated — researcher now appends a Sources section to every response. Address it directly with @researcher in chat to use it.


How do I create one via the API?

bash
Verified

curl -X POST http://localhost:3001/extensions
-H “Authorization: Bearer $DAEMION_TOKEN”
-H “Content-Type: application/json”
-d ’{ “type”: “agent”, “name”: “researcher”, “description”: “Web research specialist. Sources claims, cites URLs, lists references.”, “definition”: { “model”: “claude-sonnet-4-5”, “system_prompt”: “You are Claude, operating as a Daemion agent specializing in research. Before answering any factual question, search for current information. Always end your response with a Sources section listing the URLs you referenced. Be precise and cite evidence.” }, “source”: “user”, “enabled”: true }’

The gateway stores the record in SQLite and the agent is addressable immediately. No restart required.


What does the agent schema look like?

Agent extensions use GenericDefinitionSchema — the definition field is a flexible key-value map (defined in src/schema/extension.ts:71). The key fields the engine recognizes:

typescript

// Agent definition — shape of the definition field for type: “agent” // Uses GenericDefinitionSchema (Record<string, unknown>) — no rigid field constraints interface AgentDefinition { model: string; // Claude model ID, e.g. “claude-sonnet-4-5”, “claude-haiku-4-5” system_prompt: string; // Appended to the base system prompt in src/gateway/agent.ts:36 // Must begin: “You are Claude, operating as [role]” // Any additional fields you define are passed through to the engine context }

The top-level extension envelope:

typescript

interface Extension { id: string; // e.g. “ext_09def789” — assigned by gateway on creation type: “agent”; name: string; // unique per type, kebab-case, 1-100 chars description: string; // human-readable, max 500 chars definition: AgentDefinition; source: “built-in” | “user” | “agent” | “community”; enabled: boolean; created_at: string; // ISO 8601 updated_at: string; // ISO 8601 }

The three built-in agents — opus, sonnet, and haiku — are shipped with Daemion as source: "built-in" extensions. They are read-only but serve as the model routing defaults.


Frequently asked questions

Q Are agents separate AIs from Claude?
No. Every agent is Claude operating in a role. The base system prompt (in src/gateway/agent.ts:36) literally starts with "You are Claude, operating as a Daemion agent." Your agent's system_prompt is appended to that base. This is required by Anthropic's licensing terms — Daemion agents are Claude with a shaped identity, not a different AI.
Q Which model should I assign?
Use Haiku (claude-haiku-4-5) for classification, quick lookups, and high-frequency tasks where cost matters. Use Sonnet (claude-sonnet-4-5) for building, research, and most everyday work. Use Opus (claude-opus-4-5) for judgment, deep analysis, and architectural decisions where thoroughness matters more than cost.
Q How do I address a specific agent in chat?
Use the @ prefix followed by the agent name — for example, @researcher what is the current state of RAG?. You can also create a command extension with prefix: "@" and the agent name to make it autocomplete.
Q Can I update a built-in agent's system prompt?
Built-in agents are read-only. To customize one, create a new agent extension with source: "user" and a different name — for example, opus-custom. You can copy the built-in's system_prompt and extend it.
Q Do I need to call /reseed after creating an agent via the API?
Only if the agent is also file-backed (i.e. has a directory in agents/ on disk). If you create the agent purely via the API, it is already in SQLite and live immediately. Call POST /reseed only after modifying files on disk.

What can go wrong

What can go wrong

403 &#123;"error": "cannot disable essential extensions"&#125; — Essential built-in agents cannot be disabled.

403 &#123;"error": "cannot delete essential extensions"&#125; — Essential agents cannot be deleted. Create a new agent with source: "user" to add custom behavior.

401 &#123;"error": "unauthorized"&#125; — Bearer token missing or incorrect. Check ~/.daemion/.gateway-token and use $DAEMION_TOKEN.

Agent responds generically despite custom system prompt — The system_prompt in the definition is appended to the base prompt, not used standalone. If your prompt conflicts with the base (e.g. tries to redefine Claude’s identity), the base takes precedence. Write your prompt as an addendum — describe the role and specialization, not who Claude fundamentally is.

400 &#123;"error": "validation failed"&#125; — The top-level envelope (name length, type value, source value) failed validation. The agent definition itself uses GenericDefinitionSchema and will not be strictly validated — any key-value map is accepted.


What’s next?