delegate_task tool spawns child AIAgent instances with isolated context, inherited tool access, and their own terminal sessions. Each child gets a fresh conversation and works independently — only its final summary enters the parent’s context.
Top-level model calls run in the background automatically. Mibyan returns a handle immediately so the conversation can continue, then posts the result back as a new message. An orchestrator subagent waits for its own workers so it can synthesize their results before returning.
Completion delivery
Messaging gateways acknowledge background completions only after their adapter actually schedules the event or inserts it into the session’s queue. Missing handlers, mismatched session routes, and full queues leave the completion pending for retry; these admission refusals do not consume the durable delivery-attempt budget. A successful admission suppresses repeat delivery within the running gateway, but is not proof that a model turn or outbound reply completed. Crash/restart delivery remains at least once, subject to the existing replay age limit; actual transport failures retain their bounded retry policy. An unavailable API-server route stays pending without repeated missing-route warnings. Malformed messaging routes still produce diagnostics. On the API server, an async delegation completion adds a durable timeline delivery row only: the client owns the next model turn. Setting background process notifications tooff still drains pattern-watch events silently.
Background process lifetime
Background terminal processes belong to the agent that starts them. Closing a child during delegation teardown terminates its remaining processes, including work started in earlier turns, without stopping processes owned by the parent or sibling agents. Sharing a terminal environment does not transfer process ownership. A child should wait for its builds, tests, and other bounded background commands before returning its final summary. Start a CI watcher or server in the parent session if it must continue after the child finishes; returning a process ID does not transfer ownership to the parent.Single Task
Parallel Batch
Up to 10 concurrent subagents by default (configurable, no hard ceiling):Structured Output (output_schema)
Each task can carry an optional output_schema, a JSON Schema object the child’s final answer must validate against. The child sees the schema up front as an output contract (“return ONLY the JSON value — no prose, no code fence”); when the answer comes back the parent validates it, and on failure sends the child exactly one bounded correction turn carrying the validation errors verbatim (the schema is not re-pasted). The task’s result then gains schema_valid (true/false) and, on failure, schema_errors.
A contract miss after the retry does not discard the child’s work: the result keeps status: completed with the child’s raw final text in summary, schema_valid: false, the schema_errors, and a schema_note saying the text is unvalidated. The parent extracts what it needs from the raw text instead of re-running a task that may have taken an hour. Prose or a code fence around otherwise-valid JSON (object or array) is tolerated by the validator.
output_schema are unaffected.
How Subagent Context Works
One exception: when the parent has a resolved workspace directory, every subagent’s system prompt embeds that workspace’s project context files (.mibyan.md > AGENTS.md chain > CLAUDE.md > .cursorrules — the same discovery, priority, and size caps as the main agent’s system prompt; SOUL.md is excluded). Subagents working in a repo operate under the repo’s own conventions without having to rediscover them.
This means the parent agent must pass everything the subagent needs in the call:
Forwarding Images to a Subagent
Text context is not enough when the task is inherently visual — a screenshot the user sent, a design mock, a rendered chart. Each task accepts an optionalimages list (up to 8 entries; local file paths, http(s) URLs or data:image/... URLs):
agent.image_input_mode):
- Vision-capable child model — the images arrive as native multimodal content on the child’s first turn: local files are embedded as data URLs (subject to the same read guard as every other file read), remote and
data:URLs pass through verbatim. The child sees the actual pixels. - Non-vision child model — the goal gains
[Image attached at: <path>]hint lines and the child is told to inspect them withvision_analyze.
context as usual.
Practical Examples
Parallel Research
Research multiple topics simultaneously and collect summaries:Code Review + Fix
Delegate a review-and-fix workflow to a fresh context:Multi-File Refactoring
Delegate a large refactoring task that would flood the parent’s context:Batch Mode Details
When a top-level agent provides atasks array, Mibyan returns one background handle and runs the subagents in parallel. By default the call returns one consolidated message once every task has finished. Results are delivered only between the parent’s turns: the parent should finish anything that does not depend on the children, then end its turn rather than polling transcripts, artifacts, or CI while it waits.
Independent completions (opt-in)
Setdelegation.independent_completions: true to have results land per completion unit as each finishes instead. The model-facing group field and grouping guidance are only advertised when this option is enabled. Start a new session after changing it so the tool schema can reflect the setting without changing an existing conversation’s cached prefix. Old calls containing group remain accepted; with the option off, the whole call still returns together.
When independent completions are enabled:
- Omit
groupwhen each result is useful to act on separately. Each task reports as soon as it finishes. - Use the same
groupstring when you want to review outputs together: comparison, synthesis, or one coordinated decision. The group returns one consolidated message after all its tasks finish. Even independently executable tasks can belong in one group when their results inform the same decision. - Different groups report independently; grouped and ungrouped tasks can share one call.
units[].delegation_id, group, task_indexes); unit ids are the call’s id suffixed -1, -2, …, and every unit of one call shares a single slot of delegation.max_concurrent_children, so grouping never changes capacity accounting (the worker pool grows to the number of live units so no unit waits behind a full pool). An orchestrator subagent waits for its whole batch in the current turn so it can synthesize the results.
- Maximum concurrency: 10 tasks by default (configurable via
delegation.max_concurrent_childrenor theDELEGATION_MAX_CONCURRENT_CHILDRENenv var; floor of 1, no hard ceiling). Batches larger than the limit return a tool error rather than being silently truncated. - Thread pool: Uses
ThreadPoolExecutorwith the configured concurrency limit as max workers - Progress display: In CLI mode, a tree-view shows tool calls from each subagent in real-time with per-task completion lines. In gateway mode, progress is batched and relayed to the parent’s progress callback. CLI and TUI completion notices use task-first titles such as
Subagent Task Completed: Review changes; multi-task groups use the group name and task count. Unsuccessful or incomplete work gets a corresponding status label. These compact notices do not replace the full results delivered to the parent agent. - Result ordering: Within a unit, results are sorted by task index to match input order regardless of completion order;
TASK i/Nlabels index the whole call - Cancellation: Follow-up messages do not cancel a top-level background batch.
/stop(gateway/stop, CLI/stop, the Desktop/TUI Stop button, an ACP cancel) or closing/resetting the owning session ends its background children and every synchronous descendant beneath them; each stopped child still returns as a completion withstatus="interrupted"and its partial output
Durable background completions
When a background delegation finishes, Mibyan stores its completion event in the active profile’sstate.db before publishing it to the normal fresh-turn
queue. If Mibyan restarts after completion but before delivery, the pending
event is restored and routed through the same ownership checks. Competing
consumers use a durable claim, so only the consumer that successfully accepts
the synthetic turn acknowledges delivery; failed attempts release the claim for
retry.
This does not resume child execution after a crash. A delegation whose owner
process disappears while it is still running is recorded as unknown, because
Mibyan cannot prove whether its external side effects happened. Pending and
delivered records are bounded and profile-local.
Child background-process notifications
Background processes a subagent starts (e.g.npm ci with
notify_on_complete) technically route their completion and watch-pattern
notifications to the parent conversation, because anything that outlives
the child needs a durable consumer. By default those notifications are
suppressed in the parent chat — the child’s consolidated delegation result
is the deliverable, and mid-conversation “process finished” walls from a
child’s internal builds are noise. Suppressed events are logged at debug level
with the process session ID and subagent task ID, so they remain diagnosable.
The delegation result itself is never suppressed. To restore delivery of the
child process notifications (each carries a “Started by subagent …”
attribution line):
Handing a process to the parent
A subagent’s background processes are also killed when the subagent finishes, so a CI watcher or build a child starts withnotify=true never reports to anyone. The child’s terminal result says so (notify_on_complete: false plus a subagent_note), and the child has three honest options before it finishes:
- wait —
process_manage(action="wait", session_id=...)and report the result itself; - kill —
process_manage(action="kill", ...); - hand off —
process_manage(action="handoff", session_id=..., data="<one sentence: what it is for>"). The runtime transfers ownership to the parent under the registry lock (up to 3 per child; only a running process the child owns is accepted, anything else is a tool error). The parent’s completion notice then arrives in the parent chat withHanded off to you by a subagent… Purpose: …, and the parent can poll/log/kill it like its own.
poll/wait/log) and reports it. If the child never reads it, the exit code and output tail are attached to its result as unread_completions and shown to the parent. Whatever is still running and was neither killed nor handed off is named on its result (orphaned_processes) and in the parent’s delegation notice as terminated, so the parent hears from the runtime, never from the child’s prose, that “the watcher is running” is no longer true. For CI watchers the better pattern is still: the child returns the fact (PR number, SHA) and the parent launches its own watcher.
Model Override
You can configure a different model for subagents viaconfig.yaml — useful for delegating simple tasks to cheaper/faster models:
Cost strategy: frontier planner, inexpensive workers
Decomposing a problem into well-specified subtasks takes frontier-level judgment; executing a subtask that already comes with a clear goal, full context, and an output contract usually doesn’t. Meanwhile the children are where the tokens go — a parallel batch of subagents typically burns the large majority of a run’s total tokens, so the worker model is where the cost actually lives. Pinningdelegation.model to an inexpensive model while your main session stays on a frontier model keeps the planning quality where it matters and cuts spend where the volume is:
delegation.base_url (direct endpoint) takes precedence, then delegation.provider (full credential bundle resolved via the runtime provider system), and when neither is set children inherit the parent’s provider and credentials; delegation.model applies in all cases, and when it is empty children inherit the parent’s model. Setting delegation.provider alongside delegation.base_url keeps the explicit endpoint but carries that provider’s request overrides and max output tokens into the child. An explicit delegation.request_overrides dict is honored on every branch and merges over those runtime-derived values (see Configuration below).
Note that the pin is global: delegate_task has no per-task model parameter, so every child in a batch runs on the configured delegation model. For quality-sensitive subtasks that need a stronger model, either leave delegation.model unset for that session or hand the task to the kanban board, which does support a per-task model override.
The /review Command
/review spawns an independent, full-privilege background subagent whose only job is to review the work your conversation just produced — a PR, a diff, code, documentation, a design. It works on every surface: CLI, TUI, the Desktop app, and every gateway messaging platform.
- The last 10 user/assistant messages are snapshotted as the reviewer’s starting evidence (tool output and system messages are excluded).
- A reviewer subagent is dispatched on the same background delegation rail as
delegate_task— it gets the full normal subagent toolset (terminal, web, files, browser…), so it actually opens the PR, reads the diff, and runs code rather than judging from the excerpt. - The reviewer inherits the primary agent’s working context: any skills the primary agent had loaded (launch-preloaded or via
skill_viewduring the session) are named in its briefing with an instruction to load them and judge the work against their conventions. Like every subagent, its system prompt also embeds the workspace’s project context files (AGENTS.md / CLAUDE.md / .cursorrules) as binding conventions. - When it finishes, its full review re-enters the same session as a normal background-subagent completion — your primary agent sees it and can act on it (fix the findings, push follow-ups, reply to you).
/review, and a second pair of eyes investigates it while you keep working; the review lands back in the chat addressed to the agent that created the PR.
Dispatch prints only “Review started. Results will return here.” The live subagent viewer identifies the worker as Review: your focus (or Review recent work for bare /review), with a shortened single-line label; the reviewer still receives your full instructions. In the classic CLI, the dock above the composer shows elapsed time and latest activity; Ctrl+T (or F6) opens the roster with its model, transcript, steering, and stop controls. The same review label appears in the TUI and Desktop subagent viewers.
Review model
By default the reviewer runs on your main model. To pin a dedicated review model, setauxiliary.review in config.yaml:
delegation.provider pin (full runtime-provider bundle: base_url, api key, api_mode). provider: auto with an empty model means “inherit the main agent’s model” — the default.
/review is deliberately separate from /refine: /refine reviews the conversation to update memory and skills, /review reviews the work product the conversation created.
Inherited Tool Access
delegate_task does not accept a model-facing toolsets parameter. Each subagent inherits the parent’s enabled toolsets so the model cannot grant a child capabilities that the parent does not have. Configure the parent’s tools before starting the conversation if delegated work needs additional capabilities.
Certain tools are blocked for subagents even when the parent has them:
delegate_task— blocked for leaf subagents (the default). Retained forrole="orchestrator"children, bounded bymax_spawn_depth— see Depth Limit and Nested Orchestration below.clarify— subagents cannot interact with the usermemory— no writes to shared persistent memorysend_message— no cross-platform side effectscronjob— no scheduling more work in the parent’s name
execute_code (programmatic tool calling) so children can batch mechanical work.
Max Iterations
Each subagent has an iteration limit (default: 250) that controls how many tool-calling turns it can take. The limit is set globally inconfig.yaml and applies to every child; it is not a per-call parameter of delegate_task:
exit_reason: max_iterations and truncated: true, so the parent can tell a budget stop from a completed task.
Child Timeout
By default there is no wall-clock timeout on subagents. Children fail only from what they’re actually doing — API errors, tool errors, or hitting their iteration budget — never from a delegation-level stopwatch. Earlier releases shipped a hard cap (300s, later 600s), which kept killing legitimately busy children mid-task: deep code reviews, large research fan-outs, and slow reasoning models routinely need more than 10 minutes while making steady progress the whole time. Genuinely stuck children are still detected on every runtime, with or without a configured cap: the heartbeat staleness monitor watches each child’s progress signals (API calls, tool starts, activity-timestamp ticks). A child whose progress is completely frozen past the stale threshold — 450s idle between turns, 1200s while inside a tool — is interrupted and its wait is abandoned: the parent gets astatus: "timeout" entry whose error reads Subagent stopped making progress after N API call(s) — no activity for 450s (heartbeat stale threshold); the pending worker was abandoned. The wait ends even in one-shot runs (mibyan chat -Q, Bot Chat one-shot, cron) that have no gateway inactivity watchdog behind them, so a wedged child can no longer hold the turn or its session lease forever. An in-flight model wait still counts as progress — subagents refresh the activity clock while waiting on the provider, so a slow local / long-prefill completion is not treated as stalled.
If you want a cap anyway (e.g. cost control on unattended cron-driven delegation), opt in per-install:
0 or a negative value disables the cap; the heartbeat staleness monitor below stays active either way.
At ~80% of an idle window the child receives a one-line [delegation budget warning] through its steer channel (delivered at its next iteration boundary) telling it how long it has been idle and to return its summary now, so a slow-but-recoverable child can wrap up instead of losing its context. The warning fires once per idle window and re-arms when progress resumes.
When a configured cap or the stale threshold fires, the child’s result carries
structured timeout metadata alongside the error message so parents and hooks
can distinguish a stopwatch kill from other failures without parsing text:
timeout_seconds (whichever limit actually ended the wait — the stale
threshold when it pre-empts a longer configured cap, otherwise the cap),
timed_out_after_seconds (actual wall clock), last_event_age (how long
the child had been silent when the wait ended — the fast way to tell a slow
provider from a runaway), and timeout_phase
(before_first_llm_call when the child never reached its first request,
after_llm_calls otherwise). All four are null on non-timeout errors.
Failure Visibility
A subagent that fails — non-retryable provider error (404/400), timeout, crash, or no usable output — is never silent:- CLI: the delegation tree prints a one-line reason:
⚠️ Subagent failed — "your goal": HTTP 404: model not found (after 12s). Batch runs append the reason to the per-task✗completion line. - Gateway platforms (Telegram, Discord, Slack, …): the same clean line is delivered as a standalone chat notice, even when
tool_progressis off for that platform. - Parent agent: the tool result entry carries
status: "failed"plus the fullerrortext, so the model can react (retry, re-route, report).
Stall Detection for Background Subagents
Background delegations (delegate_task(background=true)) are watched by a
progress-based stall monitor — on by default, zero config. Unlike a
wall-clock timeout, it never touches a child that is making progress, no
matter how long it runs.
The monitor samples each detached child’s progress signals — API-call count,
current tool, and last-activity timestamp (which ticks on every streamed
token, tool transition, and API-call boundary, so a child mid-stream on a
long response always counts as alive):
- Progressing children are never touched. Any advancing signal resets the clock.
- A child whose progress is completely frozen past the stale threshold (450s idle, 1200s while inside a tool — legitimately slow terminal commands and web fetches get the higher ceiling) is interrupted and given a 120s grace window. A child that unwinds in time delivers its partial results through the normal completion path.
- A child that never returns is force-finalized with a terminal
stalledcompletion event, so the owning session hears an outcome instead of going silent, and the async slot frees for new work.
stalled event carries structured metadata mirroring the sync-path
timeout fields: stalled_after_quiet_seconds, stall_threshold_seconds,
stall_phase (idle / in_tool), and stall_grace_seconds.
This closed a long-standing failure mode where a wedged background child
left its session looking dead until a process restart. The underlying wedge
(children hanging at their first API call after multi-day gateway uptime)
was also fixed at the root: delegated children now run their OpenAI-wire
API requests inline on their own conversation thread instead of a nested
worker thread — the layer where the wedge lived. The stall monitor remains
as the safety net for anything else.
Monitoring Running Subagents (/agents)
The TUI ships a /agents overlay (alias /tasks) that turns recursive delegate_task fan-out into a first-class audit surface:
- Live tree view of running and recently-finished subagents, grouped by parent
- Per-branch cost, token, and file-touched rollups
- Kill and pause controls — cancel a specific subagent mid-flight without interrupting its siblings
- Post-hoc review: step through each subagent’s turn-by-turn history even after they’ve returned to the parent
Live activity above the composer
The classic CLI, TUI, and Desktop automatically show live subagents above the composer. You can keep writing while watching the live count, task names, elapsed time, and latest activity. The terminal dock limits visible rows according to screen height and shows how many additional workers are hidden; Desktop previews up to three workers.
Closing the terminal monitor returns to your existing composer draft. Steering uses its own input and acknowledges queued, not delivery: the child consumes guidance at a checkpoint. Stop does not interrupt unrelated siblings.
Background processes share the dock. Anything the agent starts with
terminal(background=true) (a build, a test run, a dev server, a CI poller) appears in a Processes block under the subagent rows the moment it spawns — ⚙ <command> · 42s · last: <latest output line> — and flips in place to ✔ exit 0 / ✘ exit 1 / ✘ killed when it ends, then leaves the dock about 60 seconds later (the completion notification in the conversation is the durable record). In the Classic CLI monitor, process rows sit under the agents: Enter shows the process log tail and x stops that one process; processes cannot be steered. The TUI /agents overlay lists the same block under the spawn tree (/stop ends every background process). Desktop shows the same processes as tiles above the composer.
Press Ctrl+R in the Classic CLI or TUI composer to toggle the dock between its multi-row preview and a single shaded summary line. F7 remains an optional alias when the terminal forwards function keys. The summary retains the live count and expand/restore hints, adding activity when space permits. Typing and sending remain available; opening and closing the monitor preserves your draft and insertion point. This is a local presentation choice, not a saved config change.
The live transcript tail is a bounded recent excerpt, not an unlimited conversation browser. A child leaving the live registry leaves the dock; completion messages and the TUI/Desktop history views remain the place to review finished work. Latest activity is an observation, not a percentage-complete estimate.
The classic CLI’s /agents and /tasks commands still print a text summary; Ctrl+T (or F6) is the immediate interactive monitor, including while the parent is busy. See TUI — Slash commands.
On the classic CLI and every gateway platform (Telegram, Discord, Slack, …),
/agents also lists background delegations with live per-child activity,
sampled directly from each running child:
stalling · no progress 450s — interrupting, and long-quiet-but-healthy
children show their quiet time so you can tell “slow” from “stuck” at a
glance.
Steering a Running Subagent
Interrupting a child throws away its in-flight work; often you just want to redirect it.From the parent agent (model-facing)
The parent agent orchestrates its own running children with the samedelegate_task tool it spawned them with — no separate control tool:
listreturns the conversation’s live children:subagent_id, goal, status,running_seconds,accepting_steer, and the live transcript path. Ids also come back in the spawn dispatch response assubagent_ids.steerqueues a course correction into a running child without stopping it (delivery semantics below).stopends a child early at its next iteration boundary; the partial result still re-enters the conversation as a normal completion message.
stop keeps working even after the cap is hit.
From the TUI / gateway (session-facing)
steer_subagent(subagent_id, text) in tools/delegate_tool_registry.py is the redirection-side mirror of interrupt_subagent(): it queues text into a live child through the same mechanism as /steer — the text is appended to the child’s last tool result at its next iteration boundary, the in-flight tool call is never cut, and the child sees it as an out-of-band user message. Programmatic hosts reach it through the session-scoped subagent.steer gateway RPC, which sits beside subagent.interrupt:
delegation.status (or list_active_subagents()) — the same place subagent.interrupt gets them. The gateway accepts steering only from the exact live UI/gateway session that spawned the child. A missing, foreign, ambiguous, or stale/recycled session identity is rejected; knowing a global subagent id is not authority. Direct in-process callers retain the unscoped helper contract deliberately.
Queued is not delivered, but it is never synthetic success. A "queued" response means the text was accepted before the child’s completion boundary, not necessarily that the child has seen it. Acceptance and completion are synchronized: either the child can still consume the text, or its exact text is drained into the result as pending_steer. Calls after closure return "rejected". If a child accepted the steer but had already produced its final answer, the completion entry the parent receives retains it as missed_steer, with a note appended to the summary:
Live Transcripts
Everydelegate_task dispatch also creates one append-only, human-readable log per task so you (or the parent agent) can watch a subagent work in real time instead of waiting for the consolidated summary:
live_transcripts, and the files are pre-created at dispatch time, so this works immediately:
-> tool_name({args})), tool results, and a final status marker. A manifest.json in the same directory describes the batch (goals, task count, per-task status). The logs persist after completion — they double as the full-fidelity operational record alongside the summary — and directories older than 7 days are pruned automatically on new dispatches. Because they live under cache/delegation, they are also readable from remote terminal backends (Docker/Modal/SSH).
Depth Limit and Nested Orchestration
By default, delegation is flat: a parent (depth 0) spawns children (depth 1), and those children cannot delegate further. This prevents runaway recursive delegation. For multi-stage workflows (research → synthesis, or parallel orchestration over sub-problems), a parent can spawn orchestrator children that can delegate their own workers:role="leaf"(default): child cannot delegate further — identical to the flat-delegation behavior.role="orchestrator": child retains thedelegationtoolset. Gated bydelegation.max_spawn_depth(default 1 = flat, sorole="orchestrator"is a no-op at defaults). Raisemax_spawn_depthto 2 to allow orchestrator children to spawn leaf grandchildren; 3+ for deeper trees. There is no upper ceiling — cost is the practical limit.delegation.orchestrator_enabled: false: global kill switch that forces every child toleafregardless of theroleparameter.
max_spawn_depth: 3 and max_concurrent_children: 3, the tree can reach 3×3×3 = 27 concurrent leaf agents. Each extra level multiplies spend — raise max_spawn_depth intentionally.
One-shot runs are capped separately. mibyan chat -q / --oneshot sessions may spawn at most delegation.oneshot_max_children subagents in total (default 2, 0 = unlimited). A one-shot run has no later turn to receive results, and in benchmark trajectories most of its spawns were “independently review my own work” rather than parallel work — each such child re-pays a cold system prompt and re-reads the repo. Interactive and gateway sessions are unaffected.
Lifetime and Durability
Key Properties
- Each subagent gets its own terminal session (separate from the parent)
- Subagents inherit the parent’s enabled toolsets; the model cannot select or widen them per call
- Nested delegation is opt-in — only
role="orchestrator"children can delegate further, and only whenmax_spawn_depthis raised from its default of 1 (flat). Disable globally withorchestrator_enabled: false. - Leaf subagents cannot call:
delegate_task,clarify,memory,send_message,cronjob. Orchestrator subagents retaindelegate_taskbut keep the other blocks. Both roles retainexecute_code(programmatic tool calling) so children can batch mechanical work instead of burning reasoning iterations. - Cancellation follows ownership —
/stopor closing/resetting the owning session ends its background children and the synchronous descendants beneath them; each returns an interrupted completion carrying its partial output - Only the final summary enters the parent’s context, keeping token usage efficient
- Subagents inherit the parent’s API key, provider configuration, and credential pool (enabling key rotation on rate limits)
Worktree Isolation
By default, subagents share the parent’s working directory — fine for research and read-heavy work, but parallel children editing the same repo can collide. Setdelegation.worktree_isolation: true to give each child its own git
worktree, branched from the repo’s current HEAD (inspired by Muse Code’s
--subagent-worktree-isolation):
- Each child starts its terminal in
<repo>/.worktrees/subagent-<id>on its own branchmibyan-subagent/subagent-<id>, and its goal message tells it to work and commit there. - The parent’s checkout stays untouched; children can’t clobber each other’s edits.
- When a child finishes, its result entry gains a
worktreefield reportingpath,branch,commits(ahead of the base), anddirty. The parent reviews or merges each branch (git log <branch>,git merge <branch>). - A worktree left with no commits and a clean tree is pruned automatically
(
pruned: true); anything holding work is kept. - Pruning requires proof. If a git inspection probe fails — or finalization
itself errors — the worktree and branch are kept and the entry carries
inspection_failed: trueplus anote—commits/dirtyare then defaults, not measurements, so inspect the worktree rather than assuming the child produced nothing.
Delegation vs execute_code
Rule of thumb: Use
delegate_task when the subtask requires reasoning, judgment, or multi-step problem solving. Use execute_code when you need mechanical data processing or scripted workflows.
Configuration
base_url points at an Anthropic-compatible endpoint — for example a path ending in /anthropic, an Azure Foundry Claude route, or a MiniMax /anthropic proxy — api_mode is auto-detected as anthropic_messages so the subagent uses the right wire format without you setting anything. Set api_mode explicitly when the auto-detection guess is wrong (rare).
Subagents compact where their parent does: at compression.threshold × window (0.50 by default), or the global compression.threshold_tokens cap when one is set and lower. delegation.compression_threshold_tokens (default 0, off) adds an optional absolute cap on a child’s compaction trigger, applied as the lower of it and the ratio threshold; it never touches the request payload or the parent. A token count of at least 16000 enables it; true or "200k" are config errors that are warned and ignored. It stays off by default because a replay of a 1,393-agent run put 200K–400K caps within 5% of each other in cost once cache prefixes are intact, and every compaction is a chance to lose detail.
delegation.request_overrides works on all three resolution branches — direct base_url, named provider, and pure inherit — so it always takes effect. Top-level keys are API kwargs (e.g. service_tier); an extra_body sub-dict is merged into the request’s extra_body. Explicit values merge over runtime- or parent-derived overrides: explicit top-level keys win, and extra_body is deep-merged one level, so a provider’s own request personality (e.g. thinking: {type: disabled}) survives unless your key redefines it. See Configuration → Delegation for details.

