Add subagent capability seam: interface, mock backend, model-facing tool

Introduce the `packages/subagent/` group and the abstract subagent seam — an
agent delegating to a child agent — as a named-provider registry (`ctx.subagents`),
unlike the single-implementation bash seam, so multiple transports (in-process,
ACP, future A2A) coexist. This first PR lands the interface, a scripted test
backend, and the model-facing tool, validated through the real cordis load path.

- dsh-subagent: SubagentService registry + SubagentProvider/SubagentRun
  vocabulary + subagent/start|end events. Start-time capabilities (outputSchema,
  depthLimit, toolFilter) are checked pre-start and rejected loud; runtime
  capabilities (sendMessage, resume) are optional methods on SubagentRun.
- dsh-subagent-mock (support): scripted provider for keyless, deterministic
  tests through the real Loader/export path.
- dsh-tool-subagent: the model-facing `subagent` tool, config-bound to one
  provider; synchronous collect with try/finally dispose, signal->cancel
  bridging, and non-completed-stop-reason -> isError mapping.
- Proposed RFC documenting the seam, the fork-vs-spawn-as-separate-backends
  decision, own-session isolation, synchronous-collect scope, and the deferral
  of background/poll/spill to a future unification with bash.
- Wire the new group into tsconfigs, build refs, package hierarchy docs, the
  module graph, and the cordis catalog.

RFC: docs/rfc/proposed/feature/2026-06-21-subagent-capability-seam.md
This commit is contained in:
Tianyi Cui
2026-06-21 22:31:56 +08:00
parent 6b4dc48fbd
commit 1a81f2cccd
26 changed files with 1605 additions and 3 deletions

68
pnpm-lock.yaml generated
View File

@@ -318,6 +318,52 @@ importers:
specifier: ^4.0.0-rc.6
version: 4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4)
packages/subagent/subagent:
devDependencies:
'@deepseek-ai/dsh-agent':
specifier: workspace:^
version: link:../../core/agent
'@deepseek-ai/dsh-llm':
specifier: workspace:^
version: link:../../llm/llm
'@deepseek-ai/dsh-tools':
specifier: workspace:^
version: link:../../core/tools
cordis:
specifier: ^4.0.0-rc.6
version: 4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4)
packages/subagent/tool-subagent:
dependencies:
schemastery:
specifier: ^3.18.0
version: 3.18.0
devDependencies:
'@cordisjs/plugin-loader':
specifier: ^1.0.0-rc.4
version: 1.0.0-rc.4(cordis@4.0.0-rc.6)
'@deepseek-ai/dsh-agent':
specifier: workspace:^
version: link:../../core/agent
'@deepseek-ai/dsh-llm':
specifier: workspace:^
version: link:../../llm/llm
'@deepseek-ai/dsh-subagent':
specifier: workspace:^
version: link:../subagent
'@deepseek-ai/dsh-subagent-mock':
specifier: workspace:^
version: link:../../support/subagent-mock
'@deepseek-ai/dsh-system-prompt':
specifier: workspace:^
version: link:../../core/system-prompt
'@deepseek-ai/dsh-tools':
specifier: workspace:^
version: link:../../core/tools
cordis:
specifier: ^4.0.0-rc.6
version: 4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4)
packages/support/invariants:
devDependencies:
'@deepseek-ai/dsh-agent':
@@ -345,6 +391,28 @@ importers:
specifier: ^4.0.0-rc.6
version: 4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4)
packages/support/subagent-mock:
dependencies:
schemastery:
specifier: ^3.18.0
version: 3.18.0
devDependencies:
'@cordisjs/plugin-loader':
specifier: ^1.0.0-rc.4
version: 1.0.0-rc.4(cordis@4.0.0-rc.6)
'@deepseek-ai/dsh-agent':
specifier: workspace:^
version: link:../../core/agent
'@deepseek-ai/dsh-llm':
specifier: workspace:^
version: link:../../llm/llm
'@deepseek-ai/dsh-subagent':
specifier: workspace:^
version: link:../../subagent/subagent
cordis:
specifier: ^4.0.0-rc.6
version: 4.0.0-rc.6(@cordisjs/plugin-include@1.0.4)(@cordisjs/plugin-loader@1.0.0-rc.4)
packages/support/ui-stdio:
dependencies:
schemastery: