Orchestrator
The orchestrator is the root agent. It receives every user request, decides how to handle it, and either answers directly or delegates to subagents. Every surface in the app — Today, Inbox, Dashboard, chat — boots an orchestrator.
What it sees
When the orchestrator starts, its system prompt has been assembled by the platform into a strict sequence:
<system instructions: role, defaults, hard constraints>
<USER namespace> ← who's asking
<MEMORY namespace> ← what's happened
<SKILLS namespace> ← how to do things
<TASKS namespace> ← what's pending
<tool definitions> ← what tools are available
This layout is deliberate. USER first so identity sets the frame. MEMORY next so recall is on top of mind. SKILLS so the playbook is visible before it's needed. TASKS last so pending work surfaces without dominating attention.
The user's actual question comes in as the first user-role message. Anything previously in the conversation is in the message history.
The decision loop
For each turn, the orchestrator:
- Reads the assembled context + new user message.
- Decides — answer directly, call a tool, or delegate to a subagent.
- If tool call — emits a tool call, receives the result, loops back to step 1 with the result in context.
- If delegate — spawns a subagent (see Subagents) with a focused brief; awaits its return.
- If answer — emits final text, optionally with a planned action attached (which goes into TASKS).
Streaming starts at step 5. Earlier steps run server-side without emitting text — only the final answer + structured tool-call events stream to the UI.
Tool selection
The orchestrator has a fixed core toolset on every run:
| Tool | Purpose |
|---|---|
graph_semantic_search | Find entities by question. Vector + fuzzy hybrid. |
dashboard_query | Run a typed dashboard query (e.g. pipeline by stage). |
read_entity | Hydrate a specific entity by id with full payload. |
delegate | Spawn a subagent with a focused brief. |
propose_action | Emit a planned action into TASKS for confirmation. |
Surface-specific tools are added based on context — e.g. a Today
card run gets write_card_draft; an Inbox confirm run gets
execute_planned_action. The skill being applied may inject
additional preferred tools.
Model routing
The orchestrator runs on a model selected by the model router:
- Cloud — Sonnet by default for orchestrator turns, Haiku for cheap classifications, Gemini Pro for long-context cases. Per-tenant plan tier caps which models are reachable (Starter → Haiku/Mini only, Scale → Sonnet + Gemini Pro).
- Self-host — Llama 3.1 8B by default via Ollama, or BYO (OpenAI/Anthropic) configurable.
The router is the failsafe — if the tenant's preferred model is unavailable, it falls back along a preference chain (Sonnet → Gemini → Haiku → Deepseek). See Self-host BYO key for swap-out details.
Tool calling cadence
Multi-round by default. The orchestrator can chain up to 8 tool calls in one user turn before being forced to respond. The cap protects against runaway agents while leaving room for genuinely multi-step tasks.
The model often calls tools in parallel when they're independent — e.g. semantic search across three different node kinds simultaneously. The platform batches the responses back so the model sees them as a single tool_result block, keeping context efficient.
Citation enforcement
Every numeric claim in the final answer must have a corresponding citation pulled from the assembled context. A post-generation pass walks the output, matches numbers + named entities against the context, and:
- Marks cited claims with the source node id.
- Flags uncited claims as "low confidence" with a visible warning in the UI.
- For severe mismatch (multiple uncited factual claims), re-runs the orchestrator with a "you must cite" reminder. Once.
The contract is: agent says "we have 17 active deals" → user clicks 17 → citation drawer opens with those 17 rows. Anything less is broken.
Error handling
Tool failures are returned to the orchestrator as tool_result
blocks with an error field. The orchestrator can:
- Retry once with adjusted parameters.
- Skip and answer with partial data, flagging the gap.
- Surface a "tool failed" message asking the user how to proceed.
The model router handles its own retries for transient LLM errors (rate limit, 5xx). Those don't reach the orchestrator's reasoning; it sees a clean response or a final error after retries are exhausted.
Telemetry
Every orchestrator run emits a structured TurnRecorder trace:
- Run id, tenant id, user id, surface.
- Assembled context size + breakdown (USER bytes, MEMORY bytes, etc.).
- Tool calls with timing + result sizes.
- Subagent delegations with depth + outcome.
- LLM token in/out per provider.
- Final answer length + citation density.
- Plan hash if a planned action was emitted (for dedup).
You can see your own runs at Settings → Agent runs. Admins see all runs in their tenant. Cross-tenant aggregates power the benchmarks flow (cloud only, k-anonymized).
Read next
- Subagents — when the orchestrator delegates and what subagents look like.
- Tool calling — tool definitions, multi-round semantics, error handling in more depth.