description, kind
| description | kind |
|---|---|
| Discover and coordinate a subagent tree through messaging, interruption, and inbox waiting. | package-reference |
@deepseek-ai/dsh-tool-subagent-control
English | 中文
Summary
dsh-tool-subagent-control lets agents discover and message their subagent tree by Session id, interrupt descendants, and wait for their own next-step inbox. By default, one plugin instance registers all four tools; members inherit the same definitions and ordering.
Table of Contents
- Use this package
- Understand the implementation
- Further Exploration
- Model Experience
- Known Limitations and Deferred Work
- Dev Note
Use this package
Mount this package once per tool scope. It requires tools, subagents, agents, and systemPrompt.
Minimal configuration
With the required services available, load the subagent service, a backend, the delegation tool, and this package to expose all four control and discovery tools:
- name: '@deepseek-ai/dsh-subagent'
- name: '@deepseek-ai/dsh-subagent-spawn-in-process'
- name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: spawn
- name: '@deepseek-ai/dsh-tool-subagent-control'
Set config.interrupt: false to omit interrupt_agent. The default is true. The other three tools and ctx.subagents.interrupt() remain available. See the generated configuration catalog.
send_message
Sends a message to another agent in the same subagent tree by agent_id. The caller must be the live root or a resident continuable subagent. A working target receives Steer input at its next step; an inactive target starts or resumes a turn. Only the target resumes; its creation ancestors stay offline. Success returns inbox acceptance (messageId), never a reply. Self, unrelated trees, unsupported targets, unknown ids, unavailable history, and rejected admission return errors.
interrupt_agent
agent_id identifies a descendant by Session id. External executions stop permanently and cannot receive follow-ups. Local targets stop only their current turn: queued messages stay parked until a later send_message, descendants keep running, and the child stays available for follow-ups. The call returns when the stop request is accepted, not when the target is quiet; interrupting an already-finished agent is an accepted no-op, and self, sibling, stale, and non-ancestor callers get errored results.
wait_agent
Waits for the exact caller’s next-step inbox. Pending input returns immediately; later input, including messages, completion notifications, and user steering, ends the wait. Queued next-turn messages, unrelated inboxes, and Agent status changes do not end it. Task changes do not end the wait. The tool neither consumes input nor starts an Agent. timeout_ms defaults to 30000 and must be an integer from 10000 through 3600000. Results contain only timedOut; cancellation, caller disposal, or plugin unload rejects the wait.
list_agents
Lists the root and all reachable continuable descendants, including the caller, in stable pre-order. Descendant rows carry their direct parent id and depth from the root. Live status is running or inactive. External entries are omitted without reading child Sessions; readable one-shot children remain traversal nodes. Unknown modes and unreadable catalogs produce diagnostics. Ordinary Session forks lead separate subagent trees.
Understand the implementation
Implementation internals — click to expand
This section explains what the tools delegate to the subagent service; the observable behavior is covered in Use this package.
Design concept
Messaging, interruption, and discovery delegate to ctx.subagents; residency, cold resume, and authorization belong to that service. The wait tool subscribes to the exact caller’s inbox events before starting the timer and checking pending next-step input, and removes its listeners and timer on every settlement.
Delivery and signal ownership
The execution signal owns work only until inbox acceptance. Accepted messages cannot be cancelled through this tool. Every message is framed as Agent <sender-id> sent a message: and recorded with { kind: 'agent-message', form: 'relay', senderSessionId: sender.id }. Tree membership authorizes communication; the subagent tree root owns runtime instances and capacity.
Listing projection
list_agents resolves the caller’s live root and traverses its catalogs without a cursor, refining activity through the live Agent registry. Unknown modes remain traversable with diagnostics; unreadable catalogs stop that branch. Sessions absent from reachable catalogs cannot be discovered.
Source map
| File | Role |
|---|---|
src/index.ts |
Shared control-tool registration |
src/list-agents.ts |
Whole-tree discovery and activity projection |
src/wait-agent.ts |
Exact-caller inbox wait and cleanup |
Further Exploration
Read these pages when the package-level contract is not enough; they move from the tool schemas to the continuation service behind them.
- Subagent subsystem — continuable children, activations, inbox, interrupt, and follow-up authority.
- dsh-tool-subagent — the delegation tool that starts continuable children.
- Generated tool catalog — the tool schemas.
Model Experience
Tool schema
What the model sees
The generated schemas define id-addressed messaging and interruption, whole-tree discovery, and inbox waiting with timeout_ms. wait_agent returns { "timedOut": false } for available input, and { "timedOut": true } on timeout. It returns no message body or peer-activity diagnosis.
Token effect
Fixed schema cost per request, independent of the number or descriptions of children; disabling interruption removes its schema and discovery guidance.
KV Cache effect
Prefix-stable; the schemas do not change at runtime, and a parent and its continuable children, including fork children, receive identical definitions.
Communication context
What the model sees
The logged subagent:communication runtime context tells delegated children their direct creator’s JSON-encoded id and how to send findings that change the parent’s next action. Sending a message does not end the turn. Root Agents and ordinary Session forks receive no communication context; delegated children receive it only when the standard messaging definition is admitted in the current scope and step. Automatic result delivery remains owned by the subagent service.
Token effect
One short context entry per delegated child, independent of tree size.
KV Cache effect
Communication guidance is retained as runtime context after inherited history, leaving the shared system prompt and tool definitions unchanged between parent and child. Cold resume derives the parent id again from the target Session.
Interrupt result
What the model sees
interrupt requested for agent <agent_id> on acceptance. An unauthorized caller — self, sibling, stale, or non-ancestor — is an errored result naming the rejection; an absent or settled target still renders the acceptance line.
Token effect
One short acknowledgement per call; the interrupted turn's abort is visible only in the child's own transcript.
KV Cache effect
Append-only; each result follows the reusable request prefix.
Delivery result
What the model sees
message delivered to agent <id> on acceptance; canonical output carries the accepted messageId. A target outside the caller’s subagent tree or rejected admission produces an errored result.
Token effect
One short acknowledgement per call; replies arrive as separately addressed messages. Use ids from list_agents for follow-ups across the subagent tree.
KV Cache effect
Append-only; newly visible content follows the reusable request prefix and does not invalidate existing KV-cache entries.
Listing result
What the model sees
The first row is <id> [<status>] — root agent. Each continuable descendant follows as <id> [<status>] parent=<id> depth=<n> — <label>. The root has kind: root; descendants have kind: child relative to that root. Diagnostics render <id> [diagnostic: <reason>] parent=<id> depth=<n>. Status describes turn activity, not task completion.
Token effect
Grows linearly with the whole subagent tree’s listed rows. There is no cursor or cap.
KV Cache effect
Append-only; each result follows the reusable request prefix.
Known Limitations and Deferred Work
These limits define what the control tools cannot observe or steer; they are current package constraints.
- A delivered message has no independent result — acceptance returns only its inbox
messageId; later target work lands in that target's durable Session and is never collected through this tool. A reply is another explicitly addressedsend_message, not this call's result. - Messaging requires a live subagent tree root — intermediate creators may be offline. Only the target resumes, consuming one shared capacity slot. Unrelated trees and external or one-shot targets cannot receive messages.
- Listing is a snapshot, not a delivery promise — it may race publication, disposal, or a later message, and another process may activate a child this process reports as
inactive; cross-process accuracy requires a shared lease.interrupt_agentperforms the authoritative live-lineage check itself, so discovery staleness cannot grant authority. - No pagination or deletion — the complete stably ordered set is returned, and persisted children remain listed for as long as their sessions remain in persistence; a service-level bound or delete operation is a later product decision.
Dev Note
Working context for maintainers — click to expand
None.