# Conflicts: # .agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.i18n.yaml # .agents/notes/implemented/architecture/2026-06-11-content-block-vocabulary.zh.md # .agents/notes/implemented/architecture/2026-06-18-shared-persistence-write-coordinator.i18n.yaml # .agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.i18n.yaml # .agents/notes/implemented/architecture/2026-07-10-single-file-executable-sdk-runtime-distribution.zh.md # .agents/notes/implemented/bug-fix/2026-07-29-pnpm-setup-runner-isolation.i18n.yaml # .agents/notes/implemented/bug-fix/2026-07-29-pnpm-setup-runner-isolation.zh.md # .agents/notes/implemented/bug-fix/2026-08-18-request-image-payload-bound.i18n.yaml # .agents/notes/implemented/bug-fix/2026-08-18-request-image-payload-bound.zh.md # .agents/notes/implemented/feature/2026-07-06-sandbox.i18n.yaml # .agents/notes/implemented/feature/2026-07-06-sandbox.zh.md # .agents/notes/implemented/feature/2026-07-16-persistent-pty-sessions.i18n.yaml # .agents/notes/implemented/feature/2026-07-21-cross-session-references.i18n.yaml # .agents/notes/implemented/feature/2026-07-21-cross-session-references.zh.md # .agents/notes/implemented/feature/2026-07-22-web-multimodal-image-input-and-durable-attachments.i18n.yaml # .agents/notes/implemented/feature/2026-07-22-web-multimodal-image-input-and-durable-attachments.zh.md # .agents/notes/implemented/feature/2026-07-27-web-subagent-conversations.i18n.yaml # .agents/notes/implemented/feature/2026-07-31-permission-default-for-new-sessions.i18n.yaml # .agents/notes/implemented/feature/2026-08-03-web-search-source-scroll.i18n.yaml # .agents/notes/implemented/feature/2026-08-03-web-search-source-scroll.zh.md # .agents/notes/implemented/feature/2026-08-04-claude-code-and-codex-subagent-backends.i18n.yaml # .agents/notes/implemented/feature/2026-08-04-claude-code-and-codex-subagent-backends.zh.md # .agents/notes/implemented/feature/2026-08-05-agent-teams.i18n.yaml # .agents/notes/implemented/feature/2026-08-05-agent-teams.zh.md # .agents/notes/implemented/feature/2026-08-11-workspace-sidebar-order-and-folding.i18n.yaml # .agents/notes/implemented/feature/2026-08-15-product-subagent-noninteractive-permissions.i18n.yaml # .agents/notes/implemented/process/2026-07-21-serial-cross-platform-ci-reference.i18n.yaml # .agents/notes/implemented/process/2026-07-21-serial-cross-platform-ci-reference.zh.md # .agents/notes/implemented/process/2026-07-22-evidence-based-larger-hosted-runners.i18n.yaml # .agents/notes/implemented/process/2026-07-22-evidence-based-larger-hosted-runners.zh.md # .agents/notes/implemented/process/2026-07-23-portable-required-pull-request-ci.i18n.yaml # .agents/notes/implemented/process/2026-07-23-portable-required-pull-request-ci.zh.md # .agents/notes/implemented/testing/2026-07-24-web-gui-browser-e2e-lane.i18n.yaml # .agents/notes/implemented/testing/2026-07-24-web-gui-browser-e2e-lane.zh.md # .agents/notes/implemented/testing/2026-07-30-web-browser-snapshot-ci-gate.i18n.yaml # .agents/notes/implemented/testing/2026-07-30-web-browser-snapshot-ci-gate.zh.md # .agents/notes/proposed/architecture/2026-07-27-session-projection-and-command-log.i18n.yaml # README.i18n.yaml # README.zh.md # docs/architecture.i18n.yaml # docs/architecture.zh.md # docs/development.i18n.yaml # docs/development.zh.md # docs/persistence-catalog.i18n.yaml # docs/persistence-catalog.zh.md # docs/subsystems/README.i18n.yaml # docs/subsystems/README.zh.md # docs/subsystems/agent-team.i18n.yaml # docs/subsystems/agent-team.zh.md # docs/subsystems/client-modules.i18n.yaml # docs/subsystems/client-modules.zh.md # docs/subsystems/commands.i18n.yaml # docs/subsystems/commands.zh.md # docs/subsystems/persistence.i18n.yaml # docs/subsystems/persistence.zh.md # docs/subsystems/session-reference.i18n.yaml # docs/tool-catalog.i18n.yaml # docs/tool-catalog.zh.md # docs/user/guide/providers.i18n.yaml # docs/user/guide/providers.zh.md # packages/README.i18n.yaml # packages/README.zh.md # packages/bundle/web-app/README.i18n.yaml # packages/bundle/web-app/README.zh.md # packages/client/README.i18n.yaml # packages/client/README.zh.md # packages/client/connection/README.i18n.yaml # packages/client/connection/README.zh.md # packages/client/ui-conversation/README.i18n.yaml # packages/client/ui-conversation/README.zh.md # packages/client/ui-primitives/README.i18n.yaml # packages/client/ui-primitives/README.zh.md # packages/client/ui-sidebar/README.i18n.yaml # packages/client/ui-sidebar/README.zh.md # packages/client/ui-workspace/README.i18n.yaml # packages/client/ui-workspace/README.zh.md # packages/context/README.i18n.yaml # packages/context/README.zh.md # packages/core/agent-loop/README.i18n.yaml # packages/credentials/README.i18n.yaml # packages/credentials/README.zh.md # packages/experimental/agent-team/README.i18n.yaml # packages/experimental/agent-team/README.zh.md # packages/experimental/tool-agent-team/README.i18n.yaml # packages/experimental/tool-agent-team/README.zh.md # packages/host/frontend-static/README.i18n.yaml # packages/host/frontend-static/README.zh.md # packages/host/webserver/README.i18n.yaml # packages/host/webserver/README.zh.md # packages/interaction/commands/README.i18n.yaml # packages/interaction/commands/README.zh.md # packages/plan/plan-mode/README.i18n.yaml # packages/plan/plan-mode/README.zh.md # packages/sandbox/sandbox-local/README.i18n.yaml # packages/sandbox/sandbox-local/README.zh.md # packages/session/README.i18n.yaml # packages/session/README.zh.md # packages/session/session-persistence-sqlite/README.i18n.yaml # packages/session/session-persistence-sqlite/README.zh.md # packages/session/session-projection-cache/README.i18n.yaml # packages/session/session-projection-cache/README.zh.md # packages/shell/tool-pwsh/README.i18n.yaml # packages/shell/tool-pwsh/README.zh.md # packages/subagent/subagent-codex/README.i18n.yaml # packages/subagent/subagent-codex/README.zh.md # packages/subagent/subagent/README.i18n.yaml # packages/subagent/subagent/README.zh.md # packages/web/tool-web/README.i18n.yaml # packages/web/tool-web/README.zh.md # scripts/snapshots/translation-prompt-v4/request-response.expected.json
@deepseek-ai/dsh-sdk-client
English | 中文
The TypeScript client SDK for driving a DeepSeek Harness runtime as a subprocess over stdio JSON-RPC — the design twin of the Python SDK (deepseek-harness), sharing the same runtime peer, protocol, and layering: DeepSeekHarness is the high-level owned-run API, HarnessClient the lower-level protocol client. The package root enumerates the consumer interface: the two client layers, caller-facing types, and JsonRpcResponseError; source modules, normalization helpers, and subscription-delivery machinery are not consumer imports. A pure library: it registers nothing on a Cordis context; the runtime process it spawns is a complete harness whose composition its own cordis.yml decides.
Unlike the Python SDK, the launch spec is fully explicit (command/args): this package is for repo-adjacent TypeScript consumers — including the dsh-subagent-dsh-sdk backend and automation — that know which runtime they are launching. Bundled-runtime resolution (finding a packaged executable) remains the Python distribution's concern.
DeepSeekHarness
import { DeepSeekHarness } from '@deepseek-ai/dsh-sdk-client'
await using harness = new DeepSeekHarness({
launch: { command: 'node', args: ['lib/bin.js', 'cordis.yml'] },
provider: 'deepseek-official',
model: 'deepseek-v4-flash',
maxTokens: 49_152,
})
const result = await harness.run('say hi')
console.log(result.finalResponse)
The subprocess starts lazily on first use and stays owned by the instance across run() calls; close() (or await using) is required so the child is always reaped. start() memoizes the initialize handshake (the workspace cwd — resolved absolute before it crosses the wire — plus the provider/model route and optional positive maxTokens output cap); a failed handshake reaps the runtime and swaps in a fresh client, so a later call retries with a new subprocess (until close(), which is terminal). The cap applies to each root-agent request and is inherited by in-process descendants; compaction plugins own their separate summary limits. session(id?) opens a named or fresh session handle.
run(input, { sessionId?, onNotification? }) owns one activity interval: it queues the prompt, waits until its MessageId appears in a durable agent/inbox/spliced receipt, then collects through the next whole-agent idle. It returns RunResult { sessionId, finalResponse, events, notifications }. finalResponse is the last committed root-session assistant text in that interval, not a response causally assigned to the prompt; steering, injected context, and other queued work may contribute before idle. events contains root-session events, while notifications also contains descendants discovered from subagent.started, all in wire order. The result carries no prompt-level status or turn reason. Transport loss, timeout, and protocol violations reject; model outcomes remain observable in the event stream without being attributed to one input.
HarnessClient
The protocol client under the owned-run API: explicit start()/initialize()/prompt()/request()/close(), plus notification subscriptions. prompt() returns the queued message id as soon as the runtime accepts it; it never waits for agent activity. subscribe(filter?) returns a NotificationSubscription (awaitable next(), non-blocking tryNext(), async iteration); subscribeSessionTree(id) scopes to one session and the descendants discovered from subagent.started lineage edges — the runtime notifies for every session in its context, and scoping is client-side, exactly like the Python SDK. Error surfaces are typed and exported from this package: JsonRpcResponseError (wire error response, code/data preserved), RequestTimeoutError (a configured bound elapsed), SdkProtocolError (a response outside the documented protocol), TransportClosedError (the runtime is gone — message carries the exit code and a bounded stderr tail).
close() requests protocol shutdown (bounded by shutdownTimeoutMs, default 1000 ms), then walks a stdin-EOF → SIGTERM → SIGKILL ladder (disposeEofGraceMs default 6000, disposeGraceMs default 3000) until the process has actually exited. The ladder is private to this client: it runs outside any harness context, so it cannot ride the dsh-subprocess service — the seam's documented exception for SDK-managed transports. It is idempotent, and a closed client refuses reuse.
HarnessClientOptions.env replaces the child environment entirely when given (undefined inherits the parent's); callers own credential policy — scrubbedParentEnv from dsh-subprocess is the shared scrub base for isolation-minded launches.
Model Experience
None, as this is a client-process library; the model runs in the spawned runtime, whose experience is owned by the plugins its cordis.yml composes.
KV Cache effect
None; this package neither assembles nor sends a provider request.
Known Limitations and Deferred Work
- No bundled-runtime resolution — callers name the runtime executable explicitly; packaged-executable discovery stays Python-side until a TypeScript distribution consumer exists.
- No mid-turn cancel — the wire has no prompt-cancel method; abandoning a turn means closing the runtime (see the protocol's Known Limitations).
- No per-prompt result or cancel — low-level
prompt()returns only an enqueue receipt; high-levelrun()owns receipt-to-idle collection, and abandoning it means closing the runtime. - Client→server notifications and server→client requests are unimplemented on both wire ends; the transport carries them for future approval flows.