Address review: `agentType` was a Claude-Code concept (`subagent_type`) that does not fit our own subagent seam — nothing in the harness interprets it, and its only consumer was the CC-dialect hook bridge. Rather than let a foreign concept sit on the core seam, remove it: - `SubagentStartRequest`, `SubagentRunInfo`, `SubagentRunEndInfo`: drop the `agentType` field; the `subagent/start`/`subagent/end` payloads now carry `provider`/`id` (+ end `stopReason`/`lastAssistantMessage`) only. - `dsh-tool-subagent`: drop `Config.agentType` and its request plumbing. - Tests: keep the lastAssistantMessage / clone-containment / reject-path coverage (rewritten to not assert agentType); delete the two tool-subagent tests that only exercised agentType forwarding (dead behavior). - Docs: retitle + rewrite the subagent-observe-enrich RFC to the one shipped enrichment (lastAssistantMessage), with a note on why agentType was dropped; update rfc/README index title, both subagent READMEs, and the core-data-structures/subagent.md type-equiv block + prose; regenerate catalog. The CC bridge (PR-F) will feed Claude Code's own default matcher value "general-purpose" for its SubagentStart/Stop agent_type matcher instead.
@deepseek-ai/dsh-tool-subagent
The model-facing subagent tool: delegate a self-contained task to a child agent and return its final output. Pure schema + lifecycle shaping over the ctx.subagents provider registry — an in-process, ACP, or future A2A backend swaps in without changing what the model sees.
Provider selection is config, not model-facing
This plugin binds to exactly one provider (Config.provider). The model sees only { description, prompt } — there is no provider/type parameter in the schema. To expose more than one transport, load the plugin more than once, each bound to a different provider and a distinct toolName (the tool registry rejects a duplicate name, so a second load that kept the default subagent name would throw). Keeping selection in config (not the schema) is the deliberate split: the service holds a multi-provider registry; the tool picks one.
| Config key | Meaning |
|---|---|
provider (required) |
The ctx.subagents provider name to start runs on (spawn, fork, acp, …). |
toolName |
The model-facing tool name to register (default subagent). Set a distinct value per load when exposing multiple providers, e.g. subagent + subagent_acp. |
agentOptions |
Default per-child { model?, systemPrompt? } applied to every spawned child. |
Lifecycle (synchronous collect)
execute starts a run on the configured provider and awaits run.result inside a try/finally that always dispose()s the run — the owned child agent/session is torn down on every path (success, error, abort), never leaked. The tool's abort signal (exec.signal) is bridged to run.cancel(). A non-completed stop reason (aborted/error/max-tokens/refusal) maps to an isError tool result rather than returning partial output as success.
Background / poll collection is deferred (see the RFC); this cut blocks the parent turn until the child finishes.