- subagent-sdk: the default registry name becomes `dsh-sdk` (the bare
`sdk` read ambiguously in configs); READMEs, config catalog, fixture,
and suites follow. The Loader fixture now omits providerName to exercise
the shipped default end to end.
- loader-composition.e2e: two full harness runtimes boot in sequence, so
the default 30s loader-smoke window times out under host load; raise the
subprocess deadline to 120s with matching vitest headroom (the
real-model.e2e precedent).
The aborted-mid-stream case raced the abort against the child's chunk
delivery across two pipes and lost under full-suite load. Replace it with a
same-pipe ordering probe: the fake streams one text-delta chunk and then
answers the prompt with a malformed (non-accepted) result, so frame order
guarantees the chunk precedes the failure — the accumulated partial text
must survive into the error result. Same code path (collectOutput without a
complete assistant/message), no timing window.
The duplication gate flagged three ACP/SDK clones; the shared halves move
into dsh-subagent-subprocess as provider.ts: NO_START_CAPABILITIES (frozen
all-false advertisement), assertPositiveFinite (prefix-parameterized timing
validation), settleRunResult (never-reject result settlement with contained
onError sink and listener hygiene), and subprocessRunHandle (idempotent
dispose publication). Both backends now compose these; the previously
unreachable cancelled-rejection branch is directly unit-tested at the
library level instead of v8-ignored in each backend. knip learns the
subagent-sdk workspace (e2e entry outside vitest unit includes).
- examples/jsonrpc-agent gains its first snapshot suite (sdk.snapshot.ts):
the real dsh-jsonrpc-agent runtime driven through the real dsh-sdk-client,
keyless llm-replay behind a new cordis.snapshot.yml overlay; three recorded
scenarios (text turn, bash tool, spawn subagent) pin the notification
stream, the SDK turn result, and the persisted parent+child session logs.
- Bilingual READMEs for dsh-sdk-protocol / dsh-sdk-client / dsh-subagent-sdk;
sdk/ and subagent/ group tables extended; dsh-jsonrpc README points at the
extracted protocol package; Agent Note (en+zh) owns the decision.
- The proposed make-jsonrpc-directional note is updated for the transport's
new home and its second (client) consumer.
- Model Experience sentence allowlist entries for the two client-side
packages; module graph + config catalog regenerated; i18n pairings
recorded. doc-sync passes 24/24.
A test-only cordis.yml under examples/jsonrpc-agent boots the headless app
through the Loader; a scripted model delegates once to the SDK backend, whose
child is a COMPLETE second harness runtime (own cordis.yml, jsonrpc serving
surface, scripted cwd-echo model, own JSONL persistence). Asserts the parent
tool result AND the child's own persisted transcript both carry the parent
session's workspace cwd; child launch resolves through the shared
example-launch resolver so src/lib modes both hold.
- @deepseek-ai/dsh-sdk-protocol: extract the line transport from dsh-jsonrpc
and name the request/result/notification wire types both ends share; error
responses preserve wire code/data via JsonRpcResponseError.
- @deepseek-ai/dsh-sdk-client: TypeScript twin of the Python SDK — spawns the
dsh-jsonrpc-agent runtime as a subprocess, drives stdio JSON-RPC turns
(DeepSeekHarness high-level API + HarnessClient protocol client), scopes
notifications to session trees client-side, and reaps the child through the
shared subprocess dispose ladder.
- @deepseek-ai/dsh-subagent-sdk: out-of-process subagent backend driving a
child harness runtime through the TS SDK; shares cwd resolution with
subagent-acp via new dsh-subagent-subprocess cwd helpers.
- Keyless unit suites drive real subprocesses (scripted fake runtime peer);
100% per-file coverage on all touched packages.