refactor(subagent): drop the agentType lifecycle field
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.
This commit is contained in:
@@ -32,7 +32,7 @@ Unlike the bash seam (one executor per context, second load throws), **multiple
|
||||
|
||||
`provider.start(request)` returns a `SubagentRun`: a handle with a `result` promise, `cancel()`, `dispose()`, and the optional runtime methods. `result` resolves with a `SubagentResult` (`output`, optional `structured`, `stopReason`) — it does **not** reject on a child-level failure (a model/transport failure resolves with `stopReason: 'error'`), so the consumer maps a non-`completed` reason to an `isError` tool result. The consumer MUST `dispose()` on every path (success, error, abort) to reach child quiescence and avoid leaking an idle child / session.
|
||||
|
||||
The service emits `subagent/start` (payload `SubagentRunInfo`) and `subagent/end` (payload `SubagentRunEndInfo`) around the run — both **observe-only** (plain `emit`s; `subagent/end` fires from a detached `.then` and awaits no listener). Both payloads carry the request's optional `agentType` label (Claude Code's `subagent_type`, verbatim — the seam never interprets it); `subagent/end` additionally carries `lastAssistantMessage` (a deep clone of the child's final `output`) on the settle path, absent when the run rejected at the infrastructure level. The clone keeps the surface observe-only: the end emit fires from a detached `.then` before the caller's `await run.result` resumes, so a shared reference would let a mutating listener corrupt the caller's result. A `subagent/start` listener can still reach the live child via `ctx.agents.get(info.id)`; a `subagent/end` listener can only observe (the run has settled). Any run-affecting decision (continuation, injection that changes the run) is out of scope for this observe-only surface.
|
||||
The service emits `subagent/start` (payload `SubagentRunInfo`) and `subagent/end` (payload `SubagentRunEndInfo`) around the run — both **observe-only** (plain `emit`s; `subagent/end` fires from a detached `.then` and awaits no listener). `subagent/end` carries `lastAssistantMessage` (a deep clone of the child's final `output`) on the settle path, absent when the run rejected at the infrastructure level. The clone keeps the surface observe-only: the end emit fires from a detached `.then` before the caller's `await run.result` resumes, so a shared reference would let a mutating listener corrupt the caller's result. A `subagent/start` listener can still reach the live child via `ctx.agents.get(info.id)`; a `subagent/end` listener can only observe (the run has settled). Any run-affecting decision (continuation, injection that changes the run) is out of scope for this observe-only surface.
|
||||
|
||||
## Scope (first cut)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user