← 返回列表
未验证
删除会话、注入请求头并配置模型自动回退链
尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/9/1 · 已提供中文文档
DSH(DeepSeek Harness)功能增强插件
综合分
28.4
GitHub 分
28.4
用户评分
—
★ Stars
0
周下载量
—
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add rangdl/dsh-all-enhance该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
数据截至 2026/9/16(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
依赖的 DSH / Cordis 模块
@deepseek-ai/dsh-settings@deepseek-ai/dsh-storage-domain@deepseek-ai/schemastery@deepseek-ai/cordis用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动
README
dsh-all-enhance
npm
npm downloads
license
node
dshfind
DSH(DeepSeek Harness)功能增强插件:会话删除、模型请求头、模型回退链 —— 三大功能均可在 Web 设置页的「增强设置」分区中开关与配置。
快速安装
需要 dsh(DeepSeek Harness),一条命令安装到目标 profile(如 web),重启后生效:
dsh plugin --profile web add dsh-all-enhance
推荐固定稳定版本,避免后续发布悄悄改变实际运行的代码:
dsh plugin --profile web add dsh-all-enhance@latest
安装后:Web 端进入「设置 → 插件配置 / 增强设置」即可开关与配置三大功能(会话删除、模型请求头、模型回退链)。更详细的安装方式见 安装。
功能
会话删除
在会话列表的更多操作菜单中新增「删除会话」:
- 冷会话(未运行)永久删除本地记录:日志文件与工作区账目一并清理,侧栏行即时移除。
- 运行中会话拒删:服务端 409 + TOCTOU 二次复核,绝不误删正在跑的任务。
- 删除需二次显式确认;目录移除带会话 ID 名称护栏,防止 DSH 布局变化时误删无关目录。
模型请求头
为出站模型请求注入自定义请求头(如 User-Agent),保存在插件自己的设置命名空间(不写入 llm-pi-ai,任意渠道含官方内置都可配置):
- 优先级:按模型(键 提供方/模型)> 按提供方 > 全局,同名请求头大小写不敏感覆盖。
- 注入范围:对话流、「获取可用模型」探测、底层 fetch 全覆盖,经 AsyncLocalStorage 贯穿整条请求链路。
- 内置 User-Agent 预设(claude-cli / claude-code 等)可选填,仍可自由编辑。
- 总开关关闭时零注入;保存前校验请求头名(RFC 9110 token)与值(无换行,防 CRLF 注入)。
模型回退链
对话请求失败时自动切换到链中的下一个模型继续,无需手动换模型:
- 触发:失败码命中触发码即回退。默认含鉴权无效 / 配额耗尽 / 限流 / 连接断开(TRANSPORT)/ 流空闲超时(TIMEOUT);流中断同样覆盖,用户主动中止不触发。
- 多链 + 虚拟路由:每条链注册为虚拟路由,在模型选择器中显示为 EnhanceChain/,选中即以该链为主模型;内置 auto 链自动聚合全部已注册提供方并置于链首,同时是普通模型失败时的默认回退链。
- 链编辑:链目从模型目录下拉选择(提供方/模型,支持 通配)或手动输入;每条目可上下调序。链 id 支持字母开头 + . _ - 数字。
- 稳定性:失败路由冷却抑制(定时解禁,或半开探测指数升级至 16 倍);每 step 切换次数上限防抖动。
- 可观测:切换事件 toast 实时提示(SSE 推送,流不可用降级共享轮询);运行状态面板展示冷却快照与切换历史。
- 调用记录(可选 fallbacksLogEnabled):记录每次失败的失败码、响应消息与回退目标(回退关闭时也记录),附失败码统计直方图,一键加入触发码便于调优;经 storageDomain 域持久化,重启不丢。
- 回退决策状态纯内存,不写会话日志。
安装
作为带 dsh.bundle patch 层的组合包:
dsh plugin --profile add dsh-all-enhance
或从源码检出(使用 pnpm dsh):
pnpm dsh plugin --profile add ./dsh-all-enhance
组合包注册一条 Cordis 配置项(id: all-enhance),同时挂载 Host 半侧与 Web 客户端半侧。
本机免 pnpm 安装(pnpm 受限环境)
当 dsh plugin add(内部走 pnpm)不可用时,可直接手工安装(无需删除任何东西):
1. 把插件以包名链接进 profile 的 node_modules(junction,跟随源码改动)
替换为本机 dsh-all-enhance 源码检出目录
node -e "require('fs').symlinkSync('', process.env.USERPROFILE + '/.dsh/profiles/web/node_modules/dsh-all-enhance', 'junction')"
2. 在 profile 的 cordis.patch.yml 追加(用包名,client 半侧才会被发现):
- insert:
- id: all-enhance
name: dsh-all-enhance
3. 直接启动(不要再叠加 --patch,否则 duplicate entry id)
dsh web
注意:name 填文件路径(如 file:///.../src/index.js)只加载 Host 半侧,客户端模块系统按"包"扫描 dsh.client 声明,路径加载时 UI 不会注入;必须用包名加载才带 UI。
工作原理 / API 面
插件尽量只使用官方公开服务接口;两处官方私有实现(attached 会话从 SessionStore
内存 detach、session_projcache 表清理)以能力探测的方式穿透,DSH 升级改结构
时自动降级为 409 拒删,不会崩溃:
| 关注点 | 使用的公开 API |
|---|---|
| 设置命名空间注册 | @deepseek-ai/dsh-settings 的 installSettingsSection()(生命周期托管) |
| 运行中会话检测 | ctx.sessions.get(id)(SessionStore) |
| 会话存在性 | ctx.sessionPersistence.list() |
| 日志文件定位 | ctx.sessionPersistence.locate(header) —— 由后端解析物理路径,无需手写路径编码 |
| 工作区账目 | ctx.workspaceRegistry.list() + Workspace.detachSession(id) |
| HTTP 路由 | ctx.webServer.register()(包在 ctx.effect() 内,卸载自动注销) |
| 设置写入(客户端) | api.settings.mutate 携带 expectedRevision + 冲突重试 |
| 请求头注入 | 自有设置命名空间 + ctx.on('llm/stream') + 作用域化 fetch / ctx.llm.discoverModels 包装(ctx.effect 托管,卸载还原) |
| 回退决策 | ctx.on('agent/request-error') → { kind: 'retry' },pending 切换在 ctx.on('agent/request') 应用,per-agent 状态随 agent/disposed 清理 |
| 虚拟链路由 | ctx.llm.registerAdapter(['EnhanceChain'], …) —— 每条链一行 listModels,stream() 薄委托到链 head |
| 回退运行状态 | GET /dsh-all-enhance/fallbacks/status(冷却快照 + 切换历史,仅内存) |
| 回退调用记录 | GET/DELETE /dsh-all-enhance/fallbacks/log —— 失败观测日志(环形 200 条,storageDomain 域持久化,服务不可用降级纯内存) |
| 模型目录 | GET /dsh-all-enhance/fallbacks/models —— 聚合 ctx.llm.listProviders() + listModels(),链编辑器下拉框数据源 |
| 回退状态推送 | GET /dsh-all-enhance/fallbacks/events(SSE)—— 切换/冷却变更时推送快照;流不可用降级共享轮询(约 5 秒,连续失败指数退避) |
安全
- 删除/状态路由仅接受本机回环请求:Host + sec-fetch-site + origin 校验拒绝跨站请求(CSRF / DNS rebinding 防护)。
- POST body 上限 64 KiB,且必须为 application/json。
- 运行中会话绝不删除(服务端 409;客户端在弹确认框前先查状态)。
- 冷会话删除不可恢复;UI 要求二次显式确认。
- 请求头保存前做校验:名称必须是 RFC 9110 token,值不得含换行(防 CRLF 头注入)。
兼容性与已知限制
- 需要服务:webServer、settings、workspaceRegistry、sessionPersistence、sessions。
- Web 客户端目前对设置页导航与会话列表菜单没有官方扩展 slot;客户端使用内部哈希类名(.VOzbGW_、.YDXeBa_)与 React fiber 探测做 DOM 注入,DSH UI 升级可能需要维护选择器。可迁移的官方 slot:settings.plugin.item、conversation.chat.node。
- 归档集无公开 unarchive API(archivedSessionIds 只增不减):删除已归档会话后归档集保留失效 id。
- 进程内 header 索引缓存无公开清理 API:删除后由重启 bootstrap 自愈。
- locate() 只返回主日志产物;compaction snapshot 等后端附加产物不在公开接口内,不清理。
- 模型回退链依赖当前 DSH 的 agent/request-error / agent/request 事件契约与 ctx.llm.registerAdapter;宿主升级若调整失败码或适配器注册机制可能需要插件跟进(未知失败码不会触发回退,安全降级)。
- 流中断回退覆盖适配器层失败(连接断开、空闲超时 —— 归一为 TRANSPORT/TIMEOUT finish chunk)。llm/stream 管道内消费者/中间件层失败会完全绕过 agent/request-error,在宿主循环中即为终态 —— 任何插件都无法恢复。
- 切换 toast 优先走 SSE 推送;流不可用时客户端降级为约 5 秒的共享轮询,通知最多延迟一个轮询周期。
参考项目
- btspoony/dsh-llm-fallbacks(MIT)— 回退链的决策内核参考:agent/request-error 接管恢复、冷却抑制与 half-open 恢复的机制均源于此(本插件剥离了其角色/时段/subagent 策略,并对齐 dsh 0.1.1-rc.2 的失败码与事件契约;其 issue #52 的会话事件坑位也在本插件规避)。
- dsh-custom-provider-settings(社区插件)— 请求头注入链路参考:llm/stream 事件 + AsyncLocalStorage + fetch 包装的同构实现(本插件 TS 化并改为自有设置命名空间,runtime key 亦区分,两者可共存)。
- dsh-market — 构建方式镜像:tsc 编译 host + tsdown 打包 client、结构化服务子集类型与 bundle/patch 层组织方式。
- deepseek-ai/deepseek-harness — 宿主框架(DSH)官方仓库。
开发
源码为 TypeScript,构建方式镜像 dsh-market
(tsc 编译 host + tsdown 打包 client):
src/
├── host/ # Host 半侧(TypeScript,tsc 编译 → lib/)
│ ├── index.ts # 插件入口 apply(装配以下模块)
│ ├── ctx.ts # 结构化服务子集类型(含两处私有穿透成员)
│ ├── constants.ts # 常量 + 设置 schema(settings 命名空间)
│ ├── http.ts # HTTP / CSRF 工具
│ ├── delete-session.ts # 会话删除流水线(detach/清理/护栏)
│ ├── request-headers.ts # 请求头注入桥(全局 + 按提供方/按模型覆盖)
│ ├── fallbacks.ts # 回退链聚合入口(re-export)
│ ├── fallbacks-decision.ts # 回退决策内核(配置裁剪/链解析/状态机纯函数)
│ ├── fallbacks-bridge.ts # 回退事件桥(agent 事件 + 调用记录 + 状态快照)
│ ├── virtual-adapter.ts # 虚拟 EnhanceChain 适配器(registerAdapter)
│ ├── call-log-store.ts # 调用记录持久化(storageDomain 域存储)
│ └── routes.ts # HTTP 路由(删除/状态/回退/status/log/models/events)
├── client/ # 客户端源码(TypeScript,tsdown 打包 → client/client.js)
│ ├── index.ts # 入口 apply(settingsScope bind / slots / 菜单注入)
│ ├── types.ts # 客户端结构化 context 类型
│ ├── selectors.ts # 常量与官方 UI 选择器
│ ├── locales.ts # 中英文案字典 + makeT(键受 Dict 接口约束)
│ ├── toast.ts # toast 提示
│ ├── dialog.ts # 删除确认对话框
│ ├── shared-styles.ts # 共享样式常量
│ ├── collapsible.ts # 折叠卡片组件(设置分区用)
│ ├── settings-section.ts # 「增强设置」分区组件(settings.section slot)
│ ├── session-menu.ts # 会话菜单注入(DOM hack)
│ ├── delete-flow.ts # 删除流程(status → confirm → delete → refresh)
│ ├── request-headers-editor.ts # 请求头编辑器(全局/提供方/模型三层)
│ ├── fallbacks-editor.ts # 回退链编辑器(多链 + 直方图 + 运行状态)
│ ├── fallbacks-poll.ts # 共享状态 feed(SSE 优先/轮询降级)
│ ├── fallbacks-notify.ts # 回退切换 toast(历史差量)
│ └── styles.ts # 注入样式
├── lib/ # 构建产物(tsc:host 编译 JS + .d.ts,gitignore,由 prepare/build 生成)
└── client/client.js # 构建产物(tsdown:__ModuleLoader__ 单 bundle,提交——loader 契约,须字节稳定)
pnpm install # prepare 会自动跑 pnpm build
pnpm typecheck # tsc 两项目类型检查(host + client)
pnpm build # tsc 编译 host → lib/ + tsdown 打包 client → client/client.js
pnpm test # node --test(75 个用例:manifest/删除/请求头/回退链/路由/持久化/一致性)
pnpm check # typecheck + build + test + preflight(发布前全量门禁)
客户端受 dsh 模块系统限制(/plugins//client.js 单文件加载),源码拆分后
用 tsdown 打包成单 bundle(与官方 client 包 src→lib 构建一致,产物为
window.__ModuleLoader__.load({ id, factory }) 工厂格式,由
scripts/normalize-client-banner.mjs + scripts/preflight.mjs 保证契约)。
lib/ 不入库(gitignore):克隆后先 pnpm install(prepare 自动构建)或 pnpm build,
否则 Host 半侧(main: lib/index.js)无法加载。改动 src/*/.ts 后运行 pnpm build 再重启 dsh。
问题记录见 FIX-PLAN.md,合规审查见 QA-REVIEW.md。扫码进群