{"_id":"@adverts13/dsh-auto-model-router","_rev":"2-b7c171eb0fb22b65098c074abc0fa796","name":"@adverts13/dsh-auto-model-router","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@adverts13/dsh-auto-model-router","version":"0.1.0","keywords":["deepseek-harness","dsh","dsh-auto-model-router","llm","routing","cost-optimization"],"license":"MIT","_id":"@adverts13/dsh-auto-model-router@0.1.0","maintainers":[{"name":"adverts13","email":"sihaoding@163.com"}],"dsh":{"bundle":{"patch":"./cordis.patch.yml"},"client":{"inject":[],"platform":"web"}},"dist":{"shasum":"a64186272c64fc996c8feaab706214c3bfa4e1c5","tarball":"https://registry.npmjs.org/@adverts13/dsh-auto-model-router/-/dsh-auto-model-router-0.1.0.tgz","fileCount":17,"integrity":"sha512-nRPPLKCmDczMhb153Hyq3XDCdwnt1TAQYpl9PsUlvwEGsNPu20EyjzJ2q/Iex9m85JDUUPBmkC8c2o200IxLyA==","signatures":[{"sig":"MEQCICvGDGc07amOD6kuqxMX3TJRKpkhcljSaJFW/uJXwJwAAiBJSbrAWMLRpX/ZbAD+Yadjq9Q0GJd00jxzU5m9dNYekA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":110240},"main":"index.mjs","type":"module","engines":{"node":"^22.19.0 || >=24"},"exports":{".":"./index.mjs","./client":"./client.js","./package.json":"./package.json"},"gitHead":"49f5a3b7b881ff8b4004db3c44bac88fad21603d","scripts":{"test":"node --test *.test.mjs","build:client":"node build-client.mjs"},"_npmUser":{"name":"adverts13","email":"sihaoding@163.com"},"_npmVersion":"10.9.8","description":"Hybrid model router for DeepSeek Harness: declarative rules, user-configurable cost control (cost-first / quality-first / balanced), optional LLM task classifier, and failure fallback chains.","directories":{},"_nodeVersion":"22.23.2","_hasShrinkwrap":false,"devDependencies":{"@deepseek-ai/dsh-llm":"0.1.0-rc.6","@deepseek-ai/dsh-tools":"0.1.0-rc.6"},"peerDependencies":{"@deepseek-ai/dsh-llm":"0.1.0-rc.6","@deepseek-ai/dsh-tools":"0.1.0-rc.6"},"_npmOperationalInternal":{"tmp":"tmp/dsh-auto-model-router_0.1.0_1787210202314_0.03769868218567529","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@adverts13/dsh-auto-model-router","version":"0.1.1","description":"Hybrid model router for DeepSeek Harness: declarative rules, user-configurable cost control (cost-first / quality-first / balanced), optional LLM task classifier, and failure fallback chains.","type":"module","main":"index.mjs","exports":{".":"./index.mjs","./client":"./client.js","./package.json":"./package.json"},"dsh":{"bundle":{"patch":"./cordis.patch.yml"},"client":{"inject":[],"platform":"web"}},"scripts":{"test":"node --test *.test.mjs","build:client":"node build-client.mjs"},"peerDependencies":{"@deepseek-ai/dsh-llm":"0.1.0-rc.6","@deepseek-ai/dsh-tools":"0.1.0-rc.6"},"devDependencies":{"@deepseek-ai/dsh-llm":"0.1.0-rc.6","@deepseek-ai/dsh-tools":"0.1.0-rc.6"},"engines":{"node":"^22.19.0 || >=24"},"keywords":["dsh","dsh-plugin","deepseek-harness","model-router","llm","routing","cost-optimization"],"repository":{"type":"git","url":"git+https://github.com/ADVeRTs13/dsh-auto-model-router.git"},"homepage":"https://github.com/ADVeRTs13/dsh-auto-model-router#readme","bugs":{"url":"https://github.com/ADVeRTs13/dsh-auto-model-router/issues"},"license":"MIT","_id":"@adverts13/dsh-auto-model-router@0.1.1","gitHead":"c77b24941833bf9aa5f3f828c5f3e91e86f8e95d","_nodeVersion":"22.23.2","_npmVersion":"10.9.8","dist":{"integrity":"sha512-GzooMcKcGnh5rzDozFFnJGbZj1WvALIY+rP3DUOPc1X4JHDyxDu020A014+ZR33XLpIHSWki2GmJA7hJBEW99Q==","shasum":"b5a422c31c22d4fe07b200443aaad8b8e0221bb6","tarball":"https://registry.npmjs.org/@adverts13/dsh-auto-model-router/-/dsh-auto-model-router-0.1.1.tgz","fileCount":17,"unpackedSize":110620,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIH94XFwL4VLres9sNSC/z7PA6pWbSjJY+XHfFgIC9y2oAiBTLDBnPX1P8neBNSAmncEGu+ykGjhRWvv3euGbTgDOvg=="}]},"_npmUser":{"name":"adverts13","email":"sihaoding@163.com"},"directories":{},"maintainers":[{"name":"adverts13","email":"sihaoding@163.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dsh-auto-model-router_0.1.1_1787212164711_0.11630100897337003"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-20T07:16:42.088Z","modified":"2026-08-20T07:49:24.962Z","0.1.0":"2026-08-20T07:16:42.462Z","0.1.1":"2026-08-20T07:49:24.840Z"},"license":"MIT","keywords":["dsh","dsh-plugin","deepseek-harness","model-router","llm","routing","cost-optimization"],"description":"Hybrid model router for DeepSeek Harness: declarative rules, user-configurable cost control (cost-first / quality-first / balanced), optional LLM task classifier, and failure fallback chains.","maintainers":[{"name":"adverts13","email":"sihaoding@163.com"}],"readme":"# dsh-auto-model-router\n\n一个适配 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)（DSH）的混合式自动模型路由插件。通过 **L0–L3 四个能力层级**为每个 agent 请求选择模型——日常问答、代码测试、编写审查、复合多步任务——支持用户可配置的成本策略、可选的 LLM 任务分类器、以及失败降级链。\n\n> 设计思路参考 [open-world-project/model-router](https://github.com/open-world-project/model-router)（Hermes Agent）与 [opencode-model-router](https://github.com/marco-jardim/opencode-model-router)（fast/medium/heavy 分层）：层级化路由 + 成本模式决定模糊时的偏移方向。\n\n## 致谢\n\n本插件的思路来自以下开源项目：\n\n- [open-world-project/model-router](https://github.com/open-world-project/model-router) — Hermes Agent 的自动模型路由器，含关键词评分和成本感知分层选择\n- [opencode-model-router](https://github.com/marco-jardim/opencode-model-router) — OpenCode 的 fast/medium/heavy 分层委托插件\n- [openclaw-routing-yaml](https://github.com/glasshousehq-os/openclaw-routing-yaml) — OpenClaw 的声明式 YAML 按任务路由\n- [openmarkai/openclaw-router](https://github.com/openmarkai/openclaw-router) — 基于基准测试驱动的模型路由\n- [MoeAisaka/openclaw-model-policy-router](https://github.com/MoeAisaka/openclaw-model-policy-router) — OpenClaw 的策略驱动 fail-closed 路由\n- [NanmiCoder/dsh-auto-mode](https://github.com/NanmiCoder/dsh-auto-mode) — DSH 的自动权限模式；客户端设置页实现参考\n- [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) — 本插件所适配的宿主平台\n\n- [English](README.md)\n- 中文（本文档）\n\n## 工作原理\n\n```\n用户消息\n  │\n  ▼\n① agent/pre-step         任务文本 + token 记账\n  │\n  ▼\n② system-prompt/assemble 让 {{model}} 与路由结果保持一致\n  │\n  ▼\n③ agent/request   ★ 决策点：\n  │\n  ├─ Tier 1 规则：        子串 / 正则匹配 → 层级（L0…L3）——永远优先\n  ├─ Tier 2 成本：        预算耗尽 → 钉到最便宜层级；\n  │                      未命中规则 → 模式决定默认层级\n  ├─ Tier 3 分类器：      可选便宜 LLM → 层级；层级缺模型 → 按模式漂移\n  └─ Tier 4 降级：        请求失败 → 沿链切换模型并重试\n  │\n  ▼\nLLM 分发\n```\n\n### 四个层级\n\n| 层级 | 典型任务 | 模型建议 |\n| --- | --- | --- |\n| `L0` | 日常问答、快速回答 | 最便宜/最快 |\n| `L1` | 小改动、简单测试 | 普通 |\n| `L2` | 写代码、审查、重构 | 较强 |\n| `L3` | 复杂 BUG 修复、多步任务、汇报 | 最强 |\n\n每个层级是一个用户自行指定的 provider/model 路由，**必须**附带\n`reasoningEffort`（省略时默认 `off`）：`off` = 无思考模式，`high`/`max` =\n思考强度。层级可以留空不配置；路由会落到最近的已配置层级（方向由成本模式决定）。\n\n## 模型选择框中的 Auto 模式\n\n插件注册了一个虚拟的 `auto` provider，模型选择框会出现 **Auto Router** 分组，\n内含一个 **Auto** 模型：\n\n```\nAuto Router\n  └─ Auto\ndeepseek-official\n  ├─ deepseek-v4-flash\n  └─ deepseek-v4-flash\n```\n\n- 选 **Auto** → 插件接管，按 L0–L3 层级自动路由。\n- 选**具体模型** → 插件原样放行，你手选的模型优先，路由不干预。\n\n### 设置界面页签（浏览器端）\n\n浏览器端会在 DSH 设置面板（齿轮图标 → 侧栏）注册一个 **Auto Router**\n页签，展示当前路由策略——即 host 在会话开始时注入的\n`<dsh-auto-model-router-status>` 状态报告——并附提示文案：如需修改配置，\n直接在对话中告诉 AI（例如\"把 L2 改成 deepseek-v4-flash 且 max 思考\"或\n\"成本模式切换为 cost-first\"），AI 会帮你编辑 `cordis.patch.yml`，\n重启 DSH 后生效。\n\n在模型选择框选 **Auto** 立即生效，不再有确认弹窗。\n\n无需额外构建步骤：`client.js` 是本仓库维护的自包含 ModuleLoader bundle\n（`pnpm run build:client` 可从 `client/` 源码重新生成）。\n\n## 安装\n\n```bash\ndsh plugin --profile web add ./dsh-auto-model-router\n```\n\n或通过已发布的 npm 包安装：\n\n```bash\nnpm install @adverts13/dsh-auto-model-router\ndsh plugin --profile web add @adverts13/dsh-auto-model-router\n```\n\n## 配置\n\n在 profile 的 `cordis.patch.yml` 中添加：\n\n```yaml\n- insert:\n    - id: dsh-auto-model-router\n      name: '@deepseek-ai/cordis-plugin-group'\n      group: true\n      isolate:\n        modelRouter: true\n      config:\n        - id: dsh-auto-model-router-runtime\n          name: '@adverts13/dsh-auto-model-router'\n          config:\n            # ── 四个层级（出厂默认）────────────────────────────────────\n            # reasoningEffort：off = 无思考，medium/high/max = 思考强度\n            levels:\n              L0:                              # 日常问答\n                provider: deepseek-official\n                model: deepseek-v4-flash\n                reasoningEffort: off\n              L1:                              # 代码与测试\n                provider: deepseek-official\n                model: deepseek-v4-flash\n                reasoningEffort: medium\n              L2:                              # 编写与审查\n                provider: deepseek-official\n                model: deepseek-v4-flash\n                reasoningEffort: high\n              L3:                              # 复合多步任务\n                provider: deepseek-official\n                model: deepseek-v4-flash\n                reasoningEffort: max\n\n            # 关键词规则仅在全自动模式生效，默认为空\n            rules: []\n\n            # ── 模式A：字符统计锁（零延迟）────────────────────────────\n            heuristic:\n              windowSize: 3        # 统计最近 N 次用户输入\n              counting: cjk2       # 中文计2字符/其他计1；可选 tokens\n              thresholds:          # 宽度 → 层级（用户可改）\n                - maxChars: 10\n                  level: L0\n                - maxChars: 100\n                  level: L1        # 锁顶；超过 100 弹窗询问用户\n\n            # ── 模式C：关键词积分（全自动）────────────────────────────\n            scoring:\n              weights:             # 每次命中积分（按层级）\n                L1: 1\n                L2: 2\n                L3: 3\n              bands:               # 积分 → 层级（用户可改）\n                - maxScore: 0\n                  level: L0\n                - maxScore: 5\n                  level: L1\n                - maxScore: 15\n                  level: L2\n                - maxScore: null\n                  level: L3\n\n            # ── Tier 2：成本控制（用户可配置）─────────────────────────\n            costControl:\n              enabled: true\n              mode: balanced        # cost-first | quality-first | balanced\n              defaultLevel: L1      # 未命中规则时使用的层级\n              tokenBudgetPerSession: 0   # 0 = 不设预算（默认）；\n                                        # 设置正值即按会话封顶\n              # 会话预算耗尽时的行为：\n              #   silent  — 静默切到最便宜层级（不告知用户）\n              #   notify  — 注入用户可见消息说明降级原因\n              #   ask     — 弹窗询问；用户可选\"继续用当前模型\"\n              #             （本会话豁免预算）\n              downgradeBehavior: notify\n\n            # ── LLM 分类器（全自动模式兜底；默认开启）───────────────────\n            llmClassifier:\n              enabled: true\n              model:\n                provider: deepseek-official\n                model: deepseek-v4-flash\n              requestTimeoutMs: 10000\n\n            # 固定层级模式每 N 次用户输入重新弹窗询问\n            askEveryInputs: 3\n\n            # ── Tier 4：失败降级链（模型级）───────────────────────────\n            fallbackChain:\n              - provider: deepseek-official\n                model: deepseek-v4-flash\n\n            maxRetries: 1\n```\n\n### costControl 三种模式\n\n| 模式 | 默认层级（未命中规则） | 模糊时偏移方向 |\n| --- | --- | --- |\n| `cost-first` | 最低已配置层级 | **向下**（更便宜） |\n| `quality-first` | 最高已配置层级 | **向上**（更强） |\n| `balanced` | `costControl.defaultLevel` | 不动 |\n\n规则命中永远优先于成本模式：用户显式匹配到的层级不会被成本层降级。\n\n### 预算降级可见\n\n`tokenBudgetPerSession` **默认为 0（不设预算）**——成本层不会因预算耗尽而强制\n降级，`downgradeBehavior` 此时不生效。设置一个正值即可开启按会话封顶：\n\n- 例如 `tokenBudgetPerSession: 300000`：会话用满 30 万 token 后降级。\n- 降级行为由 `downgradeBehavior` 控制（默认 `notify`）：\n  - `notify`：注入一条用户可见消息，说明预算耗尽、剩余请求使用哪个模型、\n    如何调高上限。\n  - `ask`：弹窗询问\"切到便宜模型还是继续用当前模型\"；选\"继续\"则本会话\n    豁免预算。\n  - `silent`：静默切换（不推荐——用户会疑惑回答质量为何变化）。\n\n### 加载时询问（无需客户端界面）\n\n安装或热插拔插件后的**第一个会话**，DSH 会：\n\n1. 注入一条状态汇报消息（当前层级→模型映射、成本模式、预算、降级链）。\n   语言跟随 `settings.yaml` 的 `locale.preference`（`zh`/`en`，默认 `en`）。\n2. 弹窗询问三个问题（每轮插件加载只问一次）：\n\n| 问题 | 选项 |\n| --- | --- |\n| Q1 匹配规则 (T1) | 保持现有规则 / **查看现有规则**（注入规则清单） |\n| Q2 成本模式 (T2) | 保持当前 / cost-first / balanced / quality-first（选择立即生效） |\n| Q3 其他配置 | 跳过 / **检查某项配置**（输入 budget、fallbackChain、classifier 等，注入当前值） |\n\nQ1/Q3 注入的清单与当前值让用户**决定**是否调整；持久修改仍落在\n`cordis.patch.yml`（消息中会说明）。headless 或无可询问通道时自动降级为\n只汇报、不询问，不会阻塞。\n\n## 规则语法\n\n- 纯文本：`match: 'refactor'` —— 大小写不敏感的子串匹配。\n- 正则字面量：`match: '/\\\\bdebug\\\\b/'` —— 首尾斜杠界定正则，末尾可加标志（如 `/.../i`）。\n- 规则**按顺序**求值，第一个命中生效。\n- `match` 可匹配用户消息文本、工具调用结果文本，或会话 `cwd`（以 `cwd:<path>` 匹配）。\n\n## 挂载点\n\n| DSH 事件 | 作用 |\n| --- | --- |\n| `agent/session-start` | 重置每会话路由状态 |\n| `agent/pre-step` | token 记账（预算跟踪） |\n| `system-prompt/assemble` | 保持 `{{model}}` 提示词变量一致 |\n| `agent/request` | **路由决策点** —— 替换 provider/model |\n| `agent/request-error` | 降级链 → `{ kind: 'retry' }` |\n| `session/event` | 从 assistant 消息统计 token 消耗 |\n\n## 测试\n\n```bash\nnpm test        # node --test *.test.mjs\n```\n\n无需外部服务——所有层级均以 fixture 做单元测试。\n\n## 已知问题\n\n- **全自动模式延迟**：开启 LLM 分类器后，每个新用户输入的第一步会增加一次分类器调用（LLM 请求）。虽然同一输入内的后续步骤已缓存、无额外开销，但多步任务的整体响应时间仍比直接选择模型慢。欢迎贡献优化方案——例如跨会话缓存分类结果，或用轻量启发式作为 LLM 分类的前置过滤。\n\n## License\n\nMIT\n","readmeFilename":"README.zh.md","homepage":"https://github.com/ADVeRTs13/dsh-auto-model-router#readme","repository":{"type":"git","url":"git+https://github.com/ADVeRTs13/dsh-auto-model-router.git"},"bugs":{"url":"https://github.com/ADVeRTs13/dsh-auto-model-router/issues"}}