Files
deepseek-harness/packages/subagent/subagent-fork
Tianyi Cui 3529b3c166 fix(scope): close final ownership races
Drain idle injection flushes before agent teardown, snapshot approval and subagent provider inputs, and gate subagent lifecycle events on real child readiness. Align the RFCs and generated contracts with the hardened behavior.
2026-07-12 00:31:46 +08:00
..

@deepseek-ai/dsh-subagent-fork

The in-process fork subagent backend: a SubagentProvider that runs each child as a child Agent seeded with a prefix of the parent's session log — so the child inherits the parent's conversation context instead of starting fresh. Shares the run driver (startInProcessRun) with dsh-subagent-spawn; the only difference is the seed. The shared run.started boundary resolves only after the seeded child is published, so subagent/start observers see a live registry entry.

The seed boundary (the crux)

At the moment a subagent tool's execute runs, the parent's CURRENT turn is open and unbalanced: the log holds the assistant/message carrying this spawn's tool-call and the dangling tool/call with no tool/result yet. Seeding that raw prefix would give the child an open turn that the session constructor and the dev-mode invariants replay reject.

So the fork seeds only the balanced completed-turn prefix — the parent's log up to and including its last turn/end, excluding the in-flight turn entirely (completedTurnPrefix). Because the live log keeps seq === index, the slice is contiguous-from-0 and a valid seed. A parent on its very first (not-yet-complete) turn forks an empty seed — i.e. effectively a fresh child.

The seam this rides on: CreateAgentOptions.seed (added on dsh-agent, threaded through AgentLoop.createAgentctx.sessions.prepare({ seed })), the same primitive resume uses.

Capabilities

{ outputSchema: true, depthLimit: true, toolFilter: true, persona: true } — identical to spawn because the shared driver owns depth, model, persona, tool-filter, and structured-output behavior.

Config

Key Meaning
providerName Registry name on ctx.subagents (default fork).

See dsh-subagent-spawn for the run lifecycle, model inheritance, and depth tracking — all shared.