Install
openclaw skills install safe-subagent-spawnSafely create and manage subagents through a strict wrapper instead of calling sessions_spawn directly. Use whenever a task needs a subagent, detached helper, or delegated worker. Mandatory for all models when creating a subagent. Supports multi-round continuity via shared context files with full-text history.
openclaw skills install safe-subagent-spawnUse this skill whenever you need to create a subagent. Do not call sessions_spawn directly.
sessions_spawn directly. Always use scripts/safe_subagent_spawn.py to generate the payload.runtime: "subagent"mode: "run"thread: falsecleanup: "keep" (preserve sessions to expose subagent issues)streamTo: never includedagentId with model. agentId must be a real agent id from agents.list[].id — never a model alias or provider/model string.
agentId is optional and rarely needed. Omit it unless the user explicitly names a target agent that exists in agents.list[].id.model field.agentId: "google/gemini-2.5-pro" — WRONG!! this is a model stringagentId: "main" — correct, a real agent idagentId entirely — correct defaultscripts/append_to_context.py for all appends. The parent tracks each context file by its task slug (visible in the file's Metadata section and filename) and file path.a-z, 0-9, and - (lowercase ASCII letters, digits, and hyphens). Must start and end with an alphanumeric character. Maximum 48 characters. The script validates this and rejects invalid names — no silent transformation.| Script | Purpose |
|---|---|
scripts/create_context.py | Create a new context file (initial metadata + background + first directive) |
scripts/safe_subagent_spawn.py | Generate a spawn payload from an existing context file |
scripts/append_to_context.py | Append a directive, child output, or external message to a context file |
All
scripts/paths are relative to this skill's installation directory.
When spawning a subagent, the parent must decide whether to reuse an existing context file or create a new one.
Reuse the existing context file when:
Create a new context file when:
When in doubt, create a new file. Unnecessary context is worse than missing context.
scripts/create_context.py \
--task "descriptive-task-slug" \
--background "the user's original request or relevant background" \
--directive "clear instructions for the child agent"
--directive is optional. Omit it to create a context file with only metadata and background — useful when you need to collect information (via External Messages) before formulating the first directive. A context file without a directive cannot be spawned until a directive is appended (the spawn script enforces this).
Output (stdout): the absolute path to the newly created context file.
If the context file was created without --directive, append External Messages to supply information before defining the task:
scripts/append_to_context.py \
--context-file "<context_path>" \
--role external-message \
--content "information gathered from an external source"
When ready, append the first directive:
scripts/append_to_context.py \
--context-file "<context_path>" \
--role directive \
--content "instructions for the child agent, informed by the external messages above"
Then proceed to Step 2 to generate the spawn payload.
The context file must contain at least one Directive section. The script validates this and rejects files that have no directive.
scripts/safe_subagent_spawn.py \
--context-file "<context_path>" \
--timeout-seconds 300
Optional parameters:
--child-model "provider/model-name" — Override the child agent's model. Maps to the model field (string, optional) of sessions_spawn, overriding the parent's default model.--agent-id "agent-name" — Target a specific agent id (must come from agents.list[].id). Rarely needed — omit unless the user explicitly names an existing agent.--timeout-seconds should be determined by the parent agent based on task complexity. Default is 300 seconds. Use a shorter value for simple tasks and a longer value for complex ones.
Output (JSON): the spawn payload. Use it directly when calling sessions_spawn. Do not modify or add fields.
Pass the JSON output from Step 2 directly to sessions_spawn as the complete argument:
sessions_spawn(<complete JSON payload from Step 2>)
Do not manually decompose or reassemble fields. The script output is the ready-to-use payload.
Append the child's full verbatim output to the context file:
scripts/append_to_context.py \
--context-file "<context_path>" \
--role child-output <<'CHILD_EOF'
<full verbatim child output>
CHILD_EOF
For very long output, use a temp file instead:
# Write output to temp file first, then append
scripts/append_to_context.py \
--context-file "<context_path>" \
--role child-output \
--content-file /tmp/child_output.txt
External messages can be appended in two positions:
--directive, to supply information before formulating the first task (see Step 1b).If the parent has incrementally obtained information (e.g., streaming results, user replies, external API responses), append it as external messages before appending the next directive:
scripts/append_to_context.py \
--context-file "<context_path>" \
--role external-message \
--content "first piece of information"
scripts/append_to_context.py \
--context-file "<context_path>" \
--role external-message \
--content "second piece of information, appended to the same section"
External messages have no round numbers and no timestamps. Multiple consecutive appends are merged into a single ## External Message section — no new header is created until the next directive starts a new round.
External messages can only appear (1) after Background and before the first Directive, or (2) between a Child Output and the next Directive. The script enforces this ordering.
If the task requires another round, append a new directive and spawn:
# Append new directive
scripts/append_to_context.py \
--context-file "<context_path>" \
--role directive \
--content "new instructions for the next round"
# Generate spawn payload (same as Step 2)
scripts/safe_subagent_spawn.py \
--context-file "<context_path>" \
--timeout-seconds 300
Then spawn using the output payload (same as Step 3).
The next child reads the entire context file — including all prior directives and child outputs — and executes the latest directive.
scripts/append_to_context.py auto-detects round numbers and appends structured entries:
---
## Directive — Round 2 — 2026-04-02T12:00:00+00:00
<parent's instructions for this round>
---
## Child Output — Round 2 — 2026-04-02T12:05:00+00:00
<full verbatim output from child agent>
For external messages (no round number, no timestamp; consecutive appends merge into one section):
---
## External Message
<first piece of information>
<second piece of information, appended without a new header>
Content can be provided via:
--content "inline text" — for short directives--content-file /path/to/file — for long content stored in a fileDeduplication: If the content being appended is identical to the latest existing entry of the same role, the script silently discards the duplicate and exits successfully (exit code 0).
All context files are stored by default under sub-agents/ in default workspace folder, named {timestamp}-{task-slug}.md.
When --directive is omitted during creation, the file initially contains only Metadata, Standing Instructions, and Background. External Messages and the first Directive are appended later via append_to_context.py.
# Subagent Context: {task-slug}
## Metadata
- Created: {ISO-8601 timestamp}
- Task: {task-slug}
- Context File: {absolute path}
## Standing Instructions
- Do not self-append or modify this file. It is read-only context provided by the parent.
- Do not spawn additional subagents inside this subagent. All delegation must come from the parent.
## Background
{user's original request or relevant background information}
---
## Directive — Round 1 — {ISO-8601 timestamp}
{clear instructions for the child agent}
---
## Child Output — Round 1 — {ISO-8601 timestamp}
{full verbatim output from child agent}
---
## Directive — Round 2 — {ISO-8601 timestamp}
{new instructions for the next round}
---
## Child Output — Round 2 — {ISO-8601 timestamp}
{full verbatim output from child agent}
---
## External Message
{incrementally appended information from parent, before next directive}
---
## Directive — Round 3 — {ISO-8601 timestamp}
{instructions that can reference the external messages above}
When the context file is created without a directive (deferred directive pattern), the initial portion looks like:
# Subagent Context: {task-slug}
## Metadata
- Created: {ISO-8601 timestamp}
- Task: {task-slug}
- Context File: {absolute path}
## Standing Instructions
- Do not self-append or modify this file. It is read-only context provided by the parent.
- Do not spawn additional subagents inside this subagent. All delegation must come from the parent.
## Background
{user's original request or relevant background information}
---
## External Message
{information collected before the first directive}
---
## Directive — Round 1 — {ISO-8601 timestamp}
{instructions informed by the external messages above}
If any step in the workflow fails — script error, subagent timeout, or wrapper unavailable:
sessions_spawn directly.