dsh-loop-engine
Manifest valid★ 8Adds a Settings "Loop engine" dropdown that switches which agent loop engine drives sessions — the built-in in-process driver or a hosted Claude Code, Codex, Pi, or Kimi Code engine — with no changes
dsh-loop-engine
Switch the agent loop engine of dsh web the same way you switch a model: a "Loop engine" dropdown in Settings chooses which driver runs your agents — the built-in in-process loop, the Claude Code CLI, the Codex CLI, the Pi CLI, or the Kimi Code CLI — without changing anything in the main repository.
Install
dsh plugin --profile web add dsh-loop-engine
Restart dsh web, then open Settings → Loop engine.
Switching engines rewrites a small managed block in
cordis.patch.yml. Everything else you wrote in that file is preserved; only the plugin's own span changes.
pnpm users: pnpm 10+ blocks dependency build scripts by default, so the install may fail with
ERR_PNPM_IGNORED_BUILDSnamingesbuild,@google/genai, andprotobufjs(all reached through the engine SDKs). This is expected — allow them and retry, either interactively withpnpm approve-builds, or by declaring them in the installing project'spnpm-workspace.yaml:allowBuilds: esbuild: true '@google/genai': true protobufjs: trueOnly the installing project can grant this; the plugin cannot pre-approve its own dependencies. Note that
allowBuildsis the pnpm 11 spelling — pnpm 11 deletes the legacyonlyBuiltDependencies(andneverBuiltDependencies,ignoredBuiltDependencies) keys frompackage.jsonand no longer honors them, so putting them there silently does nothing.
Running against a harness source checkout
The install above assumes a published dsh (npx @deepseek-ai/dsh) and needs
no extra setup. Booting the harness from its source checkout
(cd deepseek-harness && pnpm dsh web) takes one more step, because the two
halves then resolve harness packages to different files:
| Side | @deepseek-ai/dsh-scope resolves to |
|---|---|
| Source-launched harness | packages/core/scope/src/index.ts (via tsconfig paths) |
Installed plugin (its tarball ships only lib/) | packages/core/scope/lib/index.js |
That is one package loaded as two module instances. dsh-scope tags a context
with a module-local Symbol('dsh.scope'), so a scope minted through one instance
is invisible to the other, and resuming a session fails with:
agent-presets: refusing to compose an unscoped context;
the scope key is what joins an agent to its preset
Bridge the profile's peers to the harness source so both halves share one
instance. Set HARNESS to the harness checkout as a file:// URL, then run
this from the profile directory:
HARNESS=file:///path/to/deepseek-harness # e.g. file:///D:/repos/deepseek-harness
cd "$DSH_HOME/profiles/web" && mkdir -p shims
while IFS='|' read -r name rel; do
mkdir -p "shims/$name"
printf '{"name":"@deepseek-ai/%s","version":"0.0.0","private":true,"type":"module","main":"index.mjs"}\n' \
"$name" > "shims/$name/package.json"
printf "export * from '%s/%s'\nimport * as mod from '%s/%s'\nexport default mod.default\n" \
"$HARNESS" "$rel" "$HARNESS" "$rel" > "shims/$name/index.mjs"
done <<EOF
cordis|vendor/cordis/src/index.ts
schemastery|vendor/schemastery/src/index.ts
dsh-agent|packages/core/agent/src/index.ts
dsh-scope|packages/core/scope/src/index.ts
dsh-session|packages/core/session/src/index.ts
dsh-session-persistence|packages/session/session-persistence/src/index.ts
dsh-settings|packages/settings/settings/src/index.ts
dsh-subprocess|packages/subprocess/subprocess/src/index.ts
dsh-timeout|packages/util/timeout/src/index.ts
dsh-llm|packages/llm/llm/src/index.ts
dsh-invariants|packages/runtime-diagnostics/invariants/src/index.ts
dsh-home-paths|packages/util/home-paths/src/index.ts
EOF
Then point the profile's package.json at them and reinstall:
node -e 'const f="package.json",j=require("./"+f),d=j.dependencies??={}
for(const n of ["cordis","schemastery","dsh-agent","dsh-scope","dsh-session","dsh-session-persistence","dsh-settings","dsh-subprocess","dsh-timeout","dsh-llm","dsh-invariants","dsh-home-paths"])
d["@deepseek-ai/"+n]="file:./shims/"+n
require("fs").writeFileSync(f,JSON.stringify(j,null,2)+"\n")'
pnpm install
Restart dsh web. If something loads the @deepseek-ai/dsh-scope/invariant
subpath, also give that shim an invariant.mjs (export * from '$HARNESS/packages/core/scope/src/invariant.ts') and add
"./invariant": "./invariant.mjs" to its exports.
Installing the plugin as a local
link:checkout sidesteps this entirely: when the checkout sits beside the harness repo it inherits the harness's owntsconfig.jsonand with it the samepathsmapping. The split only appears when a packed plugin (npm or tarball) meets a source harness.
Version compatibility
dsh-loop-engine is versioned in lockstep with the harness it targets: the
version is the harness version plus a plugin release counter (0.1.5-rc1
targets harness 0.1.5-rc.1), and every harness package it consumes is pinned
exactly in peerDependencies. The two must be matched — a mismatch fails
loudly at boot or session resume:
| dsh-loop-engine | Requires harness |
|---|---|
| 0.1.5-rc1 | 0.1.5-rc.1 |
| 1.0.0-rc8 … 1.0.0-rc15 | 0.1.2-rc.1 |
| 1.0.0-rc7 and earlier | 0.1.1-rc.2 |
- 0.1.5-rc1 requires harness 0.1.5-rc.1. It uses the 0.1.5 assistant-stream
contract (
assistant/messageembeds its exact timedstreamand rejectssourceEventSeqs), the driver-ownedInboxinterface, the two-argumentAgentSetup, and theSessionPersistence.create/openhandle seam. - Releases up to
1.0.0-rc15used the plugin's own version series and target harness0.1.2-rc.1; they are not compatible with harness0.1.5-rc.1. - To use the plugin with an older harness, install the release matching it
(e.g.
npm i dsh-loop-engine@1.0.0-rc15for harness 0.1.2-rc.1). - The GitHub Release body of each tag states the harness version it targets.
Requirements
- For the Claude Code engine: the Claude Code CLI installed and logged in on the host.
- For the Codex engine: authenticated either via
codex loginon the host or aCODEX_API_KEYenvironment entry. - For the Pi engine: authenticated the way
piexpects (its own~/.pi/agent/auth.jsonor the provider's API-key environment variable such asANTHROPIC_API_KEY). - For the Kimi Code engine: the
kimiCLI installed and logged in on the host (e.g.kimi login), and reachable onPATH(or pinned to an absolute path viakimiBinin the composition entry).
Usage
- Pick an engine in Settings → Loop engine —
in-process(default),claude-code,codex,pi, orkimi— then restartdsh web. - To return to the default, pick In-process and restart again.
- To remove the plugin:
dsh plugin --profile web remove dsh-loop-engine, then restartdsh web.
What a hosted engine takes over
While a hosted engine is selected, it owns the session's command and skill
surface: the plugin disables dsh's own /goal and points new sessions at a
managed loop-engine agent preset — a copy of standard minus the dsh-native
/compact, /plan, goal-tool, and skill rows that an external engine cannot
honor — so the slash menu shows the engine's bridged commands and its own
skill catalog. Engine-agnostic dsh commands (/export, /feedback,
/permission) keep working and stay. Switching back to in-process restores
the previous preset default; already-running sessions always keep the preset
they were created with.
Engine notes
- The Claude Code driver runs one SDK query per step; its slash commands are
bridged into the web menu (built-ins plus user-level
~/.claude/commands/) and forwarded to the engine, which expands them natively. Project-level.claude/commands/files stay engine-side and also work typed directly. - The Codex driver runs
codex app-serverand has no interactive tool approval — permissions come from the session'ssandboxMode+approvalPolicy. ItsAGENTS.mdinstruction files are surfaced through the dsh skill-injection seam across every directory from the session cwd up to the git root, plus~/.codex/AGENTS.md. - The Pi driver runs
pi --mode rpc; Pi has no permission system, so the whole child is sandboxed through the dsh subprocess service (defaultread-only). Its context files (AGENTS.md/CLAUDE.mdwithAGENTS.override.mdpreferred, plus the user-level file under the pi config dir) and itsskills/catalogs (~/.pi/agent/skills/and.pi/skills/) are surfaced through the dsh skill-injection seam. - The Kimi Code driver runs a persistent
kimi acpchild (Agent Client Protocol over stdio) and speaks one statelesssession/new+session/promptper dsh step; the durable dsh session log is the sole model context. It streams assistant text (agent_message_chunk) and thinking (agent_thought_chunk) incrementally as liveagent/assistant-streamframes, and the step's durableassistant/messageembeds that exact timed stream; it maps tool calls/streams (tool_call/tool_call_update) intotool/call+tool/result. ACP surfaces tool approvals assession/request_permission, which the driver answers from the session's dsh approval knobs (anaskpolicy denies, fail-closed). The child is spawned through the dsh subprocess seam — the only privilege boundary (default read-only sandbox). Its projectAGENTS.mdchain (cwd→git root) and.kimi-code/skills/catalogs (user and project) are surfaced through the dsh skill-injection seam, and its slash commands are bridged (built-ins forward the raw/nameline back to the engine, which expands it). The prompt is an ACP request body — not an argv positional — so there is no command-line length ceiling. Note Kimi's remaining slash-command surface is TUI-only (/login,/provider,/settings,/sessions, …); those are not bridged because the ACP prompt surface does not expand them, butskill:commands are carried by the skill seam and Kimi's own shorthand.
License
MIT
Compatibility
Versions
| Latest version | Published | Size |
|---|---|---|
| 1.0.0-rc3 | — | — |
| 1.0.0-rc4 | — | — |
| 1.0.0-rc6 | — | — |
| 0.1.7-rc2 | — | — |
| 0.1.5-rc2 | — | — |
| 1.0.0-rc8 | — | — |
| 0.1.5-rc5 | — | — |
| 1.0.0-rc7 | — | — |
| 0.2.0-rc1 | — | — |
| 0.1.5-rc4 | — | — |
| 0.1.7-rc1 | — | — |
| 1.0.0-rc5 | — | — |
| 0.1.5-rc1 | — | — |
| 0.1.7-rc5 | — | — |
| 1.0.0-rc12 | — | — |
| 1.0.0-rc10 | — | — |
| 1.0.0-rc9 | — | — |
| 0.1.7-rc4 | — | — |
| 1.0.0-rc14 | — | — |
| 1.0.0-rc13 | — | — |
Comments
Loading…
Similar plugins
by burning-frappuccino
DSH OVERDRIVE — Fast/Max execution gears for DeepSeek Harness. 少走弯路,火力全开。
★ 6
MIT
TypeScript
Oct 24, 2026
dsh plugin --profile web add dsh-turboby MJorgin
⚡ DSH 指挥家 / Conductor for DeepSeek Harness — in-session dispatch to 11 external agent CLIs (Codex, Claude Code, TraeCode, OpenCode, Gemini, Cursor, Kimi, Qwen, Copilot, WorkBuddy, Grok). Zero-dep skil
★ 14
MIT
JavaScript
Sep 30, 2026
dsh plugin --profile web add dsh-agent-conductorby gulagala001
Codex, Grok Build, Cursor, Pi, and ZCode presets on DSH models, with native sessions and optional OMD enhancements.
★ 4
Apache-2.0
TypeScript
Oct 25, 2026
dsh plugin --profile web add oh-my-agents-above-allby zhangjunjesse
Run the main session model on a local Claude Code subscription through the official Claude Agent SDK, taking over the llm/stream route for the claude-code provider, with token-level streaming, session
★ 3
JavaScript
Sep 17, 2026
dsh plugin --profile web add dsh-claude-driverby ruby1304
Vision for any DSH route: paste images in the Web composer with intent-aware auto-analysis, delegate workspace image reads to a Kimi/MiniMax vision subagent, and materialize pasted originals for editi
★ 1
↓ 76/wk
MIT
TypeScript
Sep 10, 2026
dsh plugin --profile web add dsh-vision-subagentTurns a one-line DSH draft into a complete task brief (role / goal / constraints / output format). The engine is a byte-verified port of linshenkx/prompt-optimizer (three modes, 10 templates identical
★ 0
dsh plugin --profile web add @benrong/dsh-prompt-polish