magi-code 0.104.0

Repository-aware CLI coding agent for terminal work
Documentation
# Parallel subagents

[Feature docs index](README.md) ยท [Repository README](../../README.md)

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.

## Define independent tasks

The `subagents` call requires a top-level nonblank `intent` explaining the batch. Each entry in `tasks` separately requires its own `intent` objective, described below.

| 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. A prose instruction such as "do not edit" does not enforce permissions:

```json
{"intent":"Delegate read-only settings investigation","tasks":[{"intent":"Investigate the settings flow and report findings without changes","mode":"inspect"}]}
```

Inspection permits local-file/skill `read`, `find`, `list_files`, `grep`, and read-only `ast_grep`. It denies network tools, MCP tools, edits, shell commands, builds, Code Mode, and nested delegation. Calls remain denied even if a provider requests a tool absent from its schema. Inherited and profile restrictions still apply.

Return partial findings when blocked. Implementation or shell access requires a separate, explicitly authorized standard task; steering and summaries cannot widen a running inspection task.

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.

## View and steer a child

Open a child's live viewer from its transcript card. It uses 60% of terminal width and height where space permits, with a separate prompt and tabs for sibling tasks. Short terminals may hide the prompt to keep an output row visible. See [Mission Control](mission-control-tui.md#follow-subagents) for keys and cancellation.

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`:

```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:

```text
<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](sessions-context-cache.md) 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.