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:
@@ -11,7 +11,7 @@ The **harness tier** below (the `@deepseek-ai/dsh-*` packages) is the vocabulary
|
||||
|
||||
## Events
|
||||
|
||||
Dispatch modes: **emit** (fire-and-forget), **waterfall** (each listener gets `next()` and may transform or veto — see [waterfall semantics](../architecture.md#cordis-waterfall-semantics-important)), **parallel** (awaited fan-out, no veto). The harness declares 22 events across 5 scopes.
|
||||
Dispatch modes: **emit** (fire-and-forget), **waterfall** (each listener gets `next()` and may transform or veto — see [waterfall semantics](../architecture.md#cordis-waterfall-semantics-important)), **parallel** (awaited fan-out, no veto). The harness declares 24 events across 6 scopes.
|
||||
|
||||
### `agent/*`
|
||||
|
||||
@@ -231,6 +231,28 @@ Awaited durability checkpoint. The agent loop awaits `ctx.parallel('session/flus
|
||||
|
||||
Source: [`packages/core/session/src/index.ts:45`](../../packages/core/session/src/index.ts)
|
||||
|
||||
### `subagent/*`
|
||||
|
||||
#### `subagent/end` — emit
|
||||
|
||||
A subagent run settled — emitted when SubagentRun.result resolves (any stop reason). Paired with Events['subagent/start'].
|
||||
|
||||
```ts cordis-catalog
|
||||
'subagent/end'(info: SubagentRunEndInfo): void
|
||||
```
|
||||
|
||||
Source: [`packages/subagent/subagent/src/index.ts:65`](../../packages/subagent/subagent/src/index.ts)
|
||||
|
||||
#### `subagent/start` — emit
|
||||
|
||||
A subagent run started — emitted after the provider is resolved and its capabilities validated, as the child run begins. Paired with Events['subagent/end'].
|
||||
|
||||
```ts cordis-catalog
|
||||
'subagent/start'(info: SubagentRunInfo): void
|
||||
```
|
||||
|
||||
Source: [`packages/subagent/subagent/src/index.ts:59`](../../packages/subagent/subagent/src/index.ts)
|
||||
|
||||
### `system-prompt/*`
|
||||
|
||||
#### `system-prompt/assemble` — waterfall
|
||||
@@ -279,7 +301,7 @@ Source: [`packages/core/tools/src/index.ts:43`](../../packages/core/tools/src/in
|
||||
|
||||
## Services
|
||||
|
||||
The 8 `ctx.<key>` services the harness provides. An abstract seam (e.g. `ctx.bash`) is implemented by a separate package; the interface is what consumers code against.
|
||||
The 9 `ctx.<key>` services the harness provides. An abstract seam (e.g. `ctx.bash`) is implemented by a separate package; the interface is what consumers code against.
|
||||
|
||||
### `ctx.agentLoop` — `AgentLoop`
|
||||
|
||||
@@ -392,6 +414,19 @@ list(): Session[]
|
||||
|
||||
Source: [`packages/core/session/src/index.ts:229`](../../packages/core/session/src/index.ts)
|
||||
|
||||
### `ctx.subagents` — `SubagentService`
|
||||
|
||||
The `subagents` service: a registry of named SubagentProviders and a capability-checked start surface.
|
||||
|
||||
```ts cordis-catalog
|
||||
registerProvider(provider: SubagentProvider): () => void
|
||||
getProvider(name: string): SubagentProvider | undefined
|
||||
list(): string[]
|
||||
start(name: string, request: SubagentStartRequest): SubagentRun
|
||||
```
|
||||
|
||||
Source: [`packages/subagent/subagent/src/index.ts:103`](../../packages/subagent/subagent/src/index.ts)
|
||||
|
||||
### `ctx.systemPrompt` — `SystemPrompt`
|
||||
|
||||
Registry service (`ctx.systemPrompt`): plugins contribute ordered text sections and tool-schema providers; the agent loop calls `assemble()` once per step.
|
||||
|
||||
Reference in New Issue
Block a user