DeepSeek Harness 插件

dsh-llm-fallbacks

Automatic provider/model fallback chains when LLM requests keep failing after retries, auth, quota, or rate limits.(英文原文)

跳到安装方式

来源信息

GitHub 仓库
omdsh-dev/dsh-llm-fallbacks
最近更新
2026年8月21日
分类
模型与服务商
GitHub stars
15
载体类型
plugin
目录证据
上游声明已找到 dsh.bundle
证据路径
package.json#dsh.bundle
核对版本
0.1.0-rc.8
上游核对日期
2026-08-20

该证据由上游目录提供。本站没有安装、运行或安全审核这个插件。

安装

默认先复制一段 Prompt,让 Agent 读 GitHub 仓库和源码;需要自己装时再切到命令。

复制这段 Prompt,发给 DSH、Codex 或其他 Agent,让它先读 GitHub 仓库和源码。

请先不要安装或执行任何命令。阅读这个插件的 GitHub 仓库、README 和关键源码,然后用清楚、直接的方式回答以下问题,帮助我判断它是否适合我的需求:

1. 这个插件是什么,解决什么问题;
2. 适合哪些用户和典型使用场景;
3. 安装后如何使用,并给出一个最小使用示例;
4. 有哪些已知限制,以及隐私、安全、兼容性或维护风险;
5. 给出“推荐 / 有条件推荐 / 不推荐”的明确建议和理由。

请区分仓库明确说明、根据源码推断和未知信息。证据不足时请明确说明,不要猜测或照抄 README。

GitHub:https://github.com/omdsh-dev/dsh-llm-fallbacks
插件名:dsh-llm-fallbacks
作者:omdsh-dev

检查来源文件

安装前先看这个插件目录里的 README 和其他文件。

文件资源管理器4 个文件
README.zh-CN.md来源说明 · 只读预览
README 语言

dsh-llm-fallbacks

English | 中文

![license](LICENSE) !node !pnpm !dsh tui !dsh ![dshfind](https://dshfind.com/zh/plugins/omdsh-dev/dsh-llm-fallbacks?ref=badge)

dsh(DeepSeek Harness)的自动模型降级插件:当 root agent 或 subagent 的模型请求持续失败(重试耗尽、权限、配额超限、限流 429)时,按角色/模型 fallback 链自动切换 provider/model,当前 step/turn 在目标模型上继续完成——任务不因模型问题中断。

两个 dsh 前端均可用:web profile(设置 → 插件配置 → Fallbacks 卡片)与 dsh-tui 终端 profile(/fallbacks 会话诊断、/fallbacks config 回读,以及 /settings 中的 fallbacks 区块用于编辑)。

峰谷无忧

峰谷无忧(分时切换)按墙钟窗口轮换生效 root 链:每个时段槽行拥有自己的 fallback 链,第一个窗口包含当前时刻的行将在下一个 root 请求取代全时段链——无行命中时,全时段链作为兜底保持在最后。峰谷窗口因此可以使用不同的模型链,而失败降级路径(降级切换)保持不变。

![峰谷无忧](docs/assets/screenshot-1-zh.png)

四个冻结的 UTC+8 预设(窗口为代码常量;存在预设行时 tz 锁定 Asia/Shanghai):

预设窗口
liang-peak每天 09:00–12:00 与 14:00–18:00
liang-valley其它所有 UTC+8 时间(Liang Peak 的补集)
glm-peak周一至周五 14:00–18:00
glm-valley其余时间(GLM Peak 的补集)

GLM 峰与 GLM 谷仅在已配置 zai-coding-cn 时出现在设置卡选择器中。

每个 root 请求时刻,第一条窗口包含当前时刻(按 fallbacks.tz,默认 Asia/Shanghai)的额外行生效;无行命中 → 全时段 rootChain——其链尾(默认模型)必须是恰好一个官方 V4 模型:deepseek-official/deepseek-v4-flashdeepseek-official/deepseek-v4-pro(二选一)。分时切换是路由种子而非失败决策:在下一个 root 请求生效、不消耗冷却、不计入 maxSwitchesPerStep,日志记为分时切换;失败降级保持降级切换。完整语义 → [分时槽预设(分时切换)](#分时槽预设分时切换) 与 [docs/configuration.md](docs/configuration.md)。

快速开始

安装

dsh plugin --profile web add dsh-llm-fallbacks      # web profile(设置 → Fallbacks 卡片)
dsh plugin --profile dsh-tui add dsh-llm-fallbacks  # dsh-tui 终端 profile

同一个插件、两个前端——区别只在 --profile 参数。钉版本:加 @<version>。registry 安装拉取的是已构建产物dist/),目标机无需构建。registry / git / 本地目录变体、卸载与 --dump-config 验证 → [docs/install.md](docs/install.md)。

修复旧会话(0.2.2 之前的版本)

0.2.2 之前的版本会把 fallbacks/switch 事件写入会话持久化日志,而新版 dsh 拒绝加载这类会话(issue #52——apply() 时的注册因插件与宿主解析到不同模块实例而无效)。如果升级后已有会话打不开,clone 本仓库并修复日志(先停 dsh):

git clone https://github.com/omdsh-dev/dsh-llm-fallbacks.git
cd dsh-llm-fallbacks
pnpm install
pnpm repair:fallbacks-switch-logs -- --dry-run            # 预览哪些会话会被改动
pnpm repair:fallbacks-switch-logs -- --apply --backup     # 给旧事件打 ignorable 标记

脚本默认扫描 ~/.dsh/sessions(可用 --root <dir> 覆盖),把遗留 fallbacks/switch 事件标记为 ignorable: true,宿主读路径即可重新接受该会话;每个被修复的日志保留一份 <file>.bak--apply 必须搭配 --backup,且须在 dsh 停止时运行。从 0.2.2 起插件不再写 durable 切换事件,新会话无需修复。

配置界面

插件的设置存在于共享的 fallbacks: 命名空间中,可通过三个界面编辑:

界面是什么说明
Web 设置卡设置 → 插件配置 → Fallbacksfallbacks: 命名空间的完整 GUI 编辑器;写入共享设置文档
$DSH_HOME/settings.yamldsh 设置文档中的 fallbacks: 分节共享的事实源——与 Web 卡写入的是同一个文件;任何场景(包括脚本化配置)都可读写
TUI /settingsdsh-tui 设置界面中的 fallbacks 区块需要 dsh-tui ≥ v0.8.5;简单键用原生字段,复杂结构用 JSON 文本字段(见 [dsh-tui profile(终端)](#dsh-tui-profile终端))

按你的前端选择入口:web 用户用设置卡,终端用户用 /settings,YAML 文件处处可用。(/fallbacks/fallbacks config 是诊断命令——只读视图,不是编辑入口。)

最小配置

在共享设置文档($DSH_HOME/settings.yaml——见 [配置界面](#配置界面))中添加 fallbacks: 分节:

fallbacks:
  enabled: true            # 功能开关——默认关闭(否则插件完全 no-op)
  rootChain:               # 全时段链:前面的条目 = 降级路径,最后一项 = 默认模型(官方 V4)
    - anthropic/claude-3-5-sonnet          # 先走
    - deepseek-official/deepseek-v4-flash  # 最后一档(Flash 或 Pro)
  timeSlots:               # 可选:按墙钟窗口轮换生效 root 链
    - kind: preset         # 冻结的 UTC+8 窗口;仅链可编辑
      preset: liang-peak   # 每天 09:00–12:00 与 14:00–18:00
      chain:
        - anthropic/claude-3-5-sonnet
    - kind: custom         # 自定义窗口(可跨午夜)
      name: evening        # 可选显示名称
      start: '22:00'
      end: '02:00'
      days: [1, 5]         # 可选;缺省/空 = 每天(0=周日…6=周六)
      chain:
        - openai/gpt-4o
  roles:                   # 可选:先声明角色实体,再由规则引用
    list:
      - id: reviewer       # 唯一 id;"inherit" 为保留字
        persona: 代码审查子代理
        chain:
          - openai/gpt-4o-mini
        fallback: inherit-root   # 先走角色链,再追加继承的 rootChain
    rules:                 # 仅对子代理生效:规则不匹配 root 请求
      - role: reviewer     # 所有 subagent → reviewer 角色

按四个步骤逐步构建:

1. 启用插件。 enabled: true 打开降级引擎。默认关闭(false——未配置任何链时插件完全 no-op。

2. 配置全时段 rootChain 前面的条目是降级链,请求失败时先走;最后一项是默认模型。

> 链尾合规:最后一项必须是恰好一个官方 V4 模型——deepseek-official/deepseek-v4-flashdeepseek-official/deepseek-v4-pro(二选一)。设置卡与 gateway 在保存时拒绝其它尾巴;遗留的非合规尾巴启动时告警并继续按 fallback-only 走原链,但无法原样保存。

3. 添加 timeSlots(可选)。 各行按墙钟窗口轮换生效 root 链。预设行使用冻结的 UTC+8 窗口(仅链可编辑;存在预设行时 tz 锁定 Asia/Shanghai);自定义行使用 start/end(可跨午夜)与可选的 days 列表。第一个窗口包含当前时刻的行生效;无行命中 → 全时段 rootChain。分时切换是路由种子——在下一个 root 请求生效、不消耗冷却(见 [峰谷无忧](#峰谷无忧))。

4. 添加 roles(可选)。roles.list 中声明角色实体(id、persona、chain、可选的 fallback 策略),再用 roles.rules 把 subagent 映射到角色。规则绝不匹配 root 请求——未命中规则(或 root 请求)时由内置 inherit 角色兜底,追加 rootChain

完整参考(角色实体、fallback 策略、规则、selector、预设角色、分时槽预设)→ [docs/configuration.md](docs/configuration.md)。

> 升级提示(行为变更):已有 fallbacks: 配置若未显式写 enabled,升级后解析为 false——请补上 enabled: true 以保持插件继续生效。

验证

保存配置并重启会话,然后键入 /fallbacks——只读的会话内诊断(来源、解析角色、链、最近降级切换、冷却状态)。在 dsh-tui profile 中,/fallbacks config 回读组合配置;见 [dsh-tui profile(终端)](#dsh-tui-profile终端)。

能力一览

  • root / subagent 自动降级:任意 agent 在模型故障下按链切换到下一个可用 provider/model,无需手动换模型。
  • 两块制配置rootChain 管 root 代理;声明式角色实体(roles.list)供 roles.rules 引用(或内置 inherit)。
  • 选择器里把链当主模型enabled 开启时,宿主模型选择器(web 与 TUI 一致)出现虚拟 FallbacksChain / Auto 行——选中它即以配置的链作为 root 主模型(需要 all-day 链头合规才能成功覆盖);选真实模型则保持 fallback-only(见 [模型选择器中的 FallbacksChain](#模型选择器中的-fallbackschain))。
  • 峰谷无忧(分时切换):可选的 fallbacks.timeSlots 行按墙钟窗口(配置级 tz 时区,默认 Asia/Shanghai)轮换 root 生效链——四个冻结的 UTC+8 预设(liang-peak / liang-valley / glm-peak / glm-valley,窗口为代码常量、仅模型链可编辑),或自定义 start/end/days 窗口。第一条命中的行生效;全时段行固定最后。时段切换在下一个 root 请求生效,日志记为分时切换——路由种子而非失败决策:不消耗冷却、不计入 maxSwitchesPerStep。失败降级保留降级切换文案(见 [分时槽预设(分时切换)](#分时槽预设分时切换))。
  • 派发时角色解析:在 subagent 的首次请求上,其角色按三个阶段解析——显式(agentPreset 匹配已声明角色 id)→ 确定性规则(不变)→ LLM 自动匹配(从已声明角色体系中选择,fallbacks.roleAutoMatch 默认 true)。解析出的角色的链头模型注入首次请求,并以显式 role → model 日志行记录(不写 durable fallbacks/switch 事件——issue #52 停写);设 roleAutoMatch: false 仅关闭 LLM 自动匹配阶段(显式 agentPreset 阶段仍生效——无显式角色时即复现原有仅规则行为)。设置卡总是渲染「启用角色自动匹配」开关(默认 true)以切换之——即使是从未声明过该键的旧配置,schema 默认值同样生效。
  • 冷却与回主:被切离/失败的模型在冷却期内不再入选;revertPolicy: cooldown-expiry 冷却到期后自动回主模型。
  • 行为可见:每次切换以 info 级日志行(from/to/role/reason)记录——无静默换模型。插件刻意不写 durable fallbacks/switch 会话事件(issue #52——apply() 时的事件类型注册被证伪无效,含该事件的会话在 dsh 重启后拒绝加载)。由旧版插件写入、含此类事件的会话由 scripts/repair-fallbacks-switch-logs.ts 修复——旧事件被标记 ignorable 后,受影响会话可重新加载。
  • 安全阀maxSwitchesPerStep 限制每 step 切换次数、alwaysModeRetryCap 限制 always 模式重试——链循环不会放大延迟。
  • 无配置回归(no-op):未配置任何链时行为与未安装插件完全一致——enabled 默认关闭(见 [最小配置](#最小配置))。

dsh-tui profile(终端)

在 dsh-tui profile 中,插件有三个操作面——职责严格区分:

  • /fallbacks —— 本次会话发生了什么:来源、解析角色、生效链、最近降级切换、冷却状态。只读。
  • /fallbacks config —— 配置了什么:组合配置回读(触发码、根链、分时槽、时区、角色、角色规则、冷却、回主策略、安全阀、预置、角色自动匹配)。除唯一的动作命令 /fallbacks config revert-seed <role-id> 外只读——该命令把某个 seed 角色的 persona 还原为已声明的默认(设置 seam 无法表达 Web 卡的这类动作能力)。
  • /settings —— 编辑界面。插件注册 fallbacks 区块,与 Web 设置卡完全一致:布尔(enabledroleAutoMatch)渲染为开关、下拉(presetsrevertPolicy)为选择器、数值(cooldownMsmaxSwitchesPerStepalwaysModeRetryCap)为数字输入;复杂结构(rootChaintimeSlotsroles.listroles.rules)为 JSON 文本字段,triggerCodes 为逗号分隔文本字段。非法草稿(JSON 解析失败、链尾不合规、分时行畸形)会阻止保存——区块绝不写入损坏配置。

版本要求/settings 的 fallbacks 区块需要 dsh-tui ≥ v0.8.5main 上 commit c51661f 及以后;settings seam 于 v0.8.0 引入,groups 结构与校验于 v0.8.5 引入)。更旧的 dsh-tui 没有该区块,文件编辑仍是 TUI 唯一编辑面。

文件编辑在任意情况下仍然可用:全局设置写共享的 $DSH_HOME/settings.yamlfallbacks: 分节——与 Web 卡写的是同一个文件);dsh-tui 专属覆盖写 profile patch ~/.dsh/profiles/dsh-tui/cordis.patch.yml(插件行上的 config: 覆盖)。注意:patch 行会整体替换目标行的整个 config——想保留的字段都要写全(schema 默认值补齐其余)。

模型选择器中的 FallbacksChain

enabled: true 时,插件注册一个虚拟 provider FallbacksChain,目录中只有一行:Auto。web profile 与 dsh-tui 都能看到这一行:两者共享同一个 adapter catalog,无需设置页接线或宿主补丁(它与 /settings 的 fallbacks 区块相互独立——区块编辑的是配置,不是选择器目录)。该行只要插件启用就可见——遗留多模型或空的 all-day 链不会隐藏它(只是覆盖不会生效)。

选择 FallbacksChain / Auto = 把配置的链作为 root 主模型:root 请求路由到请求时刻生效链的第一个精确 provider/model,失败后由降级引擎从该链头照常沿链切换。选择任何真实目录模型则保持 v0.2.2 的 fallback-only 行为——会话模型为主,链只在它失败后介入。

没有 rootMode 开关——没有配置键、YAML 字段、设置开关或 gateway 标志。模式就是会话的 {provider, model} 选择本身:FallbacksChain = 链为主模型;任意真实模型 = fallback-only。

注意:

  • 选择器文案:目录行的 name(composer 触发器显示)是动态的——Auto: DeepSeek V4 Flash[Liang Peak] / Auto: DeepSeek V4 Flash[all-day](用 catalog 显示名,不是 model id);id 仍是 Auto。all-day 尾巴不合规则只显示 Auto。重新打开选择器即可刷新。
  • 仅 root:这一行只关乎 root 代理。subagent 的角色解析与注入不变;继承了该选择的 subagent 会话仍经链头路由——虚拟行只是薄委托,绝不是第二个路由引擎。
  • 链尾合规门槛:覆盖/委托成功要求 all-day 链尾巴合规——最后一项必须是恰好一个官方 V4 模型(deepseek-official/deepseek-v4-flashdeepseek-official/deepseek-v4-pro,即设置卡的「默认模型」面板);前面的默认降级链先走。禁用插件后该行隐藏(slot/链编辑不会触发注册抖动)。
  • 过期选择:行消失(插件禁用)而会话仍选中 FallbacksChain / Auto 时,会话继续把它显示为当前模型,但 routable: false——从目录选一个真实模型即可继续(宿主原生目录语义)。
  • 能力跟随链头:该行的模型元数据(上下文窗口、模态、推理)镜像当前生效链头;重试归属保持宽松默认——重试/失败记到被委托的真实链头,而非 FallbacksChain provider。完整语义 → [docs/configuration.md](docs/configuration.md)。

分时槽预设(分时切换)

峰谷无忧在[首页专题](#峰谷无忧)中介绍,本节是完整参考。分时槽行按墙钟窗口轮换生效 root 链——适合按峰谷切换模型,且不会把墙钟轮换误认为故障降级。文案严格区分:时段轮换的日志与 UI 用分时切换;失败降级保持降级切换;会话内「模型已降级」提示只出现在失败路径。

  • 匹配顺序:每个 root 请求时刻,第一条窗口包含当前时刻(按 fallbacks.tz,默认 Asia/Shanghai / UTC+8)的额外行生效——该行的模型链取代全时段链;无行命中则用全时段 rootChain。全时段行固定最后且必选:最后一项必须是恰好一个官方 V4 模型(Flash 或 Pro;前面的降级条目先走)。
  • 预设(冻结,不可编辑窗口):liang-peak = 每天 09:00–12:00 14:00–18:00;liang-valley = 其它所有 UTC+8 时间;glm-peak = 周一至周五 14:00–18:00;glm-valley = 其余时间。一个预设 id 对应一行;设置卡的选择器不会重复提供已添加的预设。
  • 自定义行start / endHH:mm,可跨午夜)+ 可选 days(0=周日…6=周六;缺省/空 = 每天)+ 模型。
  • 下一请求生效:时段边界跨越绝不打断进行中的 step——新行在下一个 root 请求生效。轮换仅挂载生效:info 日志 + 设置卡//fallbacks 状态行,无 durable 切换事件。
  • 设置卡:主代理区块下分三块——分时槽设置(额外行:添加预设 / 添加自定义 / 删除 / 按钮或拖拽排序;预设行只读展示窗口摘要、仅可编辑模型链;自定义行带可编辑名称;时区选择器在此区块内,只要存在预设行就锁定 Asia/Shanghai——预设窗口是冻结的 UTC+8 常量)、默认降级链(all-day 链,可配置的 provider/model 选择器列表)与默认模型(官方 V4 Flash | Pro 二选一链头)。行可折叠为「名称 + 首个模型」。没有 timeSlots.enabled 总开关(添加行即开启),也没有 rootMode 控件。

预设角色(Preset roles)

插件内置 7 个通用子代理角色,开箱即用——designer / librarian / reviewer / scout / security-reviewer / sonic / task——apply 时自动以 seeded roles.list 行({ id, persona })声明:幂等,且绝不覆盖 operator 同名 persona。它们出现在设置卡的 seed 徽标(id 不可改)与 /fallbacks config 的角色摘要中,可直接被 roles.rules 引用。

  • 开关fallbacks.presets——'bundled'(默认)在 apply 时声明预设角色;'none' 关闭自动声明(已物化行保留)。
  • 完整语义(升级行为、冲突处理、presetRoles 库复用)→ [docs/configuration.md](docs/configuration.md)。

纯挂载(零 dsh 修改)

插件以纯挂载方式安装:bundle 行插入 + client inject + 自有 gateway 通道(/api/fallbacks/get|set|reset)——无 dsh 补丁、无 postinstall 步骤,dsh 升级永不需重打。旧版打补丁安装遗留的补丁无害。

文档

文档内容
[docs/install.md](docs/install.md)profile 安装(web + dsh-tui)/ registry / git / 本地目录变体 / 卸载 / --dump-config 验证
[docs/configuration.md](docs/configuration.md)fallbacks 命名空间全字段、selector 语法、示例 YAML、插件配置卡使用、TUI 回读、行为说明、预设角色
[docs/consumer-api.md](docs/consumer-api.md)开发者消费契约:库 API + 具名 llm-fallbacks service + 角色 seeds、导出清单、生命周期、类型说明
[docs/release.md](docs/release.md)发布流程:Trusted Publishing 前置、Release prep SOP、fragment 格式、回滚
[docs/verification.md](docs/verification.md)验证记录(测试矩阵、bundle 层序、运行契约、QA gate 剧本)

许可

本项目以 MIT 许可证发布,全文见 [LICENSE](LICENSE)。版权与许可条款以 LICENSE 文件为准。