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 report@google/genai,node-pty, andprotobufjsas blocked.
This is expected — click "Allow build scripts and retry" (or run
pnpm approve-builds, or list them underpnpm.onlyBuiltDependenciesin
your project root) and retry. Only the installing project can grant this;
the plugin cannot pre-approve its own dependencies.
Version compatibility
dsh-loop-engine is versioned independently of the harness (1.0.0-rcN) but
is bound to a specific harness release via peerDependencies. The two must be
matched — a mismatch fails loudly at boot or session resume:
| dsh-loop-engine | Requires harness |
|---|---|
| 1.0.0-rc8 | 0.1.2-rc.1 |
| 1.0.0-rc7 | 0.1.1-rc.2 |
- 1.0.0-rc8 is not compatible with harness 0.1.1-rc.2 or earlier. It uses
the 0.1.2 persistence seam (SessionPersistence.create/open+
SessionHandle), theinstallSectionsettings API,ToolCallId, and
Session.snapshotEvents()— none of which exist in older harnesses. - To use the plugin with an older harness, install the loop-engine release that
matches it (e.g.npm i dsh-loop-engine@1.0.0-rc7for harness 0.1.1-rc.2). - 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 a
CODEX_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 as
ANTHROPIC_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.md
preferred, plus the user-level file under the pi config dir) and its
skills/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/prompt
per 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 into the log, and 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