Agents overview
How the platform stays agent-neutral, how it picks an agent, provider and model for each task, what every agent is told, and how to add an adapter.
The scheduler, task engine, database and UI contain no agent-specific logic. Each agent is an adapter in the
core (packages/agents/src/adapters/).
How an agent is chosen
For each task the worker computes compatible (agent, provider, model) targets:
- the agent is installed, enabled and not unauthenticated;
- by default the agent's own login is used (provider
native:<agent>, modeldefault); add-on models are used when it reaches its limit — directly when the agent supports the provider, otherwise through the model gateway; - the target satisfies the task's required agent capabilities;
- for projects with several repositories, the agent can work in several directories (Claude Code);
- organization, project, worker and task policies allow it (allowed, blocked, preferred, cost tier).
Targets are ranked by preference, not by a hard-coded "best agent" list.
What every agent is told
Every agent receives the same agent-neutral instructions. They tell it to inspect before changing anything, keep
progress in .agent-orchestration/progress/<task>.json, write and run tests, never run destructive Git commands,
stay inside the project, and write a completion report.
Below the task, a Knowledge section carries background at three levels, each left out when empty:
organization knowledge (Settings → General), project knowledge (project page) and the task's own background
(New task → Background for the agent, or agentctl task create --knowledge-file). Never put secrets there;
agents get secrets through secret references. Skills and plugin instructions are added as well.
Recovery
| Agent outcome | What the worker does |
|---|---|
| Rate or capacity limit | Records it (with a reset time only if reported) and applies the fallback policy. A limit never fails a task by itself. |
| Context exhausted | Checkpoints and starts a fresh session from the checkpoint |
| Crash or failure | Restarts with backoff, resuming the session if supported. Three identical failures, or maxRestarts, lead to RECOVERY_REQUIRED. |
| Hang | Suspected only after no output, no file changes and near-zero CPU for hangTimeoutMs; evidence is recorded first |
| Asks a question | WAITING_FOR_INPUT; the answer is passed to the next session |
| Auth required / not installed | Tries another compatible target, otherwise RECOVERY_REQUIRED with instructions |
All of these paths are covered by end-to-end tests with the mock agent.
Adding an adapter
Implement AgentAdapter in the core (packages/agents/src/types.ts): detect(), capabilities(),
buildInvocation() (an argv array, env and stdin — never a shell string), parseLine() and classifyExit(),
optionally gitExcludes. Register it in defaultAgentManager(). The shared runtime handles process lifecycle,
streaming, hang detection and termination.