dsh-llm-verifier 0.6.9 → 0.8.0-beta.0

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.
Files changed (65) hide show
  1. package/README.md +11 -2
  2. package/lib/{auto-C9YG0E22.js → auto-CGbckoaX.js} +53 -10
  3. package/lib/auto-CGbckoaX.js.map +1 -0
  4. package/lib/{caller-Blp4l--v.js → caller-l5JwNkI3.js} +2 -5
  5. package/lib/caller-l5JwNkI3.js.map +1 -0
  6. package/lib/caller.js +1 -1
  7. package/lib/client.js +37 -9
  8. package/lib/client.js.map +1 -1
  9. package/lib/core.js +3 -3
  10. package/lib/core.js.map +1 -1
  11. package/lib/index.js +48 -50
  12. package/lib/index.js.map +1 -1
  13. package/lib/replay.js +1 -1
  14. package/lib/types/auto.d.ts.map +1 -1
  15. package/lib/types/auto.js +8 -7
  16. package/lib/types/auto.js.map +1 -1
  17. package/lib/types/caller.d.ts.map +1 -1
  18. package/lib/types/caller.js +1 -1
  19. package/lib/types/caller.js.map +1 -1
  20. package/lib/types/client.d.ts +28 -4
  21. package/lib/types/client.d.ts.map +1 -1
  22. package/lib/types/client.js +20 -3
  23. package/lib/types/client.js.map +1 -1
  24. package/lib/types/config.d.ts +16 -0
  25. package/lib/types/config.d.ts.map +1 -1
  26. package/lib/types/config.js +43 -2
  27. package/lib/types/config.js.map +1 -1
  28. package/lib/types/core.js +3 -3
  29. package/lib/types/core.js.map +1 -1
  30. package/lib/types/index.d.ts.map +1 -1
  31. package/lib/types/index.js +12 -12
  32. package/lib/types/index.js.map +1 -1
  33. package/lib/types/message-source.d.ts +26 -0
  34. package/lib/types/message-source.d.ts.map +1 -0
  35. package/lib/types/message-source.js +2 -0
  36. package/lib/types/message-source.js.map +1 -0
  37. package/lib/types/process-selection.d.ts.map +1 -1
  38. package/lib/types/process-selection.js +1 -1
  39. package/lib/types/process-selection.js.map +1 -1
  40. package/lib/types/router.js +12 -6
  41. package/lib/types/router.js.map +1 -1
  42. package/lib/types/session.d.ts +24 -0
  43. package/lib/types/session.d.ts.map +1 -1
  44. package/lib/types/session.js +35 -2
  45. package/lib/types/session.js.map +1 -1
  46. package/package.json +27 -27
  47. package/src/auto.test.ts +72 -53
  48. package/src/auto.ts +9 -7
  49. package/src/caller.ts +3 -1
  50. package/src/client.test.ts +27 -0
  51. package/src/client.tsx +47 -8
  52. package/src/config.test.ts +31 -1
  53. package/src/config.ts +45 -3
  54. package/src/core.ts +3 -3
  55. package/src/index.ts +14 -12
  56. package/src/message-source.ts +24 -0
  57. package/src/process-selection.test.ts +1 -1
  58. package/src/process-selection.ts +3 -1
  59. package/src/router.test.ts +104 -104
  60. package/src/router.ts +4 -4
  61. package/src/session.test.ts +43 -3
  62. package/src/session.ts +31 -1
  63. package/src/team-gate.test.ts +7 -7
  64. package/lib/auto-C9YG0E22.js.map +0 -1
  65. package/lib/caller-Blp4l--v.js.map +0 -1
package/README.md CHANGED
@@ -89,7 +89,16 @@ pnpm test # vitest 单元测试
89
89
  pnpm run typecheck:local # 依据 tsconfig.local.json,把 @deepseek-ai/dsh-* 解析到本地 checkout 的 lib/types
90
90
  ```
91
91
 
92
- 两套类型定义可能不同步:例如 `Session.events` 在 DSH 0.1.5 已被 `snapshotEvents()` 取代,`tool/code-dispatch` 也已改名 `tool/ptc-dispatch`。插件内部的 `sessionEvents()` 同时兼容两种会话形态,两类派发事件都会计入证据,因此 0.1.1 与 0.1.5 宿主都可以运行。
92
+ 两套类型定义可能不同步:例如 `Session.events` 在 DSH 0.1.5 已被 `snapshotEvents()` 取代,`tool/code-dispatch` 也已改名 `tool/ptc-dispatch`。插件内部的 `sessionEvents()` 同时兼容两种会话形态,两类派发事件都会计入证据,因此 0.1.1 与 0.1.7 宿主都可以运行。
93
+
94
+ DSH 0.1.7 又搬动了两处判定地基,两侧形态插件都读:
95
+
96
+ - **工具结果从内容块变成独立消息**。0.1.6 及以前,一条工具结果是一个 `tool-result` 内容块,真正的输出套在里面、失败标志 `isError` 挂在块上;0.1.7 删除了该块类型,工具结果改为 `role: 'tool'` 的独立消息,`isError` 上移到消息本身。`session.ts` 的 `toolResultBlocks()` / `toolResultFailed()` 是这两个差异的唯一读取点,旧宿主的嵌套输出仍会被渲染成 `[Tool Result]` 证据。
97
+ - **注入消息的来源改为生产者自报**。0.1.7 删除了 `MessageSourceMap` 的统一包装 `{ kind: 'plugin', plugin }`(持久化准入还会直接拒绝该包装),改为每个生产者声明自己的 `kind`。插件在 `src/message-source.ts` 声明并使用 `kind: 'llm-verifier'`;宿主读取旧日志时会把历史包装行改写成 `plugin:<名称>`,那只是历史行的显示名,不影响判定。
98
+
99
+ 客户端面(Web 设置页与看板)另有两处只随新版本线变化:提供 `ctx.slots` 的包是 `@deepseek-ai/dsh-client-ui-renderer`(`@deepseek-ai/dsh-client-runtime` 在 0.1.2 就已删除,插件类型一律取自 `@deepseek-ai/cordis` 的 `Context`);宿主图标名在 0.1.7 整体由尺寸后缀改为笔画后缀。图标是具名导入、且该模块对客户端 bundle 是 external,一份源码无法同时满足两套名字,因此插件改为按名探测两种拼写、都缺失时渲染空——旧宿主不会因此白屏。
100
+
101
+ typecheck 门禁按 `package.json` 的 `devDependencies` 解析,本轮已从 `0.1.1-rc.2` 上移到 `0.1.7-alpha.1`:客户端面的图标名同样在 0.1.7 才改名,一份源码只能对齐一侧,宿主面的旧形态兼容由运行时代码与回归测试保证。
93
102
 
94
103
  其中一处更隐蔽的差异是 `deepFreeze`:0.1.1 的 `@deepseek-ai/dsh-llm` 会重新导出它,0.1.5 已把它移到 `@deepseek-ai/dsh-util-values`。插件因此自带一份等价的兜底实现,并同样**放过 `AbortSignal`**——冻结那个还在重试循环里使用、尚未被订阅的信号,会让传输层首次 `addEventListener`(Node ≥26.5)或超时/取消时的 `controller.abort()`(所有 Node 版本)抛 `Cannot assign to read only property`。
95
104
 
@@ -99,7 +108,7 @@ pnpm run typecheck:local # 依据 tsconfig.local.json,把 @deepseek-ai/dsh-*
99
108
 
100
109
  发布内容由 `package.json` 的 `files` 字段决定:`lib`(构建产物、source map 与 `lib/types` 类型声明)、`src`、`cordis.patch.yml`、`README.md`。`tsconfig.local.json` 之类的本机文件不会进入 tarball。
101
110
 
102
- `peerDependencies` 中逐个列出的 `^0.1.5-alpha.1`、`^0.1.5-rc.1` 等预发布范围是必需的:按 semver 规则,预发布版本只有在同一 `x.y.z` 段存在带预发布的比较符时才算满足,因此不能简化成 `>=0.1.1-rc.2 <0.2.0`(那样会漏掉 `0.1.2-alpha.*`、`0.1.5-rc.*` 等宿主)。
111
+ `peerDependencies` 中逐个列出的 `^0.1.5-alpha.1`、`^0.1.7-alpha.1` 等预发布范围是必需的:按 semver 规则,预发布版本只有在同一 `x.y.z` 段存在带预发布的比较符时才算满足,因此不能简化成 `>=0.1.1-rc.2 <0.2.0`(那样会漏掉 `0.1.2-alpha.*`、`0.1.5-rc.*`、`0.1.7-alpha.*` 等宿主)。
103
112
 
104
113
  统计数据有两条传输路径:优先走 `/api/llm-verifier/statistics`(Connection 的 exact Fetch 路由,带 Host/Origin 栅栏与浏览器鉴权),宿主较旧时回落到插件自己的 `/llm-verifier` RPC 通道(同样经过鉴权)。裸的 webServer 路由已被移除。
105
114
 
@@ -184,6 +184,34 @@ function sessionEvents(session) {
184
184
  if (typeof candidate?.snapshotEvents === "function") return candidate.snapshotEvents();
185
185
  return candidate?.events ?? [];
186
186
  }
187
+ /**
188
+ * Inner blocks of a pre-0.1.7 nested `tool-result` block.
189
+ *
190
+ * DSH 0.1.6 and earlier modelled a tool result as a `tool-result` content block wrapping the
191
+ * result's own blocks inside the answering message. DSH 0.1.7 deleted that block type: the tool
192
+ * result is now a tool-role message whose `content` IS those blocks. Both shapes are still read,
193
+ * because the plugin declares support for hosts on either side of the change.
194
+ * @param block - one content block, possibly the legacy wrapper.
195
+ * @returns The wrapped blocks, or undefined when this is not a legacy wrapper.
196
+ */
197
+ function toolResultBlocks(block) {
198
+ if (block.type !== "tool-result") return void 0;
199
+ const inner = block.content;
200
+ return Array.isArray(inner) ? inner : void 0;
201
+ }
202
+ /**
203
+ * Whether one tool result reports a failed invocation.
204
+ *
205
+ * DSH 0.1.7 moved the flag from the nested `tool-result` block onto the tool-role message itself
206
+ * (`isError`); earlier hosts carry it on the block. Both are read so a failure is never scored as
207
+ * a success on either host.
208
+ * @param message - the `tool/result` event's message.
209
+ * @returns True when either host's shape marks the invocation as failed.
210
+ */
211
+ function toolResultFailed(message) {
212
+ if (message.isError === true) return true;
213
+ return message.content.some((block) => block.isError === true);
214
+ }
187
215
  function textOf(blocks) {
188
216
  const parts = [];
189
217
  for (const block of blocks) {
@@ -191,8 +219,10 @@ function textOf(blocks) {
191
219
  if (blockType === "text") parts.push(block.text);
192
220
  else if (blockType === "reasoning") parts.push("[Reasoning] " + block.text);
193
221
  else if (blockType === "tool-call") parts.push("[Tool Call] " + block.name + " " + block.arguments);
194
- else if (blockType === "tool-result") parts.push("[Tool Result] " + textOf(block.content));
195
- else if (blockType === "file") {
222
+ else if (blockType === "tool-result") {
223
+ const nested = toolResultBlocks(block);
224
+ if (nested) parts.push("[Tool Result] " + textOf(nested));
225
+ } else if (blockType === "file") {
196
226
  const fileData = block;
197
227
  parts.push("[File] " + (fileData.path ?? fileData.filename ?? fileData.title ?? "attachment"));
198
228
  }
@@ -346,7 +376,10 @@ function blockText$1(blocks) {
346
376
  const parts = [];
347
377
  const visit = (items) => {
348
378
  for (const block of items) if (block.type === "text" || block.type === "reasoning") parts.push(block.text);
349
- else if (block.type === "tool-result") visit(block.content);
379
+ else {
380
+ const nested = toolResultBlocks(block);
381
+ if (nested) visit(nested);
382
+ }
350
383
  };
351
384
  visit(blocks);
352
385
  return parts.join("\n").trim();
@@ -365,13 +398,16 @@ function narrativeText$1(blocks) {
365
398
  const parts = [];
366
399
  const visit = (items) => {
367
400
  for (const block of items) if (block.type === "text") parts.push(block.text);
368
- else if (block.type === "tool-result") visit(block.content);
401
+ else {
402
+ const nested = toolResultBlocks(block);
403
+ if (nested) visit(nested);
404
+ }
369
405
  };
370
406
  visit(blocks);
371
407
  return parts.join("\n").trim();
372
408
  }
373
409
  function successful(event) {
374
- return event.data.error === void 0 && event.data.message.content.every((block) => block.isError !== true);
410
+ return event.data.error === void 0 && !toolResultFailed(event.data.message);
375
411
  }
376
412
  function strictJson(text) {
377
413
  const trimmed = text.trim();
@@ -1770,14 +1806,22 @@ const PASSIVE_TOOLS = /* @__PURE__ */ new Set([
1770
1806
  "glob",
1771
1807
  "grep",
1772
1808
  "web_search",
1809
+ "web_fetch",
1773
1810
  "ssh_list",
1774
1811
  "job_list",
1775
1812
  "job_output",
1776
1813
  "list_agents",
1814
+ "list_subagent_models",
1815
+ "list_mcp_resources",
1816
+ "list_mcp_resource_templates",
1817
+ "read_mcp_resource",
1777
1818
  "get_goal",
1778
1819
  "skill",
1779
1820
  "mcp__codegraph__codegraph_explore",
1780
- "ask_user_question"
1821
+ "ask_user_question",
1822
+ "todo_write",
1823
+ "present",
1824
+ "run_code"
1781
1825
  ]);
1782
1826
  const VERIFIER_TOOLS = /* @__PURE__ */ new Set([
1783
1827
  "verifier_compare",
@@ -1791,7 +1835,6 @@ const CONSEQUENTIAL_TOOLS = /* @__PURE__ */ new Set([
1791
1835
  "write",
1792
1836
  "pwsh",
1793
1837
  "bash",
1794
- "run_code",
1795
1838
  "codex_image_generate",
1796
1839
  "ssh_exec",
1797
1840
  "ssh_upload",
@@ -1911,7 +1954,7 @@ function hasPendingSubagents(events, taskStartSeq) {
1911
1954
  if (event.type === "tool/result") {
1912
1955
  const call = calls.get(String(event.data.message.source.callId));
1913
1956
  if (call && SUBAGENT_TOOLS.has(call.data.name) && event.data.error === void 0) {
1914
- if (event.data.message.content.every((b) => b.isError !== true)) {
1957
+ if (!toolResultFailed(event.data.message)) {
1915
1958
  const text = blockText(event.data.message.content);
1916
1959
  const contMatch = text.match(CONTINUABLE_SUBAGENT_START);
1917
1960
  const jobMatch = text.match(BACKGROUND_SUBAGENT_JOB_START);
@@ -2136,7 +2179,7 @@ function analyzeAutoTask(events, policy, sessionId) {
2136
2179
  if (event.type !== "tool/result") continue;
2137
2180
  allResults.set(String(event.data.message.source.callId), event);
2138
2181
  if (event.data.error !== void 0) continue;
2139
- if (!event.data.message.content.every((block) => block.isError !== true)) continue;
2182
+ if (toolResultFailed(event.data.message)) continue;
2140
2183
  results.set(String(event.data.message.source.callId), event);
2141
2184
  }
2142
2185
  const pairedCalls = calls.filter((event) => results.has(String(event.data.callId)));
@@ -2446,4 +2489,4 @@ function selectRouteFeedbackDetail(candidates, result, maxChars = MAX_ROUTE_FEED
2446
2489
  //#endregion
2447
2490
  export { semanticDecision as A, resolveCacheFile as B, inspectDeliveryPhase as C, nextDiagnosticCycleId as D, latestDirectUserSeq as E, extractSession as F, sanitizeVerifierText as I, sessionEvents as L, semanticRouteHint as M, verificationFailed as N, parseSemanticRoute as O, verificationVerdict as P, ScoreCache as R, estimateRoutedCalls as S, itemBudget as T, stableHash as V, analyzeStructuredRoute as _, compareRouteFeedbackDetail as a, buildSemanticRoutePrompt as b, inspectUserInteractionPause as c, selectRouteFeedbackDetail as d, sessionAccepted as f, RECOVERY_FAILURE_CONTEXT_CHARS as g, MAX_ROUTED_CHECKPOINTS as h, automaticFeedback as i, semanticReferencesVisible as j, routedRepeats as k, isAwaitingUserText as l, AutoVerifierRouter as m, PROPOSAL_FEEDBACK_NOTE as n, failedAcceptanceCriteria as o, topScoreIndices as p, analyzeAutoTask as r, hasPendingSubagents as s, MAX_ROUTE_FEEDBACK_CHARS as t, isSubagentSession as u, boundDecision as v, inspectRecoverySignal as w, buildSemanticRouteView as x, buildEvidenceIndex as y, SingleFlight as z };
2448
2491
 
2449
- //# sourceMappingURL=auto-C9YG0E22.js.map
2492
+ //# sourceMappingURL=auto-CGbckoaX.js.map