README.md 4.5 KB

DeepSeek Harness Python SDK

English | 中文

Python subprocess SDK for driving DeepSeek Harness over newline-delimited JSON-RPC on stdio. Install deepseek-harness-sdk; it installs the exact same-version deepseek-harness-runtime-bin wheel for the current platform.

python -m pip install deepseek-harness-sdk

Start a runtime

The Python SDK has no separate application entrypoint. It launches the bundled dsh CLI with --profile sdk; the selected profile owns the JSON-RPC server, agent composition, credentials, persistence, tools, and shutdown behavior.

Every launch requires an explicit Harness home. Pass dsh_home or provide a non-empty DSH_HOME in the child environment. The SDK deliberately never discovers ~/.dsh.

from deepseek_harness import DeepSeekHarness

with DeepSeekHarness(
    dsh_home="/absolute/path/to/isolated-dsh-home",
    cwd="/absolute/path/to/workspace",
) as harness:
    result = harness.run("Say hi.", session_id="example-001")

print(result.final_response)

DeepSeekHarness starts lazily and reuses its runtime until close() or context-manager exit. cwd is the agent workspace; runtime_cwd independently selects the subprocess working directory. Both become absolute before launch. provider, model, and optional positive max_tokens are sent during JSON-RPC initialization. base_url and api_key explicitly override DEEPSEEK_BASE_URL and DEEPSEEK_API_KEY in the child environment.

Customize plugins

Persistent customization belongs to a dsh profile. Initialize the shipped SDK profile and install an external bundle with the runtime wheel's dsh command:

export DSH_HOME=/absolute/path/to/isolated-dsh-home
dsh --profile sdk --dump-default-config >/dev/null
dsh plugin --profile sdk add file:/absolute/path/to/my-plugin-bundle

The file: form installs the local bundle into the profile package tree, where its peer imports reach the bundled installation fallback. The profile manifest records installed dependencies and ordered bundle layers; its $DSH_HOME/profiles/sdk/cordis.patch.yml is the persistent user patch. dsh plugin needs pnpm only when managing external packages. Running the SDK does not require system Node.js.

For an invocation-specific change, pass one or more patch files. They become absolute and are forwarded in order after the profile and home patch layers:

with DeepSeekHarness(
    dsh_home="/absolute/path/to/isolated-dsh-home",
    profile="sdk",
    patches=("/absolute/path/to/first.patch.yml", "/absolute/path/to/last.patch.yml"),
) as harness:
    result = harness.run("Make the requested code change.")

profile may select another existing profile, but that composition must retain @deepseek-ai/dsh-sdk-app or another @deepseek-ai/dsh-sdk-jsonrpc-server row. Misconfiguration fails during CLI boot or SDK initialization; there is no complete-config fallback. dsh_bin may select another dsh executable while preserving the same profile grammar. Arbitrary argv replacement remains an internal fake-runtime test adapter, not public API.

Results and notifications

Session.run() owns an activity interval from its prompt's durable inbox receipt through the next whole-agent idle and returns RunResult(session_id, final_response, finish_reason, events, notifications). final_response is the last committed root-session assistant text in the interval. finish_reason is the kind of the last root-session turn/end, such as completed, max-tokens, or error, and is None when no turn ended. A turn/end without a string data.reason.kind violates the protocol and raises SdkProtocolError.

HarnessClient retains discovered subagent ancestry for the runtime process lifetime. During Session.run(), RunResult.notifications and on_notification receive the root session and known descendants in wire order. RunResult.events contains root-session events only, so descendant output cannot replace the root response. The low-level session_prompt() returns the queued message id immediately; callers that bypass Session.run() own the later activity boundary.

The selected home stores profiles, plugins, credentials, settings, and sessions. Use a fresh home when those resources must be isolated, and a fresh session id for independent work. Reusing both a harness and session id continues the durable conversation and session-owned resources.

See the Python tutorial, python-sdk-agent example, and runtime wheel reference.