@ljwei-stak/dsh-model-router 0.21.1 → 0.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  A cost-aware model-routing workbench for **DeepSeek Harness Desktop**. Plan locally, compare configured routes, inspect execution permissions, and run dependent work packages through model APIs or supported official vendor CLIs.
6
6
 
7
- Current version: **0.21.1** (`@ljwei-stak/dsh-model-router`). Hermes source installs now honor the shared install root without relocating existing user data, and the interactive terminal appears first on the official-tools page. This follows the Hermes/Pi integration and OpenCode V2 package update in 0.21.0. Compatibility remains **DeepSeek Harness Desktop 0.2.0-rc.1 / 0.2.0-rc.2 / 0.2.1-rc.2**. Hermes and Pi do not yet have verified managed runners; real vendor execution evidence remains tied to **0.20.0**, with no new model experiments in this release. The router and [GAL](https://github.com/Alice-Marx/deepseek-harness-galgame) have been independent plugins since 0.12.0.
7
+ Current version: **0.22.1** (`@ljwei-stak/dsh-model-router`). Choose algorithm recommendations or manually assign each decomposed package to an exact model API or official tool, preserving dependencies, refreshed cost previews and retry targets. Routing now supports task-specific quality evidence, joint model/effort selection, historical P90 resource estimates and dependency-aware search. Manual mixed execution is read-only; tools use their configured default model, while the existing editable official-team workflow remains available. Compatibility remains **DeepSeek Harness Desktop 0.2.0-rc.1 / 0.2.0-rc.2 / 0.2.1-rc.2**, including Hermes/Pi installation and terminal support; neither has a verified managed runner yet. Real vendor execution evidence remains tied to **0.20.0**, with no new model experiments in this release. The router and [GAL](https://github.com/Alice-Marx/deepseek-harness-galgame) have been independent plugins since 0.12.0.
8
8
 
9
9
  Official CLI teamwork runs packages sequentially with dependency context and no automatic model-directory API fallback. Editable teams explicitly choose the Harness sandbox or the vendor CLI's normal environment. In the latter, Git worktrees collect edits but do not restrict OS access. CLIs retain their configured model unless explicitly mapped. See [real Windows validation and its limits](docs/releases/0.20.0-validation.md).
10
10
 
@@ -40,16 +40,16 @@ Generating a route recommendation is local: it does not start a vendor CLI or ma
40
40
  Open **Plugins → Add plugin** and enter:
41
41
 
42
42
  ```text
43
- @ljwei-stak/dsh-model-router@0.21.1
43
+ @ljwei-stak/dsh-model-router@0.22.1
44
44
  ```
45
45
 
46
- Use the official HTTPS npm source `https://registry.npmjs.org/` when a mirror lacks that exact version. Enable the plugin, then fully quit Harness (including its tray process) and restart it. Plugin details should show **0.21.1** and the sidebar should contain **模型路由** (Model Router). A global `npm install -g` alone does not register a Desktop plugin.
46
+ Use the official HTTPS npm source `https://registry.npmjs.org/` when a mirror lacks that exact version. Enable the plugin, then fully quit Harness (including its tray process) and restart it. Plugin details should show **0.22.1** and the sidebar should contain **模型路由** (Model Router). A global `npm install -g` alone does not register a Desktop plugin.
47
47
 
48
48
  You can instead install a local `.tgz` archive or its extracted inner `package` directory through the plugin manager. Both must contain `package.json` and `.dsh-plugin`. See [releases](https://github.com/Alice-Marx/dsh-model-router/releases) for archived builds, or build your own checkout below.
49
49
 
50
50
  ### Upgrade from the old package name
51
51
 
52
- The old name `@ljwei-stak/model-router-galgame` ended at 0.13.0. Remove that plugin entry while retaining your profile/application data, then add `@ljwei-stak/dsh-model-router@0.21.1`. Do not keep both entries installed: they share the internal plugin id `model-router-galgame` and tool names. The retained id lets existing router settings and history carry over.
52
+ The old name `@ljwei-stak/model-router-galgame` ended at 0.13.0. Remove that plugin entry while retaining your profile/application data, then add `@ljwei-stak/dsh-model-router@0.22.1`. Do not keep both entries installed: they share the internal plugin id `model-router-galgame` and tool names. The retained id lets existing router settings and history carry over.
53
53
 
54
54
  For the combined 0.11.x package, back up the profile and export the GAL saves you want to preserve before upgrading. Story playback, artwork, music and saves now belong to the independent `@ljwei-stak/dsh-galgame` package. The detailed save limitations are in [MIGRATION.md](docs/archive/MIGRATION.md).
55
55
 
@@ -317,49 +317,66 @@ Coding-plan keys and endpoints stay in Harness provider settings. A `plan-key` p
317
317
 
318
318
  A valid CLI-reported USD amount, including explicit zero, wins over token-price calculation. Otherwise, token-based CLI accounting requires complete normalized usage, known nonnegative prices, and a reported actual model matching the priced route or its explicit CLI mapping:
319
319
 
320
- ```text
321
- actualUsd = (inputTokens × inputPrice + outputTokens × outputPrice
322
- + cacheReadTokens × cacheReadPrice
323
- + cacheWriteTokens × cacheWritePrice) / 1,000,000
320
+ <!-- formula:actual-cost -->
321
+ ```math
322
+ C_a = \frac{I_u p_i+O p_o+R p_r+W p_w}{10^6}
324
323
  ```
325
324
 
325
+ `C_a` is `actualUsd`; `I_u`, `O`, `R`, and `W` correspond to `inputTokens`, `outputTokens`, `cacheReadTokens`, and `cacheWriteTokens`. `p_i`, `p_o`, `p_r`, and `p_w` are the matching input, output, cache-read and cache-write prices in USD per million tokens.
326
+
326
327
  These ledger counters are disjoint after adapter normalization; do not add cached tokens to an inclusive input count. Missing optional cache prices use the input price. Incomplete usage, absent prices or unknown/unmatched identity keep the amount `null`, not zero. Complete terminal evidence can survive a failed/cancelled/timed-out run; partial events are marked `usageIncomplete`.
327
328
 
328
- For example, a complete API result with 1,000 uncached input tokens at $1/million and 500 output tokens at $5/million costs $0.0035. A subscription result can show that amount as `referenceCostUsd` while `costUsd` stays null; reference cost is not added to API spending. A provider-reported $0 is explicit evidence for that attempt, not proof that earlier unknown attempts were free. Actual provider bills are authoritative. No automatic API fallback in official-team mode prevents a router fallback; a vendor CLI may still use its own configured API credentials.
329
+ For example, a complete API result with 1,000 uncached input tokens at \$1/million and 500 output tokens at \$5/million costs \$0.0035. A subscription result can show that amount as `referenceCostUsd` while `costUsd` stays null; reference cost is not added to API spending. A provider-reported \$0 is explicit evidence for that attempt, not proof that earlier unknown attempts were free. Actual provider bills are authoritative. No automatic API fallback in official-team mode prevents a router fallback; a vendor CLI may still use its own configured API credentials.
329
330
 
330
331
  <a id="routing"></a>
331
332
 
332
333
  ## How routing works
333
334
 
335
+ Manual assignment: after planning, choose algorithm recommendations or select an API model / official tool for each package. See the [manual assignment guide](docs/MANUAL_TASK_ASSIGNMENT.zh.md).
336
+
334
337
  The planner is a deterministic local heuristic, not a trained success predictor. It classifies text, estimates complexity, creates suitable analysis/execution/verification/synthesis packages, discovers exact configured routes, overlays profiles, and applies capability/quality constraints. An explicit route bypasses comparison with other routes. Catalog quality/latency/risk hints are experimental priors, not measured success probabilities or live vendor quotes. Execution is currently text-oriented; a vision label does not establish an end-to-end multimodal pipeline.
335
338
 
336
339
  ### Token and price estimate
337
340
 
338
- Base input tokens are `max(80, ceil(text.length / 3.7))`, then adjusted by package-stage multipliers. Base output is 900, adjusted by stage/reasoning effort, with minimum 220. This is a text-length heuristic, not a vendor tokenizer. Let `I` be total estimated input, `R/W` the cached-read/write portions, `O` output, and prices USD per million tokens:
341
+ Without matching resource evidence, base input tokens are `max(80, ceil(text.length / 3.7))`, then adjusted by package-stage multipliers. Base output is 900, adjusted by stage/reasoning effort, with minimum 220. This is a text-length heuristic, not a vendor tokenizer. Sufficient matching, complete history replaces these heuristics with empirical P90 resource estimates, without applying effort or stage multipliers again. Let `I` be total estimated input, `R/W` the cached-read/write portions, `O` output, and prices USD per million tokens:
339
342
 
340
- ```text
341
- C = ((I − R − W) × p_in + R × p_cache_read
342
- + W × p_cache_write + O × p_out) / 1,000,000
343
- costUtility = 1 / (1 + C / C_ref)
343
+ <!-- formula:planning-cost -->
344
+ ```math
345
+ C = \frac{(I-R-W)p_i+O p_o+R p_r+W p_w}{10^6}
344
346
  ```
345
347
 
346
- `C_ref` uses fixed reference prices (input 1, output 5, cache read/write 1 USD/million), not a vendor offer. Fixed scaling prevents an unrelated expensive candidate from flattening all cost penalties. Unknown prices produce a public estimate of `null` and cost utility 0. Internal unconstrained search uses a cost sentinel of 0, but finite-budget assignment excludes unknown-price candidates; the sentinel never means free execution.
348
+ <!-- formula:cost-utility -->
349
+ ```math
350
+ U_c = \frac{1}{1+C/\max(C_{\mathrm{ref}},10^{-12})}
351
+ ```
352
+
353
+ `U_c` is `costUtility`. The price symbols are the same as above. `C_ref` uses fixed reference prices (input 1, output 5, cache read/write 1 USD/million), not a vendor offer. Fixed scaling prevents an unrelated expensive candidate from flattening all cost penalties. Unknown prices produce a public estimate of `null` and cost utility 0. Internal unconstrained search uses a cost sentinel of 0, but finite-budget assignment excludes unknown-price candidates; the sentinel never means free execution.
347
354
 
348
355
  ### Candidate objective and quality floors
349
356
 
350
357
  With normalized quality `q` and normalized latency, specialty, reasoning-fit and risk proxies:
351
358
 
352
- ```text
353
- u = wq × q + wc × costUtility
354
- + wl × (1 − clamp(latency × effortLatency, 0, 1))
355
- + ws × specialty + wr × reasoningFit − wk × risk
356
- − max(0, qualityFloor − q) × criticality
357
- + preferenceAdjustment
359
+ <!-- formula:latency-utility -->
360
+ ```math
361
+ L = \begin{cases}
362
+ \dfrac{1}{1+t/10\,000}, & t\text{ known}, \\
363
+ 1-\min(1,\max(0,\ell e_\ell)), & \text{otherwise}.
364
+ \end{cases}
365
+ ```
366
+
367
+ <!-- formula:candidate-utility -->
368
+ ```math
369
+ u = w_q q+w_c U_c+w_\ell L+w_s s+w_r r-w_k k-\alpha\max(0,f-q)+\Delta_p
370
+ ```
358
371
 
359
- assignmentScore = sum(package utility) − 0.015 × crossRouteDependencyEdges
372
+ <!-- formula:assignment-score -->
373
+ ```math
374
+ S = \sum_{j=1}^{n}u_j - 0.015\sum_{(i,j)\in E}\mathbf{1}[\rho_i\ne\rho_j]
360
375
  ```
361
376
 
362
- Quality uses the task-category LiveBench score when available, then overall LiveBench, then profile/catalog estimates. Public-data refresh is opt-in. Human ratings affect only the bounded `preferenceAdjustment`; they cannot increase objective quality or satisfy its floor.
377
+ `L` is latency utility: `t` is the matching historical P90 duration in milliseconds; otherwise `ℓ` is the latency proxy and `e_ℓ` its effort multiplier. In the utility formula, `s/r/k` are specialty/reasoning-fit/risk, `f` is the quality floor, `α` is criticality, and `Δ_p` is the bounded `preferenceAdjustment`; the `w` terms are the corresponding weights. `S` is `assignmentScore`; `E` contains dependency edges, and `ρ_j` is package `j`'s `provider/model` route. The indicator is 1 when routes differ, otherwise 0.
378
+
379
+ Quality first uses sufficient matching objective task evidence, then falls back to task-category LiveBench, overall LiveBench, and profile/catalog estimates. Model and effort are compared jointly only when at least two API efforts have usable task evidence; observed duration can replace the latency proxy. Public-data refresh is opt-in. Human ratings affect only the bounded `preferenceAdjustment`; they cannot increase objective quality or satisfy its floor.
363
380
 
364
381
  | Package basis | Quality | Cost | Latency | Specialty | Reasoning | Risk |
365
382
  | --- | --- | --- | --- | --- | --- | --- |
@@ -374,13 +391,15 @@ Base quality floors are **.75 / .78 / .82** for simple/balanced/complex tasks; c
374
391
 
375
392
  1. Prefer candidates meeting each package's floor. If none qualify, retain up to three highest-quality fallbacks and report relaxation.
376
393
  2. Keep at most **12 candidates per package**, including anchors for lowest known cost, greatest utility and highest quality. Local Pareto pruning is disabled when dependencies exist, because route identity affects handoffs.
377
- 3. Validate unique package IDs and topological dependency order. Search the retained Cartesian space exactly when its size is at most **4,096**; otherwise use **beam width 256**. Remaining minimum costs prune infeasible prefixes; the beam protects the cheapest feasible prefix under a finite budget.
394
+ 3. Validate unique package IDs and topological dependency order. Search the retained Cartesian space exactly when its size is at most **4,096**; otherwise use **beam width 256**. Search compresses dominated prefixes sharing the same future dependency boundary and ranks them using optimistic future handoffs. Remaining minimum costs prune infeasible prefixes; the beam protects the cheapest feasible prefix under a finite budget.
378
395
  4. Compare assignments lexicographically: fewer relaxed packages, smaller quality shortfall, higher utility, lower cost, fewer route switches, then stable route order. Minimum-cost mode compares cost before utility. Each dependency crossing a `provider/model` route subtracts .015 from utility.
379
396
  5. Report search metadata and feasibility. When a positive budget has no feasible assignment, a minimum-cost alternative can still be returned with `budgetFeasible: false`. A displayed plan is not proof that the budget is satisfied.
380
397
 
381
398
  “Exact” applies only to the retained candidate space and proxy objective. Candidate caps and beam pruning preclude a claim of global optimality over every configured model. Unit/synthetic tests establish mechanisms, not actual answer-quality gains. The public 2026-06-25 LiveBench score/cost tables used by the research audit are aggregate data; a paired per-question quality/cost matrix was not obtained, so no real routing gain is claimed. See [research](docs/ROUTING_RESEARCH.zh.md), [derivation/experiments](docs/ROUTING_DERIVATION_EXPERIMENTS.zh.md), and [validation protocol](docs/ROUTING_LIVEBENCH_VALIDATION.zh.md).
382
399
 
383
- Implementation: [router.mjs](.dsh-plugin/shared/router.mjs), [assignment-solver.mjs](.dsh-plugin/shared/assignment-solver.mjs), [routing-presets.mjs](.dsh-plugin/shared/routing-presets.mjs), [harness-plan.mjs](.dsh-plugin/shared/harness-plan.mjs) and [adaptive-feedback.mjs](.dsh-plugin/shared/adaptive-feedback.mjs).
400
+ See the [algorithm optimization guide](docs/ROUTING_ALGORITHM_OPTIMIZATION.zh.md) for evidence import, fallback rules, effort handling, and optional JSON validation with escalation. Escalation defaults to off and permits at most one additional ordinary API request after billing and budget checks.
401
+
402
+ Implementation: [router.mjs](.dsh-plugin/shared/router.mjs), [assignment-solver.mjs](.dsh-plugin/shared/assignment-solver.mjs), [routing-evidence.mjs](.dsh-plugin/shared/routing-evidence.mjs), [harness-plan.mjs](.dsh-plugin/shared/harness-plan.mjs) and [quality-gates.mjs](.dsh-plugin/shared/quality-gates.mjs).
384
403
 
385
404
  <a id="data"></a>
386
405
 
@@ -436,6 +455,8 @@ Open [the local preview](http://127.0.0.1:4173). It uses mock models, tools and
436
455
  | `experiment-plugin/` | Separate research experiment project; not shipped as part of the router plugin. |
437
456
  | `docs/` and dated reports | User documentation and historical verification records. |
438
457
 
458
+ `check:readme` guards the six math blocks, matching formulas in both languages and the reviewed blob hashes. `npm test` and `prepack` run this check; render changes must also be viewed on GitHub. The math blocks use [GitHub-supported syntax](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/writing-mathematical-expressions).
459
+
439
460
  `check:client` rebuilds in memory and compares the generated output with the committed bundle; `prepack` refuses a stale bundle. pnpm 10 has no `pnpm peers check` command: use the strict install above. Unavailable/incompatible host SDK packages may require the installed Harness runtime for local integration testing; [setup-harness-dev.mjs](scripts/setup-harness-dev.mjs) links missing SDK packages from an explicitly supplied Host `node_modules`, and [start-harness-preview.mjs](scripts/start-harness-preview.mjs) starts a separate local web Host profile. These helpers do not replace dependency verification or Desktop acceptance checks.
440
461
 
441
462
  Legacy compatibility/research files and dated reports are preserved for reference; their presence does not make every older integration an active feature of the current packaged plugin. Releases and synchronization follow [AGENTS.md](AGENTS.md); use versioned packages or verified release tags to reproduce a release.
package/README.zh.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  面向 **DeepSeek Harness Desktop** 的成本感知模型路由工作台。在本地规划任务、比较已配置路线、检查执行权限,并通过模型 API 或支持的厂商官方 CLI 执行有依赖关系的工作包。
6
6
 
7
- 当前版本:**0.21.1**(`@ljwei-stak/dsh-model-router`)。本版修复 Hermes 源码安装无法使用统一根目录的问题,保留现有用户数据位置,并将官方工具终端放到工具页顶部。沿用 0.21.0 的 Hermes/Pi 接入和 OpenCode V2 包更新。继续兼容 **DeepSeek Harness Desktop 0.2.0-rc.1 / 0.2.0-rc.2 / 0.2.1-rc.2**。Hermes 与 Pi 暂无经过验证的托管执行器;真实厂商执行证据仍见 **0.20.0** 报告,本版未新增模型实测。路由器与 [GAL](https://github.com/Alice-Marx/deepseek-harness-galgame) 自 0.12.0 起已拆分为独立插件。
7
+ 当前版本:**0.22.1**(`@ljwei-stak/dsh-model-router`)。新增“按算法推荐分配 / 手动调整分配”:拆分后的工作包可逐个指定模型 API 或官方工具,保留依赖、重新预览费用,并保存重跑目标。同时接入任务相关质量证据、模型与推理档位联合选择、历史资源 P90 估计与依赖感知搜索。手动混合执行当前只读;官方工具使用自身默认模型,原有官方团队编辑流程保留。继续兼容 **DeepSeek Harness Desktop 0.2.0-rc.1 / 0.2.0-rc.2 / 0.2.1-rc.2**,沿用 Hermes/Pi 安装与终端支持;两者仍无经过验证的托管执行器。真实厂商执行证据仍见 **0.20.0** 报告,本版未新增模型实测。路由器与 [GAL](https://github.com/Alice-Marx/deepseek-harness-galgame) 自 0.12.0 起已拆分为独立插件。
8
8
 
9
9
  官方 CLI 协作按依赖顺序逐包执行、传递依赖上下文,不会自动回退到模型目录 API。可编辑团队需明确选择 Harness 沙箱或厂商 CLI 正常环境。后者通过 Git worktree 收集修改,但不限制操作系统访问。未显式设置模型映射时,各 CLI 沿用自身配置的模型。参见[真实 Windows 验证及其局限](docs/releases/0.20.0-validation.md)。
10
10
 
@@ -40,16 +40,16 @@
40
40
  打开 **插件 → 添加插件**,输入:
41
41
 
42
42
  ```text
43
- @ljwei-stak/dsh-model-router@0.21.1
43
+ @ljwei-stak/dsh-model-router@0.22.1
44
44
  ```
45
45
 
46
- 镜像缺少该精确版本时,使用官方 HTTPS npm 源 `https://registry.npmjs.org/`。启用插件,然后完全退出 Harness(包括托盘进程)并重启。插件详情应显示 **0.21.1**,侧栏应出现 **模型路由**。仅执行全局 `npm install -g` 不会把插件注册到 Desktop。
46
+ 镜像缺少该精确版本时,使用官方 HTTPS npm 源 `https://registry.npmjs.org/`。启用插件,然后完全退出 Harness(包括托盘进程)并重启。插件详情应显示 **0.22.1**,侧栏应出现 **模型路由**。仅执行全局 `npm install -g` 不会把插件注册到 Desktop。
47
47
 
48
48
  也可以通过插件管理器安装本地 `.tgz` 压缩包,或解压后的内部 `package` 目录。两者都必须包含 `package.json` 和 `.dsh-plugin`。历史构建见 [Releases](https://github.com/Alice-Marx/dsh-model-router/releases),也可按下文从源码构建。
49
49
 
50
50
  ### 从旧包名升级
51
51
 
52
- 旧名称 `@ljwei-stak/model-router-galgame` 停留在 0.13.0。保留配置档/应用数据,移除旧插件条目,再添加 `@ljwei-stak/dsh-model-router@0.21.1`。不要同时保留两条插件:它们共用内部插件 id `model-router-galgame` 和工具名。保留该 id 能让现有路由设置与历史记录继续使用。
52
+ 旧名称 `@ljwei-stak/model-router-galgame` 停留在 0.13.0。保留配置档/应用数据,移除旧插件条目,再添加 `@ljwei-stak/dsh-model-router@0.22.1`。不要同时保留两条插件:它们共用内部插件 id `model-router-galgame` 和工具名。保留该 id 能让现有路由设置与历史记录继续使用。
53
53
 
54
54
  从合包 0.11.x 升级前,先备份配置档,并导出需要保留的 GAL 存档。剧情播放、立绘、音乐与存档现属于独立的 `@ljwei-stak/dsh-galgame`。详细存档限制见 [MIGRATION.md](docs/archive/MIGRATION.md)。
55
55
 
@@ -317,49 +317,66 @@ Coding-plan 密钥与端点保留在 Harness 供应商设置中。`plan-key` 配
317
317
 
318
318
  有效的 CLI 报告美元金额(包括明确的零)优先于 token × 单价计算。否则,按 token 核算 CLI 费用要求完整、归一化的用量,已知非负价格,以及报告的实际模型匹配计价路线或其显式 CLI 映射:
319
319
 
320
- ```text
321
- actualUsd = (inputTokens × inputPrice + outputTokens × outputPrice
322
- + cacheReadTokens × cacheReadPrice
323
- + cacheWriteTokens × cacheWritePrice) / 1,000,000
320
+ <!-- formula:actual-cost -->
321
+ ```math
322
+ C_a = \frac{I_u p_i+O p_o+R p_r+W p_w}{10^6}
324
323
  ```
325
324
 
325
+ `C_a` 对应 `actualUsd`;`I_u`、`O`、`R`、`W` 分别对应 `inputTokens`、`outputTokens`、`cacheReadTokens`、`cacheWriteTokens`,`p_i`、`p_o`、`p_r`、`p_w` 分别为输入、输出、缓存读取和缓存写入单价,单位为美元/百万 token。
326
+
326
327
  经适配器归一化后,这些账本计数互不重叠;不要把缓存 token 再加到已包含缓存的输入计数中。缺少可选缓存单价时,使用输入单价。用量不完整、价格缺失或身份未知/不匹配时,金额保持 `null`,不是零。完整的终态证据可在失败、取消、超时后保留;部分事件标记为 `usageIncomplete`。
327
328
 
328
- 例如,完整 API 结果含 1,000 个未缓存输入 token($1/百万)和 500 个输出 token($5/百万),费用为 $0.0035。订阅结果可把该金额显示为 `referenceCostUsd`,而 `costUsd` 保持 null;参考费用不加进 API 支出。厂商报告的 $0 是该次尝试的明确证据,不能证明先前费用未知的尝试免费。实际厂商账单为准。官方团队模式不自动回退 API,防止的是路由器自身的回退;厂商 CLI 仍可能使用它自己配置的 API 凭据。
329
+ 例如,完整 API 结果含 1,000 个未缓存输入 token(\$1/百万)和 500 个输出 token(\$5/百万),费用为 \$0.0035。订阅结果可把该金额显示为 `referenceCostUsd`,而 `costUsd` 保持 null;参考费用不加进 API 支出。厂商报告的 \$0 是该次尝试的明确证据,不能证明先前费用未知的尝试免费。实际厂商账单为准。官方团队模式不自动回退 API,防止的是路由器自身的回退;厂商 CLI 仍可能使用它自己配置的 API 凭据。
329
330
 
330
331
  <a id="routing"></a>
331
332
 
332
333
  ## 路由算法
333
334
 
335
+ 手动分配:生成任务建议后,可选择按算法推荐执行,或逐包指定模型 API / 官方工具。参见[手动分配使用说明](docs/MANUAL_TASK_ASSIGNMENT.zh.md)。
336
+
334
337
  规划器是确定性的本地启发式算法,不是训练得到的成功率预测器。它对文本分类、估计复杂度、创建适当的分析/执行/验证/汇总工作包,发现精确的已配置路线,叠加路线配置,并应用能力/质量约束。显式指定路线会跳过与其他路线的比较。目录质量/延迟/风险提示是实验性先验,不是实测成功概率或厂商实时报价。执行当前以文本为主;vision 标签不能证明已有端到端多模态流水线。
335
338
 
336
339
  ### Token 与价格估计
337
340
 
338
- 基础输入 token 为 `max(80, ceil(text.length / 3.7))`,再乘以工作包阶段系数。基础输出为 900,按阶段/推理强度调整,最少 220。这是按文本长度估算,不是厂商 tokenizer。令 `I` 为估计输入总数,`R/W` 为缓存读取/写入部分,`O` 为输出,价格单位为美元/百万 token:
341
+ 没有匹配资源证据时,基础输入 token 为 `max(80, ceil(text.length / 3.7))`,再乘以工作包阶段系数。基础输出为 900,按阶段/推理强度调整,最少 220。这是按文本长度估算,不是厂商 tokenizer。匹配的完整历史记录达到样本门槛后,改用经验 P90 资源估计,不再重复乘档位和阶段系数。令 `I` 为估计输入总数,`R/W` 为缓存读取/写入部分,`O` 为输出,价格单位为美元/百万 token:
339
342
 
340
- ```text
341
- C = ((I − R − W) × p_in + R × p_cache_read
342
- + W × p_cache_write + O × p_out) / 1,000,000
343
- costUtility = 1 / (1 + C / C_ref)
343
+ <!-- formula:planning-cost -->
344
+ ```math
345
+ C = \frac{(I-R-W)p_i+O p_o+R p_r+W p_w}{10^6}
344
346
  ```
345
347
 
346
- `C_ref` 使用固定参考价(输入 1、输出 5、缓存读取/写入 1 美元/百万),不是厂商报价。固定尺度防止一个无关的昂贵候选把所有费用惩罚压平。未知价格的公开估计为 `null`,费用效用为 0。内部无预算约束搜索使用费用哨兵值 0,但有限预算分配会排除价格未知候选;哨兵值绝不代表执行免费。
348
+ <!-- formula:cost-utility -->
349
+ ```math
350
+ U_c = \frac{1}{1+C/\max(C_{\mathrm{ref}},10^{-12})}
351
+ ```
352
+
353
+ `U_c` 对应 `costUtility`,单价符号与上文一致。`C_ref` 使用固定参考价(输入 1、输出 5、缓存读取/写入 1 美元/百万),不是厂商报价。固定尺度防止一个无关的昂贵候选把所有费用惩罚压平。未知价格的公开估计为 `null`,费用效用为 0。内部无预算约束搜索使用费用哨兵值 0,但有限预算分配会排除价格未知候选;哨兵值绝不代表执行免费。
347
354
 
348
355
  ### 候选目标与质量下限
349
356
 
350
357
  使用归一化质量 `q`,以及归一化延迟、领域匹配、推理匹配和风险代理值:
351
358
 
352
- ```text
353
- u = wq × q + wc × costUtility
354
- + wl × (1 − clamp(latency × effortLatency, 0, 1))
355
- + ws × specialty + wr × reasoningFit − wk × risk
356
- − max(0, qualityFloor − q) × criticality
357
- + preferenceAdjustment
359
+ <!-- formula:latency-utility -->
360
+ ```math
361
+ L = \begin{cases}
362
+ \dfrac{1}{1+t/10\,000}, & t\text{ known}, \\
363
+ 1-\min(1,\max(0,\ell e_\ell)), & \text{otherwise}.
364
+ \end{cases}
365
+ ```
366
+
367
+ <!-- formula:candidate-utility -->
368
+ ```math
369
+ u = w_q q+w_c U_c+w_\ell L+w_s s+w_r r-w_k k-\alpha\max(0,f-q)+\Delta_p
370
+ ```
358
371
 
359
- assignmentScore = sum(package utility) − 0.015 × crossRouteDependencyEdges
372
+ <!-- formula:assignment-score -->
373
+ ```math
374
+ S = \sum_{j=1}^{n}u_j - 0.015\sum_{(i,j)\in E}\mathbf{1}[\rho_i\ne\rho_j]
360
375
  ```
361
376
 
362
- 质量优先使用对应任务类别的 LiveBench 分数,其次整体 LiveBench,最后才是路线配置/目录估值。公共数据刷新默认关闭,需主动启用。人工评分仅影响有界的 `preferenceAdjustment`,不能提高客观质量或满足质量下限。
377
+ `L` 为延迟效用:`t` 是匹配历史的 P90 耗时,单位为毫秒;未知时使用延迟代理值 `ℓ` 及档位系数 `e_ℓ`。效用式中,`s/r/k` 分别是领域匹配、推理匹配和风险,`f` 为质量下限,`α` 为关键性,`Δ_p` 为有界的 `preferenceAdjustment`;各 `w` 为对应权重。`S` 对应 `assignmentScore`,`E` 为依赖边集合,`ρ_j` 为工作包 `j` 的 `provider/model` 路线;指示函数在路线不同时取 1,否则取 0。
378
+
379
+ 质量优先使用足量且匹配的任务客观证据,再回退对应任务类别的 LiveBench 分数、整体 LiveBench、路线配置/目录估值。至少两个 API 档位各有可用任务证据时,才联合比较模型与档位;经验耗时可替换延迟代理项。公共数据刷新默认关闭,需主动启用。人工评分仅影响有界的 `preferenceAdjustment`,不能提高客观质量或满足质量下限。
363
380
 
364
381
  | 工作包基础类型 | 质量 | 费用 | 延迟 | 领域 | 推理 | 风险 |
365
382
  | --- | --- | --- | --- | --- | --- | --- |
@@ -374,13 +391,15 @@ assignmentScore = sum(package utility) − 0.015 × crossRouteDependencyEdges
374
391
 
375
392
  1. 优先保留达到各工作包质量下限的候选。若没有合格候选,保留质量最高的至多三个回退候选,并报告约束放宽。
376
393
  2. 每包最多保留 **12 个候选**,包含最低已知费用、最大效用与最高质量的锚点。存在依赖时禁用局部 Pareto 裁剪,因为路线身份会影响交接。
377
- 3. 验证工作包 ID 唯一且依赖按拓扑排序。保留候选的笛卡尔空间大小不超过 **4,096** 时精确搜索;否则采用 **beam width 256**。剩余最小费用用于裁剪不可行前缀;有限预算时,beam 会保护最便宜的可行前缀。
394
+ 3. 验证工作包 ID 唯一且依赖按拓扑排序。保留候选的笛卡尔空间大小不超过 **4,096** 时精确搜索;否则采用 **beam width 256**。搜索按未来依赖的模型边界压缩被支配前缀,并用未来交接的乐观估计排序。剩余最小费用用于裁剪不可行前缀;有限预算时,beam 会保护最便宜的可行前缀。
378
395
  4. 按字典序比较分配:更少放宽包、更小质量缺口、更高效用、更低费用、更少路线切换,最后稳定的路线顺序。最小费用模式先比较费用,再比较效用。每条跨越 `provider/model` 路线的依赖边从效用中扣除 .015。
379
396
  5. 报告搜索元数据与可行性。正预算下若不存在可行分配,仍可返回最小费用备选,但标记 `budgetFeasible: false`。显示了计划不代表预算已满足。
380
397
 
381
398
  “精确”仅适用于保留下来的候选空间与代理目标。候选上限和 beam 裁剪意味着不能声称在所有已配置模型上全局最优。单元/合成测试验证机制,不证明真实回答质量提升。研究审查使用的公开 2026-06-25 LiveBench 分数/费用表属于汇总数据;未取得逐题配对的质量/费用矩阵,因此不主张真实路由收益。参见[研究](docs/ROUTING_RESEARCH.zh.md)、[推导/实验](docs/ROUTING_DERIVATION_EXPERIMENTS.zh.md)与[验证规程](docs/ROUTING_LIVEBENCH_VALIDATION.zh.md)。
382
399
 
383
- 实现:[router.mjs](.dsh-plugin/shared/router.mjs)、[assignment-solver.mjs](.dsh-plugin/shared/assignment-solver.mjs)、[routing-presets.mjs](.dsh-plugin/shared/routing-presets.mjs)、[harness-plan.mjs](.dsh-plugin/shared/harness-plan.mjs) 与 [adaptive-feedback.mjs](.dsh-plugin/shared/adaptive-feedback.mjs)。
400
+ 证据导入、回退条件、推理档位与可选 JSON 验收升级的设置参见[算法优化使用说明](docs/ROUTING_ALGORITHM_OPTIMIZATION.zh.md)。验收升级默认关闭,启用后仍需通过计费与预算检查,最多增加一次普通 API 调用。
401
+
402
+ 实现:[router.mjs](.dsh-plugin/shared/router.mjs)、[assignment-solver.mjs](.dsh-plugin/shared/assignment-solver.mjs)、[routing-evidence.mjs](.dsh-plugin/shared/routing-evidence.mjs)、[harness-plan.mjs](.dsh-plugin/shared/harness-plan.mjs) 与 [quality-gates.mjs](.dsh-plugin/shared/quality-gates.mjs)。
384
403
 
385
404
  <a id="data"></a>
386
405
 
@@ -436,6 +455,8 @@ npm run preview:ui
436
455
  | `experiment-plugin/` | 独立研究实验项目,不随路由插件发布。 |
437
456
  | `docs/` 与带日期报告 | 用户文档与历史验证记录。 |
438
457
 
458
+ `check:readme` 检查六个数学公式块、双语公式一致性和审阅后的 blob 哈希;`npm test` 与 `prepack` 均会执行。修改公式后还须在 GitHub 页面查看实际渲染。公式块采用 [GitHub 官方支持的语法](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/writing-mathematical-expressions)。
459
+
439
460
  `check:client` 在内存中重建并比较已提交 bundle;`prepack` 会拒绝过期 bundle。pnpm 10 没有 `pnpm peers check` 命令:请使用上述严格安装。Host SDK 包不可用/不兼容时,本地集成测试可能需要已安装的 Harness 运行时;[setup-harness-dev.mjs](scripts/setup-harness-dev.mjs) 从显式提供的 Host `node_modules` 链接缺失 SDK 包,[start-harness-preview.mjs](scripts/start-harness-preview.mjs) 启动独立的本地 Web Host 配置档。这些辅助脚本不能代替依赖验证或 Desktop 验收。
440
461
 
441
462
  旧兼容/研究文件和带日期报告保留作参考;它们的存在不代表当前发行插件仍启用所有旧集成。发布与同步遵循 [AGENTS.md](AGENTS.md);重现某次发布请使用带版本号的包或已验证的发布 tag。
@@ -1,8 +1,8 @@
1
1
  # DeepSeek Harness Desktop · 独立插件安装与验证
2
2
 
3
- 模型路由从 **0.12.0** 起独立发布;GAL 是独立的 **0.1.0** 插件。路由 **0.21.1** 声明支持官方 **DeepSeek Harness Desktop 0.2.0-rc.1 / 0.2.0-rc.2 / 0.2.1-rc.2**。GAL 的兼容范围以其自身安装包为准。
3
+ 模型路由从 **0.12.0** 起独立发布;GAL 是独立的 **0.1.0** 插件。路由 **0.22.1** 声明支持官方 **DeepSeek Harness Desktop 0.2.0-rc.1 / 0.2.0-rc.2 / 0.2.1-rc.2**。GAL 的兼容范围以其自身安装包为准。
4
4
 
5
- 当前路由版本为 **0.21.1**,修复 Hermes 自定义程序目录支持,并将官方工具终端移到工具页顶部;沿用 Hermes/Pi 接入和 OpenCode 官方 V2 包。兼容声明列出已核对的宿主版本,不设置兼容豁免。保留原插件 id、配置与运行记录;安装后完全退出 Harness(包括托盘)再重启。官方终端、ZCode TUI 与统一安装设置继续沿用,公开数据默认关闭。
5
+ 当前路由版本为 **0.22.1**,修复中英文 README 数学公式显示;0.22.1 新增算法推荐与手动工作包分配二选一,可逐包选择模型 API 或官方工具,并改进证据驱动规划与依赖搜索。手动混合执行目前只读;编辑文件继续走官方工具协作。沿用 Hermes/Pi 安装与终端支持、OpenCode 官方 V2 包和现有兼容声明。保留原插件 id、配置与运行记录;安装后完全退出 Harness(包括托盘)再重启。公开数据默认关闭,自动质量升级默认关闭。
6
6
 
7
7
  [路由 README](../README.zh.md) · [迁移说明](archive/MIGRATION.md) · [独立 GAL README](https://github.com/Alice-Marx/deepseek-harness-galgame#readme)
8
8
 
@@ -10,7 +10,7 @@
10
10
 
11
11
  | 需求 | 添加插件输入框 | 安装后的入口 |
12
12
  | --- | --- | --- |
13
- | 分析复杂度、按质量和费用选模型、调用官方工具 | `@ljwei-stak/dsh-model-router@0.21.1` | 模型路由 |
13
+ | 分析复杂度、按质量和费用选模型、调用官方工具 | `@ljwei-stak/dsh-model-router@0.22.1` | 模型路由 |
14
14
  | 剧情、立绘、音乐、存档、自由对话 | `@ljwei-stak/dsh-galgame@0.1.0` | Gal 模块 |
15
15
  | 两者都要 | 分别安装上面两个包 | 模型路由 + Gal 模块 |
16
16
 
@@ -24,7 +24,7 @@
24
24
  2. 在“包名、GitHub 仓库地址或本地目录路径”输入框填一个完整包名,例如:
25
25
 
26
26
  ```text
27
- @ljwei-stak/dsh-model-router@0.21.1
27
+ @ljwei-stak/dsh-model-router@0.22.1
28
28
  ```
29
29
 
30
30
  只想安装 GAL 时填写:
@@ -40,7 +40,7 @@
40
40
  ```
41
41
 
42
42
  4. 核对预览的包名、版本和宿主兼容信息,安装并启用。完全退出 Harness(包括托盘进程)再启动,确保 Host 加载新代码。
43
- 5. 检查插件详情与侧边栏:路由应为 **0.21.1 / 模型路由**;GAL 应为 **0.1.0 / Gal 模块**。仅装路由时没有 GAL 入口是预期行为。
43
+ 5. 检查插件详情与侧边栏:路由应为 **0.22.1 / 模型路由**;GAL 应为 **0.1.0 / Gal 模块**。仅装路由时没有 GAL 入口是预期行为。
44
44
 
45
45
  普通用户无需 `npm install -g`,该命令不会把插件注册到当前 Harness profile。
46
46
 
@@ -48,13 +48,13 @@
48
48
 
49
49
  进入对应 Release 下载 `.tgz`:
50
50
 
51
- - [模型路由 Releases](https://github.com/Alice-Marx/dsh-model-router/releases)(也可运行 `npm pack @ljwei-stak/dsh-model-router@0.21.1` 获取同一安装包)
51
+ - [模型路由 Releases](https://github.com/Alice-Marx/dsh-model-router/releases)(也可运行 `npm pack @ljwei-stak/dsh-model-router@0.22.1` 获取同一安装包)
52
52
  - [独立 GAL v0.1.0](https://github.com/Alice-Marx/deepseek-harness-galgame/releases/tag/v0.1.0)
53
53
 
54
54
  在“添加插件”填写下载文件的**绝对路径**,例如:
55
55
 
56
56
  ```text
57
- D:\Plugins\ljwei-stak-dsh-model-router-0.21.1.tgz
57
+ D:\Plugins\ljwei-stak-dsh-model-router-0.22.1.tgz
58
58
  ```
59
59
 
60
60
  ```text
@@ -64,7 +64,7 @@ D:\Plugins\ljwei-stak-dsh-galgame-0.1.0.tgz
64
64
  如附有 `.sha256` 文件,用 PowerShell 计算并比较摘要:
65
65
 
66
66
  ```powershell
67
- Get-FileHash -Algorithm SHA256 -LiteralPath 'D:\Plugins\ljwei-stak-dsh-model-router-0.21.1.tgz'
67
+ Get-FileHash -Algorithm SHA256 -LiteralPath 'D:\Plugins\ljwei-stak-dsh-model-router-0.22.1.tgz'
68
68
  Get-FileHash -Algorithm SHA256 -LiteralPath 'D:\Plugins\ljwei-stak-dsh-galgame-0.1.0.tgz'
69
69
  ```
70
70
 
@@ -74,7 +74,7 @@ Get-FileHash -Algorithm SHA256 -LiteralPath 'D:\Plugins\ljwei-stak-dsh-galgame-0
74
74
 
75
75
  1. 在旧合并插件的 GAL 播放器导出需要保留的剧情进度,并备份整个 Harness profile。每份 JSON 仅保存**当前剧情状态**,不含所有手动槽、设置、已读记录或本地音乐;重要槽位可依次读档再导出。
76
76
  2. 在**同一个 profile**安装独立 `@ljwei-stak/dsh-galgame@0.1.0`。
77
- 3. 0.13.0 起包名改为 `@ljwei-stak/dsh-model-router`(旧包名最后版本为 0.13.0,内容相同,之后不再更新):在插件管理器卸载原 `@ljwei-stak/model-router-galgame`(保留 profile 与应用数据),再添加 `@ljwei-stak/dsh-model-router@0.21.1`。不要两个同时安装(条目 id 与工具名相同);条目 id 未变,路由设置与执行记录会保留。完成两项更新后再玩剧情,避免同时操作旧合并入口和新入口。
77
+ 3. 0.13.0 起包名改为 `@ljwei-stak/dsh-model-router`(旧包名最后版本为 0.13.0,内容相同,之后不再更新):在插件管理器卸载原 `@ljwei-stak/model-router-galgame`(保留 profile 与应用数据),再添加 `@ljwei-stak/dsh-model-router@0.22.1`。不要两个同时安装(条目 id 与工具名相同);条目 id 未变,路由设置与执行记录会保留。完成两项更新后再玩剧情,避免同时操作旧合并入口和新入口。
78
78
  4. 现在路由与 GAL 各有一个入口。独立 GAL 沿用旧存档 localStorage 键,核对当前进度和三槽;更换 profile 或进度未恢复时,先切换到匹配剧目,再导入 JSON 备份。
79
79
  5. 后续分别更新需要的插件;只用路由可以不启用或不安装 GAL。保留 profile 与应用数据,卸载插件时不要清理故事数据。
80
80
 
@@ -82,7 +82,7 @@ GAL 核心只包含**《回声之城·正篇》**与**《旧城迁移篇:未
82
82
 
83
83
  ## 5. 模型路由第一次使用
84
84
 
85
- 工作台自 0.15.0 起分成**任务与执行、模型配置、官方工具、预算与安全**四页;0.21.1 沿用该布局。切换页面保留安装任务、终端会话和未完成的输入。
85
+ 工作台自 0.15.0 起分成**任务与执行、模型配置、官方工具、预算与安全**四页;0.22.1 沿用该布局。切换页面保留安装任务、终端会话和未完成的输入。
86
86
 
87
87
  1. 在 Harness 官方**模型**页配置供应商、模型与凭据。插件读取准确的 `provider/model` 目录,模型档案不保存 API Key。
88
88
  2. 在**模型配置**刷新目录,逐条填写自报质量评分、核对过的输入/输出单价(USD / 百万 token)和擅长方向;缺价留空。可选 `cliModel` 必须是该厂商 CLI 已验证接受的名字。可选 LiveBench 名称须准确对应版本与推理档位;它是用户确认的映射,不自动证明实际执行档位。
@@ -114,7 +114,7 @@ GAL 核心只包含**《回声之城·正篇》**与**《旧城迁移篇:未
114
114
  | 检查 | 预期 |
115
115
  | --- | --- |
116
116
  | 路由宿主版本 | 0.2.0-rc.1、0.2.0-rc.2 或 0.2.1-rc.2;包括 `rc` 后缀。 |
117
- | 路由独立安装 | 0.21.1 详情、模型路由入口、目录和模型档案可用;不出现旧合并 GAL 入口。 |
117
+ | 路由独立安装 | 0.22.1 详情、模型路由入口、目录和模型档案可用;不出现旧合并 GAL 入口。 |
118
118
  | GAL 独立安装 | 0.1.0 详情、Gal 模块入口、标题与两部核心剧情可用;不要求安装路由。 |
119
119
  | 共同安装 | 两个入口各一份,路由工具和 GAL 播放器均能使用。 |
120
120
  | 存档迁移 | 同 profile 可读旧键;跨 profile 用匹配剧目 JSON 导入;旧篇目的数据不覆盖。 |
@@ -129,7 +129,7 @@ GAL 核心只包含**《回声之城·正篇》**与**《旧城迁移篇:未
129
129
 
130
130
  ## 8. 开发者从完整源码构建
131
131
 
132
- 路由需要 Node.js **22.19+** 与 **pnpm 10.34.6**。从完整源码仓库根目录构建;当前源码版本为 0.21.1,复现已发布版本时检出对应发布标签。旧版(如 0.15.0)标签保留其当时内容。运行:
132
+ 路由需要 Node.js **22.19+** 与 **pnpm 10.34.6**。从完整源码仓库根目录构建;当前源码版本为 0.22.1,复现已发布版本时检出对应发布标签。旧版(如 0.15.0)标签保留其当时内容。运行:
133
133
 
134
134
  ```powershell
135
135
  pnpm install --frozen-lockfile --strict-peer-dependencies
@@ -0,0 +1,46 @@
1
+ # 选择算法分配或手动调整
2
+
3
+ 在工作台生成路由建议后,可以选择 **按算法推荐分配**,也可以选择 **手动调整分配**。
4
+
5
+ 1. 输入任务,选择“团队分工”,生成路由建议。单任务也可以调整一个工作包;“指定模型”沿用原来的全局模型选择。
6
+ 2. 使用算法分配时,工作包按推荐方案和已设置的计费策略执行。
7
+ 3. 切换到手动调整后,每个工作包都有独立的目标选择。初始选择为该包的推荐模型 API,可改成其他已配置的模型 API,或者已安装且支持只读执行的官方工具。
8
+ 4. 核对任务目标、前置依赖、原算法推荐与新选择。修改目标不会改变任务拆分和依赖关系。恢复推荐可重新填入各包的推荐模型;切回算法分配会恢复原有自动策略。
9
+ 5. 点击“预览执行计划”,核对 Host 验证后的实际目标、费用和权限,再确认执行。修改任务、模型目录、设置、规划依据或分配选择后,需要重新预览。
10
+
11
+ 手动分配支持在一次运行中混合模型 API 与官方工具,例如由模型分析、Codex 检查、另一个模型汇总。各包按依赖执行,上游失败会阻止依赖它的后续工作包。结果和分配选择保存在同一份运行记录中,失败步骤重跑沿用保存的目标;改派重跑则使用新选择。
12
+
13
+ ## 模型和工具分别代表什么
14
+
15
+ - **模型 API**:固定调用所选 provider/model,使用适配器默认推理档位。不会因为 CLI 已安装、订阅优先、质量升级或自动省钱策略而改为其他模型或渠道。配置为只用订阅的路线,以及编程套餐专用端点,不能直接作为普通 API 目标;预览会说明原因。
16
+ - **官方工具**:固定调用所选的注册工具,使用该工具自身配置的默认模型。选择工具不等于选择某个 API 模型;如需控制工具内部模型,应在该官方工具的配置中设置。未安装、平台不支持或执行未就绪时,预览会拒绝执行;工具失败不会自动转 API。
17
+
18
+ 工具默认模型的价格通常无法可靠预估,因此显示“价格待配置/费用未知”,不会套用原推荐 API 模型的价格。已报告的真实费用仍按现有账本规则记录。预算 0 表示未设置本次估算上限;有限预算下,手动目标费用过高或无法确认满足本次预算时会暂停,确认后仍沿用手选目标,不会自动换成便宜模型。估算不是厂商实际扣费的硬上限。
19
+
20
+ 手动混合分配当前执行只读任务。需要编辑工程文件时,继续使用“官方工具协作 → 编辑文件”的隔离工作树流程。该流程保留现有权限确认与改动整合机制。
21
+
22
+ 如果“允许手动改派”设置关闭,工作台也会关闭手动分配入口。
23
+
24
+ ## 在官方会话工具中使用
25
+
26
+ 先调用 `model_router_plan`,保存返回的 `packagePlanKey` 和 `team.workPackages`。再调用 `model_router_execute`,使用相同的任务文本与规划模式,传入:
27
+
28
+ ```json
29
+ {
30
+ "assignmentMode": "manual",
31
+ "packagePlanKey": "复制当前计划返回的键",
32
+ "packageAssignmentsJson": "以当前计划全部工作包 ID 为键的 JSON 对象"
33
+ }
34
+ ```
35
+
36
+ 每个绑定只能是下面两种结构之一:
37
+
38
+ ```json
39
+ { "kind": "api", "provider": "目录中的供应商 ID", "model": "目录中的准确模型 ID" }
40
+ ```
41
+
42
+ ```json
43
+ { "kind": "tool", "toolId": "codex" }
44
+ ```
45
+
46
+ 必须覆盖当前计划中的全部工作包,不可添加其他包 ID。拆分键过期、目标不存在或后续工具未就绪时,会在第一个模型调用前拒绝整次执行。未传手动分配参数时,工具继续使用算法推荐。
@@ -0,0 +1,91 @@
1
+ # 路由算法优化:实施与使用
2
+
3
+ 本轮把任务相关证据、模型与推理档位联合选择、真实资源估计和依赖感知搜索接入规划器,并提供可选的 JSON 结构验收级联。它们改进的是有证据约束的规划和执行行为;真实回答质量提高多少、总费用降低多少,仍需独立留出任务上的同题实测。
4
+
5
+ ## 已实现的行为
6
+
7
+ - **任务相关质量证据**:按 provider、model、reasoningEffort、channel、任务类型精确匹配,再用查询的哈希词法特征检索相似训练任务。不同任务组才计为不同邻居;样本不足或查询不相似时回退原有估计,不给未调用模型补造标签。输出的邻居离散程度不是校准后的答对概率。
8
+ - **模型 × effort 联合选择**:同一 API 模型至少有两个档位各自具备可用任务证据时,才把这些档位展开成独立动作。冷启动保留原档位选择方式;同一模型切换 effort 不计为跨模型交接。
9
+ - **真实资源估计**:从成功且用量完整的工作包学习输入比例、输出 token 和耗时的经验分布,规划时使用可用的 P90 估计。计数不足、模型身份不符或用量不完整时回退启发式估计。经验分位数不保证整次运行不超预算。
10
+ - **有界 DAG 搜索**:默认候选组合数不超过 4096 时精确枚举;更大空间保留未来依赖所需的模型边界,安全压缩被支配前缀,再按未来交接的乐观估计限宽,默认宽度 256。有限预算继续保护可负担前缀,未知价格不能证明预算可行。
11
+ - **effort 执行一致性**:API 调用传递路由允许列表中的精确 effort ID,并记录计划值、请求值及状态。`requested` 只代表 SDK 请求已携带该控制,不证明提供方实际使用了该强度。CLI 规划使用厂商默认档位;显式传入尚未支持的 CLI effort 时记录 `unsupported`,换模型时不会继承原模型的档位。
12
+
13
+ 搜索结果中的 `strategy`、`expandedStates`、`dominancePruned`、`beamPruned`、`peakFrontier` 和 `beamWidth` 可用于审计。`exact` 的范围仅是传入的保留候选空间;beam 路径的 `approximate: true`、`boundCertified: false` 不提供全池最优或目标差距保证。
14
+
15
+ ## 导入离线质量证据
16
+
17
+ 在源码项目根目录运行:
18
+
19
+ ```powershell
20
+ node scripts/build-routing-evidence.mjs --input data.json --output evidence.json
21
+ ```
22
+
23
+ 此命令只处理本地文件,不调用模型、不联网、不自动收集历史。输入顶层是 `{ "runs": [...], "observations": [...], "matrix": {...} }`,三项均可省略。输入文件上限 10 MB,`runs` 和最终展开的 `observations` 各不超过 10000 条;输入输出路径必须不同。
24
+
25
+ 一条 `observations` 的字段示例如下。示例不代表真实测量;`timestamp` 应使用实际采样的 Unix 毫秒时间,`quality` 应来自可追溯的客观验收。
26
+
27
+ ```json
28
+ {
29
+ "observations": [
30
+ {
31
+ "id": "task-001:model-a:medium",
32
+ "groupId": "task-001",
33
+ "text": "修复缓存失效后返回旧值的问题",
34
+ "type": "code",
35
+ "provider": "configured-provider-id",
36
+ "model": "configured-model-id",
37
+ "reasoningEffort": "medium",
38
+ "channel": "harness-llm",
39
+ "quality": 1,
40
+ "split": "train",
41
+ "timestamp": 1792281600000,
42
+ "provenance": {
43
+ "kind": "objective",
44
+ "source": "unit-tests",
45
+ "reference": "audit/run-001"
46
+ }
47
+ }
48
+ ]
49
+ }
50
+ ```
51
+
52
+ 每条记录必须有上述身份、任务文本、类型、评分、时间、训练划分和来源字段。`reasoningEffort: ""` 表示档位未知;不能替换为任意已知档位。`channel: "api"` 会归一为 `harness-llm`。质量分须在 `[0,1]` 内,来源须声明 `kind: "objective"` 和非空 `source`、`reference`;点赞、自评、模型裁判和主观偏好不能直接当作这类标签。
53
+
54
+ `runs` 接受运行账本形状:run 含 `id`、`task`、`createdAt`、`finishedAt`、`packages`;工作包含 `id`、`provider`、`model`、`channel`、`type`、`purpose`、`ran: true`、`ok: true`、`usage`、`inputChars`、`finishedAt`,可含 `durationMs`。资源学习要求有效的非负 `usage.inputTokens`、`usage.outputTokens` 和实际正整数输入字符数。可选的 cache 计数必须是与未缓存输入互斥的读、写类别,不能把已包含缓存的总数再相加。缺失或未知计数不应补零。时间须落在有效窗口及所属 run 的起止范围内;失败、用量不完整、身份不符、重复或多次质量调用合并后的工作包不作为单动作资源样本。资源拒绝原因保留在产物 `stats` 中,账本中的评分不会自动变成质量标签。
55
+
56
+ 同题多动作也可用矩阵输入:`matrix` 必须含 `split: "train"` 和 `tasks`;每个 task 含 `id`、`groupId`、`text`、`type`、`timestamp`、`results`。每个 result 含 `action: {provider, model, reasoningEffort, channel}`、`quality`、`provenance`,可另给唯一 `id`。只写实际测量的动作,未调用的动作保持未知。
57
+
58
+ 重复 id、同一任务组的重复动作、未来或过期时间、非法客观记录和未经显式允许的 synthetic 记录会使 CLI 的质量导入失败。测试、验证、校准任务须按 `groupId` 在生成训练输入前分离;它们不能作为训练邻居导入。默认时间窗口为 180 天。
59
+
60
+ `--min-samples N` 可用于离线实验,默认 8;`--now TIMESTAMP` 固定评估时间以便复现;`--allow-synthetic` 只用于测试夹具。**生产 Host 重新构建证据时固定采用至少 8 个匹配样本的门槛**,不会沿用离线降低的门槛;质量预测还要求这些样本来自不同且足够相似的任务组。上面的单条示例不足以触发质量预测。
61
+
62
+ 将生成文件的 JSON 文本填入插件设置的 `routingEvidenceJson`(最多 200000 字符)。Host 只从导入产物接收质量样本;资源统计从本机运行账本重新学习。`resourceLearningEnabled` 默认 `true`,关闭后停止使用账本重建资源证据。没有可用证据时保持原有冷启动回退。
63
+
64
+ 输出产物不保留任务和答案明文,但词法哈希不保证匿名。`revision` 是内容变化标识,不是来源认证或签名;严格解析只能校验声明的格式,不能证明评分和来源真实。
65
+
66
+ ## 可选结构验收与一次升级
67
+
68
+ `qualityEscalationEnabled` 默认 `false`。在 `qualityGateJson` 中填写 JSON 文本,例如:
69
+
70
+ ```json
71
+ {
72
+ "kind": "json-object",
73
+ "requiredKeys": ["answer"],
74
+ "fieldTypes": {"answer": "string", "sources": "array"}
75
+ }
76
+ ```
77
+
78
+ 空文本或 `{}` 表示没有 gate。仅支持 `json-object`,只接受完整 JSON 对象,不从散文或 Markdown 代码块提取 JSON。`requiredKeys` 最多 32 个安全键;`fieldTypes` 支持 `string`、`number`、`boolean`、`object`、`array`、`null`,只检查存在的自身字段;需要必填的字段须同时列入 `requiredKeys`。未知配置字段、非法类型和危险键会被拒绝。JSON 数字必须有限。
79
+
80
+ gate 检查结构,不判断回答是否正确。首次通过、没有 gate、升级关闭、请求失败、取消、阻塞、暂停或截断,都不会因此多调用模型。只有显式启用升级、首次结构验收失败、存在不同 provider/model 的已配置合格 API 替代路线,并通过预算与计费批准,才最多再调用一次;不循环重跑同一模型。
81
+
82
+ 当前自动质量升级适用于普通 API 工作包:原路线和替代路线均须显式配置 `execution: "api"`,或属于没有官方工具映射的提供方;两者都排除显式 `subscription-first`、`subscription-only` 和 `execution: "official"`,也排除计费计划识别出的任何订阅(含编程套餐名称与关联 `apiRoute`)。有官方工具映射的 API 路线可用 `subscription: "none"` 明确普通 API 身份。替代路线的已知质量先验须高于原路线。CLI、编程套餐订阅调用和 direct 强制指定模型不会自动换模型升级。首次调用已经产生的 usage、价格快照和报告费用会保留在 `qualityAttempts` 中;批准回调失败、第二次失败或两次之间取消,都不能抹掉首次消耗。不同模型的 token 不合并成一个虚假的单模型账单。部分费用未知时 `costUsd` 保持 `null`,已知部分另以 `knownCostUsd` 计入日/月已知小计,并保留未知标记。
83
+
84
+ ## 验证与解释边界
85
+
86
+ ```powershell
87
+ npm run test:routing-algorithm
88
+ node --test tests/routing-search-experiment.test.mjs tests/routing-search-summary.test.mjs tests/routing-search-frontier.test.mjs tests/routing-optimizer.test.mjs
89
+ ```
90
+
91
+ 搜索回归同时检查独立穷举 oracle、预算、随机 DAG、档位交接和顺序稳定性。已知 6561 组合反例恢复了零交接解;1728 组合反例的无预算 beam 路径也与 oracle 一致。不过宽度 1 的紧预算条件仍可能损失目标效用,测试继续保留这一差距。固定池上的这些结果不能代替真实模型质量与总成本评估。
@@ -1,8 +1,8 @@
1
1
  # 模型路由工作台:配置、规划与实际执行
2
2
 
3
- 适用版本:`@ljwei-stak/dsh-model-router@0.21.1`。声明兼容 DeepSeek Harness Desktop `0.2.0-rc.1 / 0.2.0-rc.2 / 0.2.1-rc.2`。安装与开发见[中文 README](../README.zh.md),旧包迁移见[迁移说明](archive/MIGRATION.md)。
3
+ 适用版本:`@ljwei-stak/dsh-model-router@0.22.1`。声明兼容 DeepSeek Harness Desktop `0.2.0-rc.1 / 0.2.0-rc.2 / 0.2.1-rc.2`。安装与开发见[中文 README](../README.zh.md),旧包迁移见[迁移说明](archive/MIGRATION.md)。
4
4
 
5
- 0.21.1 支持在统一根目录的 `hermes-agent` 子目录安装 Hermes 源码,插件使用该源码内的独立命令入口;保留现有配置、登录及历史数据的位置。官方工具终端移到本页顶部。
5
+ 0.22.0 新增“按算法推荐分配 / 手动调整分配”:生成任务建议后,可为每个工作包选择模型 API 或官方工具;修改后重新预览费用与渠道,再确认执行。任务依赖与重跑目标保留。手动混合执行当前只读,官方工具使用自身默认模型;编辑文件继续选择官方工具协作。详见[手动分配说明](MANUAL_TASK_ASSIGNMENT.zh.md)。Hermes 自定义程序目录、原配置/登录/历史位置,以及工具页顶部终端的行为继续保留。
6
6
 
7
7
  0.21.0 新增 Hermes Agent 与 Pi 的安装更新、版本检测及交互终端,OpenCode npm/pnpm 切换至官方 V2 包。Hermes 与 Pi 的登录由各自 CLI 完成,暂不提供经过验证的托管执行器。
8
8
 
@@ -0,0 +1,28 @@
1
+ # 0.22.0 release acceptance
2
+
3
+ Date: 2026-10-19. Package: `@ljwei-stak/dsh-model-router@0.22.0`.
4
+
5
+ This release combines routing algorithm improvements and the algorithm/manual work-package assignment choice. It retains the existing plugin identity, saved configuration, execution history and supported DSH SDK versions.
6
+
7
+ ## Automated and UI checks
8
+
9
+ - Full suite: 966 tests, 963 passed, 0 failed, 3 existing platform-dependent skips. Skipped PTY/process checks do not count as real execution acceptance.
10
+ - The manual-assignment increment adds 45 tests covering strict targets, task-decomposition identity, complete preflight validation, pinned APIs, exact tools, subscription restrictions, budget behavior, mixed dependency context, stored intent and retries.
11
+ - Twelve Chromium interactions against the actual workbench component and offline fixtures passed: default algorithm mode, per-package manual controls, unavailable tool choices, mixed-target preview, stale confirmation invalidation, simulated execution and stored tool intent, restore, return to algorithm mode, single-package adjustment, direct mode, 390-pixel layout and stale asynchronous responses. Screenshots were inspected. These use simulated data and no paid model calls.
12
+ - `pnpm install --frozen-lockfile --strict-peer-dependencies` with pinned pnpm 10.34.6, the actual client build, generated-client consistency, workbench preview compilation, package preflight and `git diff --check` passed.
13
+ - Before publication, the generated tarball is checked against the exact release commit's Git blobs; after publication, registry and GitHub Release assets are downloaded and compared with that verified tarball. The release audit records the commit and tarball digests separately.
14
+
15
+ One development run of the existing Windows multi-process state test encountered an `EPERM` while opening its lock file. Five isolated rechecks and the final full suite passed. This release does not claim to fix that intermittent locking behavior.
16
+
17
+ ## Behavioral boundaries
18
+
19
+ - Manual mixed API/tool execution is read-only. Editing remains in the existing official-team workflow with its isolated worktree and permission checks.
20
+ - An explicit API target uses the selected provider/model and adapter-default effort. It is not replaced by CLI preference, budget downgrade or automatic quality escalation. Subscription-only and coding-plan routes cannot bypass their billing policy by being selected as ordinary APIs.
21
+ - A selected official tool uses its own configured default model. Missing installation, execution support or readiness blocks execution before the first paid package; failure does not silently switch to API. Unknown tool prices stay unknown.
22
+ - Objective task evidence requires valid training observations and enough matching samples. Resource P90 values are empirical estimates, not joint budget guarantees. Beam search remains approximate over retained candidates. The tests establish mechanisms rather than measured production routing quality or savings.
23
+ - JSON validation checks structure, not semantic truth. Automatic escalation defaults to off and permits at most one eligible API upgrade after budget approval, retaining every attempt's known or unknown cost.
24
+ - Exact SDK effort requests do not establish the provider's actual internal reasoning effort. Official CLI effort mappings remain unsupported.
25
+
26
+ No new real provider or vendor CLI model execution was performed for 0.22.0. Earlier real execution evidence remains in the dated [0.20.0 report](0.20.0-validation.md); it is not relabeled as evidence for this release's new behavior. Hermes/Pi managed execution remains unverified.
27
+
28
+ Upgrade by fully quitting Harness, including its tray and Host process, updating the plugin to 0.22.0, and restarting.