Files
deepseek-harness/python/sdk-runtime
kingwl 1f38b211be Merge origin/master (generic task runtime #219, single-exe closure, package renames)
Semantic resolutions beyond line merges:
- The bash seam keeps resolveMode + the bash/resolve-mode waterfall on
  master's task-free BashExecutor (run/start/resolve only; BashProcess
  handles); tool-bash consults it at its stamping site and escalation
  baseline on master's render/background split, with a waterfall test on
  the recording executor.
- dsh-mode's BASH_FAMILY narrows to ['bash']: bash_output/bash_kill are
  replaced by the kind-generic task_output/task_kill, which span every
  task kind and only observe or stop work, so the access cap withholds
  only the starter it can reason about.
- The plan-mode snapshot suite adopts master's pin grammar (tool-schema
  sidecars; the expectedHeaderSnapshots extension is gone — the exit
  transition deltas, and entering-before-turn-1 needs no second
  snapshot); modes-advertise joins the plan header class (no-model, so
  membership is vacuous). Fixtures re-recorded on the acp-demo bin;
  the replay overlay gains the passthrough sandbox runner.
- examples/plan-acp-agent rewires to @deepseek-ai/dsh-acp-demo and drops
  its tool-bash entry (the spine bundle now composes it); dsh-stdio (the
  renamed stdio-chat home) keeps its /mode command and gains the dsh-mode
  peer edge; the acp bridge keeps the modes surface beside master's
  permission presets.
- mode README gains the Model Experience / Known Limitations sections the
  new README gates require; AGENTS.md ceiling 1370 → 1440 for the kept
  mode/ layout line and Agent efficiency section.
2026-07-15 23:17:18 +08:00
..

DeepSeek Harness Runtime Wheel

English | 中文

Runtime carrier package for the Python SDK (dist deepseek-harness-runtime-bin, module deepseek_harness_runtime): it locates the bundled runtime binaries the deepseek-harness client spawns, and ships the default configuration behind zero-config runs.

Runtime carriers

Two carriers coexist under src/deepseek_harness_runtime/runtime/, both injected by the repo's scripts/build-exe-for-python-sdk.ts build and both gitignored:

  • exe (production) — single-file executables dsh-jsonrpc-agent-pkg-<platform>-<arch> (platform: linux/macos; arch: x64/arm64). No Node installation needed on the target machine. This is the only carrier that ships in wheel distributions; this package does not publish sdists.
  • node (dev-only) — the full deploy closure under runtime/node/ (package.json + node_modules/), executed as node runtime/node/node_modules/@deepseek-ai/dsh-jsonrpc-demo/lib/bin.js on a system Node >= 22.19. It is the current checkout's source build, meant for repo-local development and verification only; it is never selected automatically and is excluded from distributions.

Both carriers hold the same content, defined once: the package.json at this package's root is the deploy root of the single-exe pipeline — a pure dependency manifest (no code of its own) whose dependency closure IS both the plugin set compiled into the exe and the tree materialized into runtime/node/. Adding a plugin to the distribution means adding one dependency line there and rebuilding.

A missing exe raises FileNotFoundError naming both acquisition routes: build via scripts/build-exe-for-python-sdk.ts in a deepseek-harness checkout, or install the matching platform runtime wheel produced by the build-exe-for-python-sdk CI workflow. A missing dev-only node carrier names its sole route, the build script. The workflow retains wheels rather than standalone executable archives. Acquisition strategy is deliberately separate from the lookup interface, so an on-demand download can replace it later without touching callers.

Each wheel contains exactly one executable. The fixed tags are py3-none-manylinux_2_28_x86_64, py3-none-manylinux_2_28_aarch64, and py3-none-macosx_11_0_arm64; the build hook rejects py3-none-any, absent or multiple executables, and unsupported platform tags. The repository root package.json supplies the shared version for this package and the SDK, and a python-vX.Y.Z release tag must match it.

Resolution API

  • resolve_bundled_launch_args(mode=None) -> tuple[str, ...] — the argv tuple that launches the bundled runtime: (exe_path,) in exe mode, (node_path, bin_js_path) in node mode. Mode selection: explicit argument > DSH_RUNTIME_MODE env var (exe | node) > automatic. Automatic resolution finds the production exe ONLY — the dev-only node carrier must be opted into explicitly so a production deployment can never silently ride on a source build.
  • bundled_runtime_path() -> Path — the platform exe path (exe carrier only; the node carrier has no single-path equivalent and launches via the argv tuple above).
  • bundled_default_config_path() -> Path — the checked-in default config (see below).
  • bundled_package_dir() -> Path — the installed package data root.

Zero-config design

The runtime binary always demands an explicit config ($DSH_CORDIS_CONFIG, or a config path as an argv positional argument) and exits loudly without one — that hard semantic is part of the runtime's design and this package does not soften it. The bin (dsh-jsonrpc-agent) boots only the plugins the config lists; the serving surface (the stdio JSON-RPC server) is itself one of its entries (@deepseek-ai/dsh-jsonrpc), and without it the booted agent has no channel to the outside. This package checks in runtime/cordis.yml with the JSON-RPC serving entry, agent core, a preloaded DeepSeek adapter, JSONL persistence, and local bash. The adapter reads DEEPSEEK_API_KEY and DEEPSEEK_BASE_URL, while persistence and bash use DSH_SESSION_ROOT and DSH_CWD with manual-run fallbacks. When the caller uses no explicit config channel, the deepseek_harness client injects that file's path via DSH_CORDIS_CONFIG (injection conditions: sdk README). Zero-config is thus an explicit, visible parameter pass in the wrapper, not a hidden fallback in the runtime.