chore(release): v0.8.33 — sub-agent and RLM renovation with persistent sessions

- Persistent RLM sessions (rlm_open/rlm_eval/rlm_close) with bounded REPL helpers
- Fork-aware sub-agent sessions (agent_open/agent_eval/agent_close) with handle_read
- Shared handle_read storage with slice/range/count/JSONPath projections
- Slash-command routing: /rlm, /agent, /relay (/接力) for handoff prompts
- Sidebar renamed to "Work" tab, consistent across Plan/Agent/YOLO modes
- Tool papercuts: file_search excludes, grep_files strings, fetch_url JSON,
  edit_file fuzz, exec_shell merged stdout/stderr, revert_turn no-op reject
- CLI reasoning-effort honoured on non-auto exec routes (#1511 @h3c-hexin)
- Edit-file replacement boundaries clarified (#1516)
- Pandoc output validated before probing (#1523)
- Running turns steerable/repaintable (#1533, #1537)
- Tasks/Activity Detail calmer under load
- npm retry timeout hint (#1538 @reidliu41)
- Issue templates improved (#1525 @reidliu41)
- Shell: kill process group to prevent UI freeze (#828 @CrepuscularIRIS)
- TUI: ignore leaked SGR mouse reports in composer (#1421 @reidliu41)
- Footer: keep chips within available width (#1417 @Wenjunyun123)
- Session picker: scope Ctrl+R to current workspace (#1395 @LinQ)
- Removed stale competitive-analysis doc
- Prompts/docs teach only new tool names
This commit is contained in:
Hunter Bown
2026-05-12 19:54:08 -05:00
parent 503551ddec
commit 99c6b22e83
80 changed files with 6158 additions and 2084 deletions
+38 -39
View File
@@ -1,23 +1,21 @@
# Sub-Agents
Sub-agents are background instances of the agent loop. The parent
agent spawns one with a focused task, gets back an `agent_id`
immediately, and continues working while the sub-agent runs to
completion. Sub-agents inherit the parent's tool registry by default
and run with `CancellationToken::child_token()`, so cancelling the
parent cancels every descendant.
Sub-agents are persistent background instances of the agent loop. The parent
opens one with a focused task, gets back an `agent_id` and session name
immediately, and continues working while the sub-agent runs to completion.
Sub-agents inherit the parent's tool registry by default and run with
`CancellationToken::child_token()`, so cancelling the parent cancels every
descendant.
This doc covers the role taxonomy. For the orchestration tool surface
(`agent_spawn` / `agent_wait` / `agent_result` / `agent_cancel` /
`agent_list` / `agent_send_input` / `agent_resume` / `agent_assign`)
see `prompts/base.md` "Sub-Agent Strategy" and the in-line tool
descriptions.
This doc covers the role taxonomy. The active orchestration surface is
`agent_open`, `agent_eval`, and `agent_close`; see `prompts/base.md`
"Sub-Agent Strategy" and the in-line tool descriptions.
## Role taxonomy
The `agent_type` field on `agent_spawn` selects a system-prompt
posture for the child. Each role is a distinct stance toward the
work — not just a different label.
The `type` field on `agent_open` selects a system-prompt posture for the child
(`agent_type` is accepted as a compatibility alias). Each role is a distinct
stance toward the work — not just a different label.
| Role | Stance | Writes? | Runs shell? | Typical use |
|---------------|----------------------------------------|---------|-------------|----------------------------------------------|
@@ -32,23 +30,22 @@ work — not just a different label.
Each role's full system prompt lives in
`crates/tui/src/tools/subagent/mod.rs` (search for
`*_AGENT_PROMPT`). The prompt prefix loads automatically when the
child agent boots; the parent's spawn prompt becomes the first
child agent boots; the parent's assignment prompt becomes the first
turn's user message.
## Context forking
`agent_spawn` starts fresh by default: the child gets its role prompt
plus the task you pass. Use `fork_context: true` when the child should
continue from the parent's current request prefix instead. In fork
mode the child request keeps the parent's system prompt and message
history byte-identical, appends a structured state snapshot, then
adds the sub-agent role instructions and task at the tail. That keeps
DeepSeek prefix-cache reuse high while giving the child the context
needed for continuation, review, summarization, or compaction work.
`agent_open` starts fresh by default: the child gets its role prompt plus the
task you pass. Use `fork_context: true` when the child should continue from
the parent's current request prefix instead. In fork mode the runtime keeps the
parent prefill/prompt prefix byte-identical where available, appends a
structured state snapshot, then adds the sub-agent role instructions and task
at the tail. That preserves DeepSeek prefix-cache reuse while giving the child
the context needed for continuation, review, summarization, or compaction work.
Use fresh spawns for independent exploration. Use forked spawns when
the task depends on decisions, files, todos, or plan state already in
the parent transcript.
Use fresh sessions for independent exploration. Use forked sessions when the
task depends on decisions, files, todos, or plan state already in the parent
transcript.
### When to pick which role
@@ -56,8 +53,12 @@ the parent transcript.
look", "design", or "verify". This is the right default; reach for
a more specific role only when the posture matters.
- **`explore`** — when the parent needs evidence before deciding what
to do next. Explorers are cheap and fast; spawn 23 in parallel
to do next. Explorers are cheap and fast; open 23 in parallel
for independent regions.
They should orient first: confirm the project root, read relevant
`AGENTS.md`/`README.md` guidance in unfamiliar trees, search only the
likely scope, and return `path:line-range` evidence instead of a narrative
tour. The role name to use is `explore` or `explorer`.
- **`plan`** — when the parent has an objective but no executable
decomposition. Planners write artifacts (`update_plan` rows,
`checklist_write` entries) but don't carry them out.
@@ -74,7 +75,7 @@ the parent transcript.
candidates under RISKS.
- **`custom`** — only when the parent needs to constrain the tool
set explicitly. Pass the allowlist via the `allowed_tools` field
on `agent_spawn`.
on `agent_open`.
### Aliases
@@ -98,9 +99,9 @@ the next turn.
The dispatcher caps concurrent sub-agents at 10 by default
(configurable via `[subagents].max_concurrent` in `~/.deepseek/config.toml`,
hard ceiling 20). When the parent hits the cap, `agent_spawn` returns
an error with the cap value; the parent should `agent_wait` for
completion or `agent_cancel` to free a slot before retrying.
hard ceiling 20). When the parent hits the cap, `agent_open` returns
an error with the cap value; the parent should use `agent_eval` to wait for
completion or `agent_close` to free a slot before retrying.
The cap counts only **running** agents — completed / failed /
cancelled records persist for inspection but don't occupy a slot.
@@ -109,7 +110,7 @@ restart) also don't count against the cap.
## Lifecycle
Each spawn produces a record that progresses through:
Each opened session produces a record that progresses through:
```
Pending → Running → (Completed | Failed(reason) | Cancelled | Interrupted(reason))
@@ -118,20 +119,18 @@ Pending → Running → (Completed | Failed(reason) | Cancelled | Interrupted(re
`Interrupted` fires when the manager detects a `Running` agent
whose task handle is gone — typically after a process restart that
loaded the agent from `~/.deepseek/subagents.v1.json`. The parent
can `agent_resume` to attempt continuation or treat it as a
can open a replacement session with the same assignment or treat it as a
terminal state.
### Session boundaries (#405)
Each `SubAgentManager` instance assigns itself a fresh
`session_boot_id` on construction. Every spawn stamps the agent
`session_boot_id` on construction. Every new session stamps the agent
with that id; the persisted state file carries it across restarts.
`agent_list` defaults to **current-session only**: prior-session
agents that aren't still running are filtered out. Pass
`include_archived=true` to surface every record, with the
`from_prior_session: true` flag so the model can tell archived
records apart from live ones.
`agent_eval` and the sidebar/status projections focus on current-session
agents by default. Prior-session agents that are not still running are treated
as archived records so the model does not mistake stale work for live work.
Records that loaded from a pre-#405 persisted state file (no
`session_boot_id` field) classify as prior-session because the