1
/**2
* The in-process SPAWN subagent backend: registers a {@link SubagentProvider} on3
* `ctx.subagents` that runs each child as a fresh child {@link Agent} on the same cordis4
* context (its own session, own system prompt, zero parent context). The cheapest transport,5
* reusing the agent factory's quiescent teardown.6
* @module @deepseek-ai/dsh-subagent-spawn-in-process7
*/9
import type { Context } from '@deepseek-ai/cordis'10
import z from '@deepseek-ai/schemastery'11
import type {12
ContinuableCreateSpec,13
ResolvedSubagentStartRequest,14
SubagentCapabilities,15
SubagentProvider,16
} from '@deepseek-ai/dsh-subagent'17
import { startInProcessRun } from '@deepseek-ai/dsh-subagent-in-process-driver'19
export const name = 'subagent-spawn-in-process'20
// `tools` is deliberately not injected: the child factory already provides it during setup,21
// and adding it here would unnecessarily change this provider's apply timing.22
export const inject = ['subagents']24
/** Config: the registry name to register the provider under. */25
export interface Config {26
/** Provider name on `ctx.subagents` (default `spawn`). */27
providerName: string28
}30
export const Config: z<Config> = z.object({31
providerName: z.string().default('spawn'),32
})34
/**35
* The spawn provider. Supports every start-time capability: `depthLimit` (it36
* constructs the child, so it can enforce a recursion cap), `outputSchema`37
* (the scoped structured runtime), `agentOptions` (merged over the parent38
* route), and `toolFilter`/`persona` (scoped `restrict()` and a scoped39
* shadowing persona section, applied in the child's creation window).40
*/41
class SpawnInProcessProvider implements SubagentProvider {42
readonly capabilities: SubagentCapabilities = {43
agentOptions: true,44
outputSchema: true,45
depthLimit: true,46
toolFilter: true,47
persona: true,48
}49
// Context contract: a spawned child starts fresh — it never sees the parent conversation.50
readonly inheritsParentContext = false52
constructor(readonly name: string) {}54
start(request: ResolvedSubagentStartRequest) {55
// Fresh child: no seed. The shared driver mints ids, stamps cwd/lineage/56
// depth, drives the one-shot (including the structured capture when the57
// request carries an outputSchema), and maps the result.58
return startInProcessRun(request, {})59
}61
prepareContinuable(): Promise<ContinuableCreateSpec> {62
// A spawned child starts fresh, so it contributes no seed; the continuation63
// manager owns every later operation on it.64
return Promise.resolve({})65
}66
}68
export function apply(ctx: Context, config: Config): void {69
ctx.subagents.registerProvider(new SpawnInProcessProvider(config.providerName))70
}