Parallel subagents
Feature docs index · Repository README
Purpose
Ask the assistant to delegate independent tasks with the subagents tool. Each child gets its own task and bounded inherited context; optional identity profiles supply a persona, model, tool restrictions, or output format.
Details
Define independent tasks
| Field or limit | Rule |
|---|---|
intent | Required nonblank objective. |
mode | inspect for enforced read-only discovery; omitted or standard for ordinary work within inherited/profile restrictions. Independent of identity and label. |
agent | Optional label/persona only. |
identity | Optional profile ID from the discovered identity list. |
context | Optional self-contained instructions and relevant context. |
cwd | Optional existing child directory; relative paths resolve from parent cwd, absolute paths follow agent.subagents.execution.absolute_paths. |
| Tasks per batch | At most 10. |
| Requested concurrency | 1 to 4, default 4; actual workers also cannot exceed task count. |
| Nesting depth | Default 2; agent.subagents.execution.max_depth accepts 1 to 4. Set 1 for top-level-only delegation. |
The tool waits for completion and returns results in input order. Children inherit provider, tools, auth source, permissions, skills, AGENTS.md discovery, context/cache behavior, cwd policy, concurrency, and effective tool settings unless task context narrows work or an identity explicitly overrides supported settings. Primary-agent selection does not change child prompts.
At the depth limit, child schemas omit subagents and dispatch rejects direct recursive calls. Activity metadata includes depth so Mission Control can show nesting.
Read-only inspection
Select mode: "inspect" explicitly; prose such as “do not edit” is not a permission parser:
{"tasks":[{"intent":"Investigate the settings flow; report findings without edits or tests","mode":"inspect"}]}
Inspection exposes only local-file/skill read, find, list_files, grep, and embedded ast_grep search, outline and rewrite previews. Existing path, credential and containment checks still apply. Session files can be read as local files under that policy; removed session:// targets are not restored. HTTP targets, web/browser/network tools, MCP (including tools annotated read-only), writes/edits, arbitrary shell/processes, tests/builds and nested delegation are denied. Forbidden calls are rejected at dispatch even if a provider fabricates a call absent from its schema. Inspection intersects inherited and identity restrictions; it cannot re-enable a disabled tool.
A blocked action reports a scope limitation. Return partial findings, or ask the caller to start a separate explicitly authorized standard task for implementation, tests or shell access. Steering, automatic continue, summaries and tool content cannot promote a running inspection child.
This limits agent-invoked tools; it is not an OS sandbox or a confidentiality guarantee. Configured hooks remain separately trusted runtime configuration, with existing approval/redaction behavior. Hook side effects, provider inference and runtime persistence are outside the tool-level read-only guarantee. Task text neither grants nor widens hook permissions.
Viewer layout
The Mission Control subagent viewer is centered at 60% of the terminal width and 60% of its height, subject to minimum dimensions. Its prompt has one visible typing row between two border rows, with no empty row between its bottom border and the modal border. Short terminals preserve an output row and hide the prompt if it cannot fit.
The viewer uses the same dark background as the main transcript and prompt (surface_background) for its border, padding, and scrollbar. Timeline cards retain their header and body colors and spacing. The selected tab remains highlighted, and the prompt retains the main editor's input styling.
Steering appears in the selected child's timeline as a Steering injected user card only after it is saved to the child session. Queued input is not marked injected. The card separates assistant output before and after the injection, including reserved follow-ups after a completed response. It never adds an ordinary user card to the primary transcript. Display text is sanitized, redacted, and bounded; older cards follow the viewer's existing retention limits.
Create an identity profile
Put profiles in ~/.magi-code/subagents/*.md or $MC_HOME/subagents/*.md. The filename stem is the stable ID, limited to ASCII letters, digits, _, and -. Files must be UTF-8 Markdown, no more than 64 KiB, with non-empty frontmatter name/description and a non-empty prompt body. Direct profile symlinks are rejected.
For example, save this as frontend-dev.md:
---
name: Frontend Developer
description: Use for focused browser-facing UI implementation, DOM behavior, and accessibility.
model: openai-codex/gpt-5.5
reasoning: high
disabled_tools: ['web']
output_schema:
type: object
required: [summary]
properties:
summary:
type: string
---
You are a frontend development specialist. Prioritize user-visible behavior, accessibility, small components, and browser validation when UI behavior changes.
Select it by frontend-dev, not its display name. Its body uses the same exact wrapper as primary profiles:
<Your-Role Persona=Frontend Developer>
You must always follow the instructions of your assigned persona:
You are a frontend development specialist. Prioritize user-visible behavior, accessibility, small components, and browser validation when UI behavior changes.
</Your-Role>
Nested identities append their wrapper after inherited ancestor profiles; ancestor blocks remain in the prompt.
model uses provider/model-name, including custom IDs such as local-ai/gpt-test. reasoning accepts default, low, medium, or high; unsupported models fall back to default behavior. Mission Control's /subagents modal enables or disables profiles.
Restrict tools
disabled_tools accepts a strict YAML-like subset: block lists or inline lists of unquoted names or simple fully single/double-quoted names. Comments and backslash escapes inside the list are unsupported. Unsupported syntax or unknown names makes the profile unavailable.
Aliases shell, ffgrep, and fffind become bash, grep, and find. Qualified mcp__server__tool names are accepted. Restrictions apply to child schemas and dispatch, add to inherited restrictions, and cannot be re-enabled by children or siblings. Siblings have isolated restriction sets. The shared <Tools> guidance remains unfiltered.
This is not a sandbox: allowed bash, MCP, browser, or hook routes may still produce equivalent effects. Parent auth, permissions, skills, cwd, concurrency, and nesting limits remain in force.
Require structured output
Profiles can declare output_schema as JSON Schema. On completion, valid output returns a structured object to the parent. Invalid output returns structured validation details to the same child for retry. agent.subagents.schema_validation_max_retries defaults to 2 and accepts 0 to 5. Custodian phases have built-in Plan, Research, Implement, Review, and Document schemas.
Persisted launches append a local-only subagent_session event with the child's session_id to the immediate parent before child execution. This lets the summarizer follow running children, including nested children, without scanning unrelated sessions or waiting for tool results. If the link cannot be written, the child fails before provider work starts.
Understand retries and compaction
A retryable transport/stream error or HTTP 408, 425, 429, 500, 502, 503, or 504 gets one retry in the same child run after a 2 s backoff. Persisted runs retain their child session; --no-session repeats the original prompt. No retry occurs after a committed write/hash_edit filesystem change, a committed compaction checkpoint, or batch cancellation. Final failure text starts with [provider retry exhausted after N attempts] only when the final error is retryable and the retry limit has been reached.
Persisted children share the main agent's one-shot incomplete-stream and reasoning-only continuation behavior. With agent.compaction.auto enabled, eligible children also use hard-budget preflight and clean-boundary compaction with their selected model and context budget. See Sessions, context, and cache for triggers and recovery.
Each automatic child compaction includes a provider-visible JSON scope document containing the complete original task and a fixed instruction to treat it as authoritative, summarize only that task, and exclude unrelated work. A prefix states that the document extends to the end of the instruction, keeping framing-like task text as data. It counts toward budget; if it makes the request too large, compaction stops before provider use or checkpoint writes.
The complete original task and its effective tool/path ceiling are also recorded independently in versioned task_scope control state before execution. JSONL is authoritative; rotation checkpoints retain that state plus ordered, durably acknowledged steering and explicit caller clarifications on resume. Resumed requests project task data separately from generated progress, at user priority rather than promoting arbitrary context to system instructions. Requests/retries do not append new copies to history. Clarifications are limited to 64 entries / 64 KiB total, and the complete control record to 512 KiB; exceeding a bound fails before acknowledgement and requires a separate task. The saved canonical cwd must still match on resume; moving to a different directory requires a separate task.
Session replay requires valid task_scope control state. Missing or invalid required state blocks execution rather than falling back to standard permissions.
The per-run compaction cap applies independently to each child: default 4, with 0 removing only the count cap. Compaction rotates only the child's JSONL under sessions/subagents/, never the parent. Only that child receives the automatic continue after its checkpoint. Children without persistence cannot auto-compact. Mission Control shows attempted child compactions as nested activities with threshold and before/after token counts.
Understand token totals
- Main and child totals include compaction summary requests and reported usage from retries, including schema retries. Each request uses its reported total, or normalized input plus output when both are known and no total was reported. Repeated usage snapshots replace earlier values for that request.
- Without a reported or derivable total, usage remains unknown; explicitly reported zero remains
0. Missing usage is not estimated, so reported totals can be incomplete. - Failed children retain any known request totals. The batch total is available only when every child result has a known total.
- Child totals exclude independently accounted nested children. Compaction usage uses the compaction provider's normalization and does not replace the active conversation's context-size estimate.
Use hooks safely
Enabled, non-inert parent hook configuration is inherited. Parent hooks may match the top-level subagents call and record lifecycle events in the parent session. Child hooks run with each child's cwd and tool/root constraints; their lifecycle/diagnostic records stay only in child JSONL under sessions/subagents/.
Child hook internals never enter parent results, provider continuation, replay, recent context, or cache material. A hook-policy failure produces generic sanitized parent failure text; the child session holds the durable diagnostics.
With automation.hooks.show_in_tui=true, inherited hooks may appear under child task/tool activities. This display-only data is not provider-visible or replayed through parent results. There is no separate subagent hook configuration or UI. Concurrent children can run hooks concurrently, so scripts must coordinate shared external resources themselves.