English | 中文
Mini DeepSeek Harness is a production-oriented Python implementation of DeepSeek Harness (dsh) — the open-source agent harness developed by DeepSeek AI — written by re-implementing the upstream core contracts bottom-up for clarity, and built for production readiness (mature open-source libraries first, stdlib only where no equivalent library fits — httpx for the DeepSeek SSE transport, pyyaml for config, and an optional [web] extra: fastapi + uvicorn for the HTTP/SSE transport layer).
The upstream project builds its entire system on a philosophy where everything is a plugin, powered by Cordis, a dependency-injection and event-bus framework whose design is described in A Programming Paradigm for Spatiotemporal Composability. We deeply admire this design. This repository is our homage: instead of only reading about it, we re-implement its core contracts — the event-sourced session log, the plugin event bus, the turn/step agent loop, and the capability-seam triangle (Service Definition / Service Provider / Consumer) — preferring mature open-source libraries over hand-rolling (the required third-party packages are httpx for the DeepSeek SSE transport, filelock for credential cross-process writer locking, watchdog for the Cordis HMR file watch, and pyyaml for YAML config), so anyone with python3 can read, run, and modify them.
A re-implementation built for production, not a byte-for-byte port. It is not affiliated with DeepSeek AI. We favor clarity and faithful reproduction of the contracts that matter in real deployment — the wire contract, the event-sourced session log, reliability/security/interop semantics — over reproducing every upstream package; deviations are documented, never silently assumed.
Disclaimer: a large part of this repository — including the analysis report and the handbook — was summarized, written, and re-implemented with the help of AI assistants. It may contain misunderstandings or inaccuracies about the upstream source code and documentation. The upstream repository itself is the only authoritative reference.
Two complementary documents (both in Chinese):
- Analysis report — a deep dive into the upstream repository: five-layer architecture, the
ctxservice map, core techniques, and key processing flows, fully illustrated with Mermaid diagrams (landing page + six topic pages). Rendered on GitHub Pages via MkDocs: https://zzkeepcurious.github.io/mini-deepseek-harness-python/ - Step-by-step handbook — how the system grows from zero, one chapter at a time: concepts → minimal runnable code → invariants/tests → checkpoint exercises.
See ROADMAP.md for where this project is heading.
| Capability | Upstream counterpart |
|---|---|
Event-sourced session (envelope {type,seq,time,data}, 1-based turn/step, deep-freeze, derive_messages, interrupted repair) |
packages/core/session |
Durable storage (JSONL / SQLite, zstd concatenated-frame container with one event per line by default, root/--<projectKey>--/<encoded-id>/session.v3.jsonl[.zstd] layout, header + SESSION_FORMAT_VERSION=3 bidirectional refusal, loud encoding/layout mismatches, flush barrier, crash recovery, multi-generation read-side that migrates released v0/v1 artifacts in-place via the upstream chain) |
packages/session/session-persistence + session-format-* |
Plugin event bus (emit / waterfall / parallel / serial, scopes, dependency-driven activation, epoch reload via HMR service + watch_user_patches) |
vendor/cordis + vendor/hmr + core/scope + core/hmr |
Config schema engine (full schemastery port: 17 resolvers, meta clone, toString/toJSON/i18n/simplify, ~standard protocol face) |
vendor/schemastery/src/index.ts |
| Tool registry + execution pipeline (schema validation, pre/execute/post, timeout) | packages/core/tools |
| Agent loop (async-driven turn/step state machine, sync facade driven by a process-wide resident event loop, pre-step rejection, tool-feedback continuation) | core/agent-loop |
LLM seam (async stream(messages, tools, signal) contract, fake adapter, official DeepSeek SSE adapter over httpx async streaming, four-level reasoning_effort) |
llm/llm + llm/llm-deepseek |
Model request retry / backoff (normal/always policy, agent/request-error, llm/retry audit pair, fused-signal pre-dispatch check, event-driven multi-signal race cancellable wait, plugin teardown draining in-flight recoveries) |
llm/llm-retry + llm/llm/src/retry-policy.ts |
| Token metering (incremental fold, usage anchor, 4 chars/token heuristic) | llm/token-meter |
Context compaction (pre-step pressure + CONTEXT_WINDOW_EXCEEDED recovery, surface-replace checkpoint transaction, optional tool-result pruner stage) |
compaction/compaction-basic + compaction-tool-result-pruner |
Background jobs (job_output/job_list/job_kill, completion notices, per-owner cap; no job/* session events) |
packages/jobs (jobs-local + tool-jobs) |
Plan mode (log-only plan/mode state, plan:policy prompt-section injection, queued in-turn commit) |
packages/plan/plan-mode |
Plan review UI (/plan command, exit_plan_mode tool, user-questions channel, plan projection) |
packages/plan/plan-mode |
Command surface (/-command registry, command/run + command/done pairing) |
packages/interaction/commands |
Goals (goal/change event-sourced fold, GoalService, automatic goal-round continuation, get_goal/create_goal/update_goal tools, /goal command) |
packages/goal (goal + goal-round-driver + tool-goal + command-goal) |
| System prompt sections (ordered section registration + rendering into each request) | core/system-prompt |
Boot & composition (YAML/JSON overlays, !!js env interpolation, startup assertions) |
packages/boot |
Headless one-shot entry (--profile headless "task": stdout final text, exit code by turn/end reason) |
packages/bundle/headless + apps/cli |
Web transport layer + browser frontend (--profile web: two-envelope RPC (client-request/server-response), WebApi unary session service, Remote stream wire (open/cancel/item/end/error on a single /api/remote.mux WebSocket, $events registry with api-session/* forwarding + approval/request waterfall settled via $events/result, session.follow/session.control streams), approval bridge (tools/ask ↔ $events waterfall), FastAPI carrier mirroring gateway stream-server.ts/handler.ts status-code chain + $events/result + frontend-static contract, session-log export endpoint GET /api/session.export (zip of root + subagent descendants + referenced media, 200/400/404/501/500 status chain, private error shell), productized webui/ React frontend (repo-top standalone project, wire-contract only; session list/create, Trajectory with virtualized windowing + Overview collapsed view + full-text search, approval waterfall, queue/jobs panel; served from webui/dist via MINIHARNESS_WEBUI_DIST); web/static/ vanilla SPA kept as a teaching reference only (old SSE wire, does not work against the current backend)) |
packages/api/gateway + packages/api/session-controller + packages/api/remotes + host/frontend-static + host/webserver |
Launcher options (--patch, --dump-config / --dump-default-config, read-only composition dump) |
apps/cli/src/args.ts |
Session management CLI (miniharness sessions list/resume/delete/stats; mini teaching extension; stats renders sessionStats/tokenUsage projection + last-turn token accounting) |
web surface (upstream) |
Telemetry / usage stats (sessionStats + tokenUsage projections as real projections.values on session.follow/session.control and Remote snapshot/baseline; per-turn token accounting derive_turn_token_usage fail-closed on missing boundaries; opt-in UsageStatsService on ctx.usageStats) |
packages/session/session-stats + packages/llm/token-meter |
Session store service (ctx.sessions: create/prepare/enter/announce lifecycle, fork with 5 error codes, flush checkpoint, `session/created |
disposed |
Capability seams (sandbox backends + policy service + bash consumer executor (ctx.sandboxPolicy resolution / sandbox/mode log override / ctx.shell confined wrap with three-way attribution) / credential layers + record service API (read/describe/list/modify/delete_record, <scope>/<id> key grammar, 30s cross-process writer lock, modifyRecord as the only write path, ctx.credentials Service + credentials/record-updated event) / authorization service (install_authorization(ctx): registerFlow/list/describe/cancel/begin + authorization/settled event, error-code set DUPLICATE_FLOW/NO_FLOW/UNKNOWN_METHOD/ALREADY_IN_FLIGHT/NOT_COMMITTED/DECLINED, credential-commit verification via credentials/record-updated + describe_record recheck) / subagent ACP+SDK+fork channels) |
capability seams docs |
Continuable subagents (start_continuable/send_message (with initial prompt), durable child session + cold resume, settlement delivery, async event-driven A8 (submit-and-return + watchSettlement + steer batch merge + ownership bookkeeping waiting/settled), lifecycle events subagent/start/subagent/end (runId-paired + epochStopReason/foldConsumedWork outcome folding + scoped dispatch via the delegating parent's scope carrier), named provider registry (register_provider → subagent/provider-removed edge on dispose), DRAINING admission cutoff (drain/drain_descendants + assert_admitting, verbatim refusal wording), interrupt authority matrix (user/ancestor authority + absent-target no-op), nested delegation (exec.agent as authorization subject, grandchild settlement notices to the direct parent), model-side delegation tool subagent (verbatim descriptions, canonical value + Tool.render, run_in_background routing), send_message/interrupt_agent/list_agents control tools) |
packages/subagent (subagent + subagent-in-process-driver + tool-subagent-control + tool-subagent-report) |
Agent Teams (implicit-root roster + durable peer mailbox + shared task DAG: team/member(v2)/team/task/team/message/queued/team/message/delivered log-only events folded from the Lead session, provisioned members as start_continuable children, CAS task-board transitions, advisory write-scope overlap checks, model-side 9 tools + team:policy prompt section, sync (no-loop) and async (in event loop) spawn delivery carriers; wire/Remote endpoints not carried, error semantics via TeamError.code closed set) |
packages/experimental/agent-team + tool-agent-team |
| Presets / agent intervention / trajectory / dynamic plugins / approval | packages/preset + core/agent + interaction |
Preset system (shipped system root + multi-root first-root-wins roster, project_preset/project_session_agent_preset projections, PresetLockedError on already-started sessions, shipped presets read-only to authoring, agent.cordis.yml → mini Preset translation; miniharness presets list/show/select/delete as a teaching-extension CLI for the upstream web Remote surface) |
packages/preset (agent-presets) |
| Protocol entries (ACP / JSON-RPC SDK / hooks bridge) | acp + sdk + hooks |
Official Python SDK interop (upstream DeepSeekHarness drives mini worker via _launch_args; tests/test_upstream_sdk_interop.py, skips without pydantic/upstream sources) |
python/sdk |
| Async event bus, true parallel tools + barrier | core/agent-loop |
| CI (GitHub Actions, Python 3.10~3.13, integration-tagged real-API tests) | — |
The upstream browser frontend (packages/client, React monorepo) is not reproduced verbatim: its wire surface is fully aligned (an upstream client pointed at the mini backend works). Two consumer fronts ship: the productized webui/ (repo-top standalone React + TypeScript + Vite project, depends only on the wire contract; build & run: webui/README.md), plus web/static/ as a vanilla SPA teaching reference only (old SSE wire, does not work against the current alpha.1 backend).
Requirements: Python 3.10+. Required dependencies install with pip install -e .: httpx (DeepSeek SSE transport), filelock (credential cross-process writer locking), watchdog (HMR file watch), pyyaml (YAML config); the web transport layer needs pip install ".[web]".
# run all tests
python -m unittest discover -s tests -t .
# end-to-end demo (fake model + tools + crash recovery, no API key needed)
python -m miniharness.demo
# multi-turn chat with the fake model
python examples/chat_demo.py
# plan mode + goal demo (/plan, exit_plan_mode review, /goal, goal-round continuation)
python examples/plan_goal_demo.py --approve
# one-shot task, like `dsh --profile headless "task"` (needs DEEPSEEK_API_KEY)
python -m miniharness.cli --profile headless "run the tests"
# start the web transport server (requires: pip install ".[web]")
python -m miniharness.cli --profile web
# read-only composition dump, like `dsh --dump-config`
python -m miniharness.cli --dump-config
# list / resume / delete persisted sessions
python -m miniharness.cli sessions
# agent presets: shipped system root + user presets (list/show/select/delete)
python -m miniharness.cli presets listAll CLI-written state lives under MINIHARNESS_HOME (default ~/.miniharness): --profile headless sessions and miniharness sessions under $MINIHARNESS_HOME/sessions, user presets under $MINIHARNESS_HOME/.agent-presets. Point it elsewhere to relocate all durable state, e.g. export MINIHARNESS_HOME=/data/miniharness.
export DEEPSEEK_API_KEY=sk-... # PowerShell: set DEEPSEEK_API_KEY=sk-...
python examples/real_api_demo.pypip install -e .
miniharness # equivalent to `python -m miniharness.cli` (same entry point)mini-deepseek-harness-python/
├── miniharness/ # core package (mature OSS libraries first, family layout, see docs/architecture.md)
│ ├── core/ # upstream packages/core
│ │ ├── session/ # types / json / message / invariant / repair / surface / session
│ │ │ ├── persistence.py
│ │ │ ├── generation.py # multi-generation read-side + migrate-on-open
│ │ │ ├── released/ # released v0/v1 codecs + v0→v1→v2→v3 migration chain
│ │ │ └── zstd_frames.py
│ │ ├── scope.py # Context / PluginManager
│ │ ├── tools.py # tool registry + execution pipeline
│ │ └── agent_loop/ # agent.py + tool_calls.py
│ ├── llm/ # upstream packages/llm
│ │ ├── protocol.py # StreamChunk / LlmAdapter / LlmFailure / BlockAssembler
│ │ ├── deepseek.py # DeepSeek wire serialization + SSE adapter
│ │ ├── fake.py # FakeLlmAdapter (no API key)
│ │ ├── retry_policy.py # retry policy parsing (normal/always)
│ │ ├── retry.py # agent/request-error recovery + backoff
│ │ └── token_meter.py # TokenMeter incremental fold + usage anchor
│ ├── compaction/ # upstream packages/compaction
│ │ ├── engine.py # pre-step pressure + request-error overflow recovery
│ │ ├── region.py # selectCompactableRange + checkpoint transaction
│ │ ├── summarizer.py # prefix-replay summarization + checkpoint framing
│ │ └── config.py # spec parsing (threshold / retain / retries)
│ ├── boot/ # upstream packages/boot
│ │ ├── boot.py # startup + patch overlays
│ │ ├── composition.py # YAML config / !!js interpolation / dump rendering
│ │ └── dotenv.py # .env parsing (parse_dotenv)
│ ├── cli/ # apps/cli
│ │ ├── main.py # launcher options (profile / patch / dump)
│ │ ├── headless.py # one-shot task entry
│ │ ├── default_tools.py # default toolset for headless
│ │ └── session_cmds.py # session list / resume / delete
│ ├── protocol/ # acp / sdk / hooks bridges
│ ├── seams/ # sandbox / credentials (incl. CredentialsService) / authorization / subagent seams (incl. windows-acl kernel executor)
│ ├── shell/ # ctx.shell bash executor family (local + sandboxed)
│ ├── goal/ plan/ jobs/ skills/ commands/ attachment/
│ ├── web/ # apiproxy subset: envelope / api / streams / approvals / server / downloads / frontend / launcher
│ ├── web/static/ # vanilla SPA teaching reference (old SSE wire; product frontend = ../webui)
│ ├── preset/ extensions/ interaction/ client/
│ ├── demo.py # end-to-end demo
│ └── example_plugins.py # boot demo plugins
├── tests/ # acceptance tests (unittest)
├── examples/ # chat & real-API demos
└── docs/
├── index.md # handbook index (learning map)
├── architecture.md # architecture + upstream mapping
├── chapters/ # 00-setup ~ 15-schemastery tutorials
└── report/ # analysis report (MkDocs Markdown, Mermaid diagrams)
- DeepSeek AI and the DeepSeek Harness team, for the original system and for open-sourcing it.
- The Cordis project, for the plugin paradigm this project re-implements.