DeepSeek Harness Python SDK quickstart

August 28, 2026 · View on GitHub

The rc.2 Python SDK is a programmatic alternative to the Web UI. It starts a bundled Harness runtime, runs a checked-in Agent composition, and returns a structured result to Python.

Restart recovery: session/prompt is not a resume operation

The Python SDK 0.1.1rc1 has an important restart boundary. A session/prompt call with an ID that was persisted before a Harness restart can fail with id collision: the SDK server calls agents.create() again, while the persistence layer expects an existing log to be opened through a resume path. In-process continuation works; cross-restart continuation does not. This is tracked in upstream discussion #4954.

Treat a restart as a state-recovery decision, not as a normal retry:

  1. Keep the original session ID and the exact dsh_home so the failure is reproducible.
  2. Capture the structured turn/end error and the persisted log before changing files.
  3. Do not overwrite the log and retry the same session/prompt; that only repeats creation against an existing ID.
  4. If the task can tolerate losing harness-internal state, use a copied profile and replay the client-owned conversation history as content blocks with a new session ID.
  5. Verify that the recovered turn has the expected visible context, and record that tool results, summaries, and other runtime state were not restored.

The replay workaround is intentionally lossy. A safe client should expose resume unavailable as a distinct state, preserve the original artifact, and request an explicit SDK resume/open method rather than silently clearing a user's session. Acceptance requires: same-ID in-process continuation succeeds; same-ID after restart produces a classified error; the original log remains intact; and the fallback path creates a new ID only after the user or operator accepts the loss of internal state.

Important

This page is pinned to the rc.2 source snapshot. The current 0.1.2-alpha.1 source tree no longer includes examples/jsonrpc-agent; do not expect the commands below to work unchanged after cloning current master.

Prerequisites

  • Python 3.10 or newer;
  • Git;
  • Linux x64/arm64 or macOS 14+ on Apple silicon;
  • a DeepSeek-compatible endpoint and credential;
  • a disposable workspace the Agent may modify.

The published SDK bundles its runtime, so the installed package does not require system Node.js.

Install in a virtual environment

git clone https://github.com/deepseek-ai/deepseek-harness.git
cd deepseek-harness
python -m venv .venv
. .venv/bin/activate
python -m pip install deepseek-harness-sdk

Configure the model route

export DEEPSEEK_API_KEY=sk-your-key-here
# export DEEPSEEK_BASE_URL=http://127.0.0.1:8000/v1
# export DSH_MODEL=deepseek-v4-flash

Keep real credentials out of shell history, repositories, screenshots, and issue reports. Use an isolated key with a spending limit.

Run the checked-in example

python examples/jsonrpc-agent/minimal.py \
  --workspace /absolute/path/to/workspace \
  --session-root /absolute/path/to/sessions \
  --session-id example-001 \
  "Inspect the repository and explain the failing tests. Do not modify files."

The script prints the final assistant response. The session root receives a JSONL log containing assembled requests and tool activity.

Call it from Python

from pathlib import Path
from deepseek_harness import DeepSeekHarness

config = Path("examples/jsonrpc-agent/minimal.cordis.yml").resolve()
workspace = Path("/absolute/path/to/workspace").resolve()
sessions = Path("/absolute/path/to/sessions").resolve()

with DeepSeekHarness(
    provider="deepseek-official",
    model="deepseek-v4-flash",
    max_tokens=49_152,
    cwd=str(workspace),
    session_root=str(sessions),
    cordis=str(config),
) as harness:
    result = harness.run(
        "Inspect the repository and explain the failing tests. Do not modify files.",
        session_id="example-001",
    )

print(result.final_response)

The context manager starts the runtime lazily and reuses it until exit. Reusing the same session_id continues the durable conversation and its persistent Bash process; use a fresh ID for independent work.

Understand the security boundary

The official minimal composition currently uses danger-full-access. Its persistent Bash and editor can modify any path the runtime process can access. A polite “do not modify files” prompt is useful intent, but it is not a security boundary.

For exploratory runs:

  1. use a disposable checkout or container;
  2. mount only required data;
  3. use a fresh session ID;
  4. inspect the JSONL session log;
  5. delete the test workspace and rotate exposed credentials if needed.

The persistent PTY requires a POSIX terminal substrate; this example does not support Windows Agents.

Success evidence

  • the process exits normally;
  • result.final_response contains the final text;
  • the chosen session directory contains a JSONL log;
  • the response refers to files inside the intended workspace;
  • no unapproved mutation occurred outside the disposable environment.

Official sources