Skip to main content

What Is a Subagent?

A subagent is an autonomous dual_ai agent spawned by a parent thread. It runs in its own DurableThread with isolated:
  • message history
  • execution logs
  • SQLite state
  • filesystem and attachments
This makes subagents the primary composition primitive for multi-agent workflows in AgentBuilder.

Why Use Subagents?

  • Keep orchestration in a parent agent and delegate focused work to children
  • Run specialized worker + reviewer loops (side_a + side_b)
  • Scale work across multiple child instances without mixing state
  • Preserve strong isolation while still supporting parent/child communication

Invocation Modes

Subagent behavior is defined per prompt-tool relationship:
ModeBehavior
non-resumable + blockingparent waits, child completes, child terminates
non-resumable + non-blockingparent returns immediately, child reports later
resumable + blockingparent waits per call, child persists
resumable + non-blockingparent returns immediately, child can be messaged anytime

Prompt Configuration

Use SubagentToolConfig in definePrompt({ tools: [...] }):
definePrompt({
  name: 'orchestrator_prompt',
  toolDescription: 'Orchestrates specialized child workers',
  model: 'base_model',
  prompt: 'Delegate work to subagents and aggregate results.',
  tools: [
    {
      name: 'topdown_asset_subagent',
      blocking: false,
      initUserMessageProperty: 'message',
      initAttachmentsProperty: 'attachments',
      initAgentNameProperty: 'name',
      resumable: {
        receives_messages: 'side_a',
        maxInstances: 20,
      },
    },
  ],
});

Key Properties

  • initUserMessageProperty: maps tool args to child initial message text
  • initAttachmentsProperty: maps tool args to child initial attachments
  • initAgentNameProperty: maps tool args to child display name (name:<value> tag)
  • resumable.maxInstances: max concurrent instances for this subagent type

Resumable Lifecycle Tools

For resumable subagents, AgentBuilder injects built-in tools:
  • subagent_create: create or start a resumable child instance
  • subagent_message: send a message to an existing resumable child
Non-resumable subagents behave like normal tool calls and do not use lifecycle tools.

Child Lifecycle Bindings

Child-side lifecycle is configured in defineAgent via SideConfig:
  • sessionStop
  • sessionFail
  • sessionStatus
Each binding can be a string or object:
sessionStop: {
  name: 'approve_topdown_asset',
  messageProperty: 'approval_summary',
  attachmentsProperty: 'approved_assets',
}
Mapped message/attachments are the canonical payload sent from child to parent.

Parent/Child Communication

Parent -> Child

  • initial invocation payload mapping
  • resumable messaging with subagent_message
  • attachment references are copied parent filesystem -> child filesystem

Child -> Parent

  • sessionStop queues a silent result message on parent
  • sessionFail queues a silent failure message on parent
  • sessionStatus updates child status in parent registry
  • returned attachments are copied child filesystem -> parent filesystem
Attachment paths are rewritten to destination-local paths during copy.

Runtime State and APIs

ThreadState exposes subagent-aware APIs:
  • getChildThread(referenceId)
  • getParentThread()
  • children registry entries
  • queueMessage() (durable queued delivery)
  • terminate() and terminated
See: