description: "The SDK wire protocol for client and server implementers: the newline-delimited JSON-RPC transport and the named request, result, and notification types spoken between a Harness runtime and its SDK clients."
English | 中文
dsh-sdk-protocol lets a DeepSeek Harness runtime and its SDK clients exchange JSON-RPC 2.0 messages over newline-delimited byte streams: one transport class plus the named request, result, and notification types both wire ends speak. The serving side is the dsh-sdk-jsonrpc-server plugin; the clients are the TypeScript dsh-sdk-client and the Python SDK, which mirrors these shapes without importing them. Use this package when you implement or debug a wire end: framing rules, method names, payload types, and error semantics all live here. It is a pure library — no plugin, no configuration, no registrations.
Use this package when you build or debug an SDK wire end — the serving plugin, a client library, or custom tooling that speaks the SDK protocol. It gives you one transport for JSON-RPC 2.0 over caller-owned byte streams and the typed shapes for every SDK method and notification.
Wire one JSON-RPC 2.0 message per \n-terminated line over byte streams you own. A frame with both id and method is a request, id alone is a response, and method alone is a notification; malformed lines are ignored. Requests with no registered handler answer -32601, handler failures answer -32603, and error responses reject the pending request with JsonRpcResponseError, which preserves the wire code and optional data. start() attaches stream listeners and close() detaches them and rejects pending requests without destroying the streams.
Both wire ends share one method set: three client-to-server requests and four server-to-client notifications.
| Direction | Method | Payload types |
|---|---|---|
| client→server | initialize |
InitializeParams → InitializeResult |
| client→server | session/prompt |
SessionPromptParams → SessionPromptResult (durable enqueue receipt) |
| client→server | shutdown |
no params → {} |
| server→client | session.event |
SessionEventNotification (every session in the runtime, unfiltered) |
| server→client | session.status |
SessionStatusNotification (whole-agent running/idle transition) |
| server→client | subagent.started |
SubagentStartedNotification |
| server→client | subagent.finished |
SubagentFinishedNotification (in-process runs only) |
HarnessSdkRequestMap and HarnessSdkNotificationMap index these shapes by method name; the package root exports them together with the transport.
SessionPromptResult.messageId identifies the queued user message; it does not identify a later assistant message, turn ending, or prompt result. SdkPromptContentBlock accepts ordinary durable content plus SdkEncodedImageBlock { type: "image", data, mimeType }; the server converts encoded images to durable references before enqueue. InitializeParams.reasoningEffort is an optional non-empty adapter-owned identifier for the selected provider/model route; omission preserves that model's default. InitializeParams.maxTokens is an optional positive safe integer that caps each conversation-model output for SDK-created agents and their in-process descendants; omission lets the selected adapter's exact-model default apply. The server resolves the exact route during initialization and rejects session/prompt until that handshake succeeds, so a missing adapter, unavailable model, or unsupported effort cannot fall back to constructor defaults. SubagentFinishedNotification.lastAssistantMessage carries the child's last non-empty assistant message, or its accumulated assistant text when no such message exists; the field is absent when the child produced neither. serverInfo.name stays the wire-stable deepseek-harness-sdk-runtime. Notification payloads depend on SessionEvent (dsh-session), ContentBlock (dsh-llm), and SubagentStopReason (dsh-subagent), so the session vocabulary is part of the wire contract.
Read these pages when the wire contract is not enough. They move from the serving plugin to the clients and the runnable application.
dsh --profile sdk application that boots the server.None, as this is a client-facing wire library; the runtime plugins behind the serving entry own all model-facing behavior.
None; this package neither assembles nor sends a provider request.
These limits define what the protocol does not cover or promise. They are current package constraints, not a comparison with other wire formats or a task backlog.
serverInfo.version (0.0.1, unvalidated by clients); pre-release stance, no compatibility promise.