Delegating to sub-agents
Consumer-facing guide to agents.delegate — the delegation primitive that lets an agent (or an API caller) dispatch a sub-agent to investigate one goal and report back. For the general agent-session model see Agents; for authoring the named agents a delegation can target, see the GET/POST /agents roster API.
What delegation is
A delegation hands one bounded investigation to a sub-agent. The sub-agent is a named prompt — an Amdahl library agent (like researcher), a workspace agent you authored, or an ephemeral inline prompt supplied just for this dispatch — running with an investigation-only toolkit: data queries, cluster search, knowledge-base search, external market search, and session memory.
Sub-agents investigate and suggest; they never commit. A sub cannot write documents, curate long-term memory, send notifications, or publish anything. It returns its findings to the caller, and the caller decides what to do with them.
The goal harness
Every delegation carries three fields that shape what comes back:
| Field | Required | What it does |
|---|---|---|
task | yes | What the sub-agent should do — its opening instruction. |
desired_output | no | Freeform description of what you want back (shape, depth, format). Defaults to the task. |
context | no | What the sub-agent should know before starting (why you are asking, what you already have). |
The sub-agent's reply is expected to be an answer to exactly the desired_output, plus evidence references and a short list of suggestions for anything the workspace should capture. If the answer comes back thin, re-dispatch with a sharper desired_output and richer context — the conversation's cost cap bounds how far that loop can run.
Picking the agent
Pass exactly one of:
agent— a roster agent: an Amdahl library slug (researcher), a workspace agent slug or id. Browse the roster viaGET /agents(or theagent://listresource).prompt— an ephemeral inline agent:{ "name": "...", "prompt": "..." }. Never saved to the roster; the prompt is snapshotted onto the run record for auditability.
Restricted rosters. A run started with a fixed agent roster (a Routine whose config.agents lists several agents) may only delegate to those agents: any other agent ref — and any inline prompt — is refused with agent_not_allowed, and the error's details.allowed echoes the permitted set. Runs without a roster are unrestricted.
Example
curl -X POST https://api.amdahl.com/api/platform/v1/agents/delegate \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent": "researcher",
"task": "Investigate churn signals in our call corpus for Q3",
"desired_output": "A ranked list of the top 5 churn risks, each with supporting quotes",
"context": "We are assembling a QBR brief; renewals close next month"
}'Response:
{
"success": true,
"run_id": "3f6f2f4e-...",
"conversation_id": "9a1c8d7b-...",
"agent": { "id": "d3b1...", "slug": "researcher", "name": "Researcher", "source": "library" },
"status": "queued"
}Async by design
Delegation never blocks for the child's answer. The call returns the child run_id immediately; the sub-agent runs in the background. Two ways to observe it:
-
Poll the run over REST until
statusreaches a terminal value (complete,error, orcanceled; a run paused on a human question showsawaiting_input):bashcurl https://api.amdahl.com/api/platform/v1/agent-runs/3f6f2f4e-... \ -H "Authorization: Bearer $API_KEY"json{ "id": "3f6f2f4e-...", "conversation_id": "9a1c8d7b-...", "status": "complete", "summary": "Top 5 churn risks, ranked, with supporting quotes ...", "tokens_used": { "input": 18324, "output": 2210 }, "created_at": "2026-07-10T22:41:00Z", "completed_at": "2026-07-10T22:42:31Z" }The full row also carries the run's step events and conversation log for tracing. (Agents observing a delegation from inside the platform read the same row through
read_resourceasagent_run://<id>— the URI form is agent-side sugar over this REST endpoint.) -
Stream: when the caller is itself an agent run, the child's progress is teed onto the parent's SSE stream as
child_progressframes, with a finalchild_terminatedframe when the sub finishes. Console sessions render this as nested activity automatically.
There is no session_id input: the child is bound to the calling run's conversation automatically. A delegation fired from inside an agent session lands in that same conversation (so cost caps, history, and streaming all stay in one place); a delegation fired directly over REST gets its own conversation.
Depth is one level
A sub-agent cannot delegate further. The sub toolkit structurally omits the delegation tool, and a delegation attempted by a run that is already a sub-agent is rejected with delegation_depth_exceeded. Decompose at the top: the dispatching agent fans out the investigations and folds the answers together itself.
Errors
| Code | Meaning |
|---|---|
invalid_argument | Missing task, or not exactly one of agent / prompt. |
not_found | The agent ref matched no library or workspace agent. |
delegation_depth_exceeded | The caller is itself a sub-agent (depth is 1). |
enqueue_failed | The child run could not be queued; nothing was left behind — retry. |