Sessions & Messages
dsh-engine-switch
Yuki-takuya-kun/dsh-engine-switch · ★ 1
Route DeepSeek Harness top-level sessions to pluggable loop engines by agent-preset — Claude Code ships as a built-in engine.
Manifest details
安装
dsh plugin --profile web add github:Yuki-takuya-kun/dsh-engine-switchGitHub 源码安装:首次需按提示配置 allowBuilds 构建授权后重试
For install and environment setup, plus plugin development tutorials, see DSH community docs ↗
README
Table of contents
✨ What it does
- 🔀 Pick engine by preset: each session is driven by whichever engine its current preset points to. Order: preset declares one > config points one out > preset name equals engine name > default DeepSeek.
- 🔁 Switch before typing: change preset before sending the first message and the session switches engine on the spot (either direction) — no new session, no restart.
- 📦 Preset auto-installed: once an engine is installed, the presets it ships are copied into DSH's preset directory and show up in the picker right away.
- 🤝 Engine and session stay out of each other's way: an engine never learns about "presets", and a session never learns it "was switched" — each just does its own job.
- 🌐 Subagents always use DeepSeek: regardless of what the top-level session picked, subagents keep going through DeepSeek.
- ⏯️ Resume picks it back up: continuing a past session re-finds the right engine from the preset recorded in the log.
🔌 In one line: this plugin itself ships no engine and no preset. It only defines "how an engine plugs in", then handles three jobs — pick the engine by preset, switch before typing, install the preset. Actual engines are registered by other plugins via
ctx.engineSwitch.register(engine).deepseekis a special name meaning "fall back to DeepSeek's original loop".
🚀 Install
dsh plugin --profile web add github:Yuki-takuya-kun/dsh-engine-switch
# then install at least one engine plugin, e.g.:
dsh plugin --profile web add github:Yuki-takuya-kun/dsh-claude-code
⚙️ Enable
Edit ~/.dsh/profiles/web/cordis.patch.yml:
- id: dsh-engine-switch
config:
enabled: true
Restart the web app. Presets shipped by engine plugins appear in the picker; pick one → that engine, anything else → DeepSeek.
🎯 How a preset picks an engine
Most of the time you do nothing: an engine's shipped preset has a directory name equal to the engine name, so it auto-matches (e.g. dsh-claude-code's preset directory is claude-code, and so is its engine).
To point one manually, two ways (highest priority first):
Declare it in the preset: edit the preset's
agent.cordis.yml, add adsh-engine-switchentry withengine:# ~/.dsh/.agent-presets/<preset-name>/agent.cordis.yml - name: dsh-engine-switch config: engine: claude-code # this preset runs on the claude-code enginePoint it out in config: write "preset name → engine name" in
engineByPreset, no preset-file edits:config: engineByPreset: research: claude-code
With neither set, it falls back to defaultEngine (default deepseek, i.e. DeepSeek).
🔌 How an engine registers
Write a plugin that inject: ["engineSwitch"], then call ctx.engineSwitch.register(...) in apply:
export const inject = ["engineSwitch"];
export function apply(ctx) {
ctx.engineSwitch.register({
id: "claude-code", // engine name = its shipped preset's directory name
name: "Claude Code",
description: "…",
presetDir: fileURLToPath(new URL("./presets/claude-code/", import.meta.url)),
makeAgent(loopCtx, id, options, session, engineConfig) {
return new ClaudeCodeAgent(loopCtx, id, options, session, engineConfig);
},
});
}
presetDir holds agent.cordis.yml + preset.yml; the framework installs them to ~/.dsh/.agent-presets/<id>/. See Engine API for the full interface an engine implements.
Reference engine: dsh-claude-code — a real plugin that registers a
claude-codeengine, driving sessions with the local Claude Code CLI.
⚙️ Config
| Key | Default | Meaning |
|---|---|---|
| enabled | false | master switch: false = plugin does nothing, sessions stay on DeepSeek |
| defaultEngine | "deepseek" | engine for presets that name none (and preset-less sessions); deepseek = fall back to DeepSeek |
| engineByPreset | {} | "preset name → engine name" overrides |
| engines | {} | "engine name → engine's own config" (passed through verbatim, unparsed) |
🔍 How it works (optional)
- On startup the plugin swaps DSH's session-driver factory for a router that picks the engine by preset.
- On create, resume, and preset switch, it resolves the engine using the order above and builds the matching driver.
deepseekis not a real engine — it means "fall back to DSH's original DeepSeek loop".
📄 License
MIT. See THIRD_PARTY_NOTICES.md.