LoserFox/marisa-distro--plugins-dsh-llm-fallbacks ↗★ 7
dsh-llm-fallbacks
Automatic provider/model fallback chains for DeepSeek Harness agents when LLM requests keep failing (retry exhausted, auth, quota, rate limit)
安装
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:LoserFox/marisa-distro#4aa96256d0af09fa65e64679a1c7826342e9ded2&path:plugins/dsh-llm-fallbacks说明文档
阅读完整 README ↗Configuration surfaces
The plugin's settings live in a shared fallbacks: namespace, editable from three surfaces:
| Surface | What it is | Notes |
|---|---|---|
| Web settings card | Settings → Plugins → Fallbacks | Full GUI editor for the fallbacks: namespace; writes the shared settings document |
$DSH_HOME/settings.yaml | fallbacks: section in the dsh settings document | The shared source of truth — the same file the web card writes; readable and editable everywhere, including scripted setups |
TUI /settings | fallbacks section in the dsh-tui settings screen | dsh-tui ≥ v0.8.5; native fields for simple keys, JSON text fields for complex structures (see dsh-tui profile (terminal)) |
Pick the surface that matches your front end: web users get the card, terminal users get /settings, and the YAML file works everywhere. (/fallbacks and /fallbacks config are diagnostics — read-only views, not edit surfaces.)
Minimal configuration
Add a fallbacks: section to the shared settings document ($DSH_HOME/settings.yaml — see Configuration surfaces):
fallbacks:
enabled: true # feature switch — defaults to off (plugin is a no-op otherwise)
rootChain: # all-day chain: leading entries = fallback walk, last = Default model (official V4)
- anthropic/claude-3-5-sonnet # walked first
- deepseek-official/deepseek-v4-flash # last resort (Flash or Pro)
timeSlots: # optional: rotate the effective root chain by wall-clock windows
- kind: preset # frozen UTC+8 window; only the chain is editable
preset: liang-peak # 09:00–12:00 and 14:00–18:00, every day
chain:
- anthropic/claude-3-5-sonnet
- kind: custom # custom window (may wrap midnight)
name: evening # optional display name
start: '22:00'
end: '02:00'
days: [1, 5] # optional; omitted/empty = every day (0=Sunday…6=Saturday)
chain:
- openai/gpt-4o
roles: # optional: declare role entities, then reference them from rules
list:
- id: reviewer # unique id; "inherit" is reserved
persona: Code-review subagents
chain:
- openai/gpt-4o-mini
fallback: inherit-root # role chain first, then the inherited rootChain
rules: # subagent-only: rules never match root requests
- role: reviewer # all subagents → the reviewer role
Build the section up in four steps:
1. Enable the plugin. enabled: true turns the fallback engine on. It defaults to off — with no chains configured the plugin is a complete no-op.
2. Set the all-day rootChain. Leading entries are the fallback chain, walked first when a request fails; the last entry is the Default model.
Conformance: the last entry must be exactly one official V4 model —
deepseek-official/deepseek-v4-flashXORdeepseek-official/deepseek-v4-pro. The settings card and gateway reject any other tail on save; a legacy non-official tail warns at startup and keeps working as a fallback-only walk, but cannot be saved as-is.
3. Add timeSlots (optional). Rows rotate the effective root chain by wall-clock windows. Preset rows use frozen UTC+8 windows (only their chain is editable; while a preset row exists, tz locks to Asia/Shanghai); custom rows take start/end (may wrap midnight) and an optional days list. The first row whose window contains the current moment wins; no match → the all-day rootChain. Rotation is a routing seed — it applies on the next root request and consumes no cooldown (see Time slots).
4. Add roles (optional). Declare role entities in roles.list (id, persona, chain, optional fallback policy), then map subagents to them with roles.rules. Rules never match root requests — with no rule match (or on a root request) the built-in inherit role applies and appends the rootChain.
Full reference (role entities, fallback strategies, rules, selectors, preset roles, time-slot presets) → docs/configuration.md.
Upgrade note (behavior change): an existing
fallbacks:section without an explicitenabledkey resolves tofalseafter upgrading — addenabled: trueto keep the plugin active.