Architecture
DeepSeek Harness architecture overview: everything is a plugin, profiles & bundles, the core package map, events, the agent loop and capability seams
This page outlines the harness architecture and helps you decide which extension point new behavior attaches to. It assumes you know Cordis.
Everything is a plugin
Cordis is the framework under dsh: plugins contribute services, typed events, and reversible effects to a shared context. Every part of the product is a plugin — including the model adapter, the tool registry, the session log, and the agent loop itself — so every part is replaceable from configuration.
There is no privileged core to patch: you extend dsh by mounting a plugin beside the others, and registrations are effects that unwind when their plugin unloads.
Architecture overview
Every capability — model routing, tools, the loop, the log, policy — hangs on the same Cordis Context, so each one is replaceable.
Profiles and bundles
A running dsh is a plugin tree composed at boot from ordered layers.
- A profile is a named composition stored in the Harness home: it lists the bundles it stacks, holds out-of-tree plugins, and keeps the user's own
cordis.patch.yml.webandheadlessship as templates. - A bundle is a distribution format for Cordis config rows and the code they mount.
Each declares itself in its own package.json under a dsh field: dsh.profile lists a profile's bundles, and dsh.bundle points at a bundle's patch file.
Layers apply in this order: each bundle in the profile's listed order, then the profile's cordis.patch.yml, then the home-level one, then any --patch overlay. To see the tree your machine actually boots:
dsh --profile web --dump-configCore packages
Here are some core packages that contribute to the Cordis tree.
| Package | Owns | ctx key |
|---|---|---|
core/session | The append-only SessionEvent log and in-memory store | ctx.sessions |
core/system-prompt | Prompt-section and tool-schema assembly | ctx.systemPrompt |
core/tools | The scoped tool registry and guarded execution pipeline | ctx.tools |
core/agent | The Agent interface, live registry, and agent/* events | ctx.agents |
core/agent-loop | The default driver implementing that interface | ctx.agentLoop |
llm/llm | Message and stream vocabulary plus the adapter seam | ctx.llm |
Events
Events are the extension points, and picking the right domain is the first decision in most changes.
- Session events are durable facts appended to the log and broadcast through
session/event. Use one when the fact must survive a reload. - Agent events (
agent/*) carry a liveAgent; use them to observe or intercept work in flight. - Capability events attach policy and adapters to a seam (
fs/*,tools/*,telemetry/*) without importing the loop.
Turn flow
A step is one model request plus the tools it calls; a turn is zero or more steps. The model proceeds through: claim input → assemble prompt sections and tool schemas → issue the model request → stream the response → tool calls pass through the tools/pre-execute → tools/execute → tools/post-execute pipeline → produce tool results, until nothing is owed.
turn/*, step/*, user/message, assistant/*, and tool/* are durable session events; agent/pre-step, agent/request, llm/stream, and the three tools/* events are waterfalls, whose listeners must call next() to delegate.
Session log
The session log is the source of the context the model sees. Model-visible means logged: anything that reaches a model request must be reconstructable from the log. That is why a new model-visible input requires a new session event.
Capability seams
A seam is a swappable capability with three roles: a Service Definition declaring the interface, a Service Provider implementing it, and a Consumer using it, commonly a model-facing tool. A package may combine roles, but one role alone is not a seam; adding a capability means designing all three.
Seams are why one provider swap changes the whole product: filesystem and subprocess providers share one execution world, so pointing them at a remote sandbox moves Bash, PTY, and LSP with them.
Where new behavior goes
| Goal | Mechanism |
|---|---|
| Add a model provider | register its adapter on ctx.llm |
| Add a model-facing capability | register on ctx.tools; its schema joins prompt assembly |
| Add shell execution | register a ctx.shell backend |
| Add background work | register on ctx.jobs |
| Intercept a request, tool, or turn | use its agent/* or tools/* event |
| Add model-facing context | call agent.inject(); it lands in the next admitted request |
| Add durable session state | extend SessionEventMap; render and replay from the log |
Next steps
- To extend the runtime temporarily while it runs, see Dynamic Plugins.
- For complete step-by-step examples, see the Cookbook.
Cordis Primer
The core concepts of the Cordis plugin framework underneath DeepSeek Harness: plugins, ctx, services, events and reversible effects
Dynamic Plugins
The runtime dynamic plugin model: Host and Client halves, immutable package versions, the define/run/stop/undefine lifecycle and approval flow