Skip to main content

Sub-Tasks

An agent can hand a slice of work to a fresh child agent and get the result back. Distri keeps a real task tree: every child is its own task with a parent_task_id, so a run that fans out into ten workers stays inspectable and cancelable as one tree.

This is Distri's equivalent of Claude Code's Task tool.

Spawn a child with invoke_agent

invoke_agent is the single tool an agent calls to dispatch a sub-agent. It takes three flat fields and runs synchronously. The parent waits and gets the child's result back as the tool result:

// Route to a registered agent
{ "prompt": "Extract the totals from invoice.pdf", "agent": "extractor" }

// Or spin up an ad-hoc worker with a one-off system prompt
{ "prompt": "id is 3", "system": "You are a leaf worker. Return the id and call final." }

// Or let the runtime pick the default worker agent
{ "prompt": "Summarize this PR" }

prompt is required; pass at most one of agent or system. Everything else (context isolation, tool inheritance, executor choice) is decided by the runtime (see Invocation Methods), so the model never reasons about it. The child starts with a fresh history; whatever it needs from the parent goes in prompt.

Fan out

To run several children at once, emit multiple invoke_agent calls in a single turn. Providers that support parallel tool calls execute them concurrently, and each becomes its own sub-task under the parent.

In the CLI, a sub-task collapses to one line while it runs:

⏺ subtask(extractor)
⎿ done (3.4s)

Run with --verbose to expand the child's full output.

Supervise running children

Agents that spawn longer-running or detached children can opt into the supervisor builtin tools via tools.builtin:

[tools]
builtin = ["get_task", "wait_task", "get_task_result", "cancel_task", "list_my_tasks"]
ToolWhat it does
get_taskPoint lookup: a task's status, parent, and timing.
wait_taskBlock until a task reaches a terminal state (or timeout_ms), then return its result.
get_task_resultHarvest a finished child's final output.
cancel_taskCancel a task and every descendant (the whole subtree).
list_my_tasksEnumerate the tasks this agent spawned (descendants), or running tasks in scope.

The supervisor agent definitions ship with all five enabled.

Sub-tasks vs. transfer_to_agent

They solve different problems:

  • invoke_agent spawns a child task. You delegate, get a result back, and the parent stays in control.
  • transfer_to_agent is a handover: the current task continues under a different agent. There's no child and nothing comes back to the caller.

Use a sub-task when you want an answer. Use a transfer when you want a different agent to take over the conversation.

In the client

The React SDK renders the task tree for you. SubTaskCard and SubTaskTree show each child run nested under its parent.

  • Invocation Methods: the join, context, and tool-policy dials behind a dispatch.
  • Deep Agents: patterns for agents that orchestrate other agents.