dsh-llm-verifier 0.8.0 → 0.8.4
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 +4 -2
- package/lib/{auto-CGbckoaX.js → auto-DpNooy0d.js} +46 -2
- package/lib/{auto-CGbckoaX.js.map → auto-DpNooy0d.js.map} +1 -1
- package/lib/index.js +7 -2
- package/lib/index.js.map +1 -1
- package/lib/replay.js +1 -1
- package/lib/types/auto.d.ts +16 -0
- package/lib/types/auto.d.ts.map +1 -1
- package/lib/types/auto.js +37 -9
- package/lib/types/auto.js.map +1 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +16 -1
- package/lib/types/index.js.map +1 -1
- package/package.json +24 -24
- package/src/auto.test.ts +42 -1
- package/src/auto.ts +39 -10
- package/src/index.test.ts +34 -0
- package/src/index.ts +16 -1
package/README.md
CHANGED
|
@@ -98,7 +98,7 @@ DSH 0.1.7 又搬动了两处判定地基,两侧形态插件都读:
|
|
|
98
98
|
|
|
99
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
100
|
|
|
101
|
-
typecheck 门禁按 `package.json` 的 `devDependencies`
|
|
101
|
+
typecheck 门禁按 `package.json` 的 `devDependencies` 解析,已随宿主推进到 `0.1.7-rc.1`(此前从 `0.1.1-rc.2` 上移到 `0.1.7-alpha.1`):客户端面的图标名在 0.1.7 才改名,一份源码只能对齐一侧,宿主面的旧形态兼容由运行时代码与回归测试保证。从 `0.1.7-alpha.1` 到 `0.1.7-rc.1` 的宿主改动对本插件消费的所有宿主面**全是加法**(`tools/pre-execute` 侧只新增可选 `projectContent`,`dsh-session` / `dsh-llm` / `dsh-settings` / `dsh-agent` / `dsh-credentials` / 客户端槽位与图标包源码零改动),因此这一步只换版本线,不动插件代码。
|
|
102
102
|
|
|
103
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`。
|
|
104
104
|
|
|
@@ -108,7 +108,7 @@ typecheck 门禁按 `package.json` 的 `devDependencies` 解析,本轮已从 `
|
|
|
108
108
|
|
|
109
109
|
发布内容由 `package.json` 的 `files` 字段决定:`lib`(构建产物、source map 与 `lib/types` 类型声明)、`src`、`cordis.patch.yml`、`README.md`。`tsconfig.local.json` 之类的本机文件不会进入 tarball。
|
|
110
110
|
|
|
111
|
-
`peerDependencies` 中逐个列出的 `^0.1.5-alpha.1`、`^0.1.7-alpha.1`
|
|
111
|
+
`peerDependencies` 中逐个列出的 `^0.1.5-alpha.1`、`^0.1.7-alpha.1`、`^0.1.7-rc.1` 等预发布范围是必需的,而且从 DSH 0.1.7-rc.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.*` 等宿主)。宿主启动 profile 时对每一个 `@deepseek-ai/dsh` / `@deepseek-ai/dsh-*` 条目跑 `semver.satisfies(运行版本, 范围, { includePrerelease: true })`,**任何一条不满足**就把该插件行停用(bundle 层直接跳过整个 bundle),并在 stderr 写出原因。所以缺少某条宿主版本线的后果不是"少个功能",而是**插件整体不加载**;应急可用 `dsh plugin allow-version` 为该插件的精确版本做一次性豁免。当前声明覆盖到 `0.1.7-rc.1`,与本机 `dsh --version` 报告的运行版本一致。
|
|
112
112
|
|
|
113
113
|
统计数据有两条传输路径:优先走 `/api/llm-verifier/statistics`(Connection 的 exact Fetch 路由,带 Host/Origin 栅栏与浏览器鉴权),宿主较旧时回落到插件自己的 `/llm-verifier` RPC 通道(同样经过鉴权)。裸的 webServer 路由已被移除。
|
|
114
114
|
|
|
@@ -514,6 +514,8 @@ Workflow 候选在被记录后的**下一步主模型请求之前**就会评审
|
|
|
514
514
|
|
|
515
515
|
候选选择产生 steering 后,Agent 必须实施胜出候选;进度未达阈值也会 steering 继续。任何自动 `compare/select/track` 成功都会设置 `finalVerificationRequired`,下一停止边界即使没有传统写入类工具也必须执行 `verifier_current_session`;只有针对最新快照且达到阈值的最终验收才能清除要求(计划预审通过**不会**设置该标记:批准计划不等于完成工作)。路由采用 reservation/commit/fail 状态,取消、过期或失败不会被误记为成功;strict 会维持阻断并 fail closed。自动反馈按**真实结果**措辞:唯一最高分才报 "Winner / Proceed with",最高分并列会列出并列集合并说明没有唯一依据,逐字节相同的候选说明"未做质量比较"——**不会**把稳定排序的第一项说成赢家;最终验收不通过时会列出未达标的判据、判官实际读到的区间,以及被长度上限省略的字符数(没有逐项判据时如实说明缺少定位依据)。以上文案是确定性的,不额外调用模型。**交付阶段**(本任务 Todo 全部完成且存在一次真实验证运行)在停止边界跳过进度 track 直接最终验收:Todo 完成只决定"送去验收",不决定通过,验证失败也照常送到裁判眼前;同一完成信号只消费一次,新工作或新验证结果才会重新激活,且未处理的候选选择优先于该快路径。
|
|
516
516
|
|
|
517
|
+
**计划模式(plan mode)激活期间,自动门控整体挂起**:停止边界的所有自动路由、Team 任务验收与最终验收、`agent/pre-step` 的候选早评审与过程选优登记全部跳过(以会话日志中最后一条 `plan/mode` 事件折叠判定,空日志视为未激活)。此时 Agent 的职责是调研与提案,唯一仍运行的门是 `exit_plan_mode` 计划预审——否则验收必然对着尚未实施的方案判低分,并 steering「去实际执行」,等于在用户批准计划之前就命令 Agent 动手。计划获批退出计划模式后,下一停止边界照常恢复验收。
|
|
518
|
+
|
|
517
519
|
显式调用 `verifier_current_session` **不会**无条件关闭自动门控:只有该次复核真的达到通过阈值(`winner === 'A'`、分数不低于阈值,**且每一项标准各自不低于阈值**——与自动门控同一条 `sessionAccepted` 规则,否则显式调用会变成绕过单项失败的漏洞),并且之后没有再产生实质工作(写文件、执行命令等)时,才会被当作"已完成验收"而放行。判决失败、低于阈值、结果无法解析、或通过之后又继续改动的复核,都不会解除门控——下一停止边界仍会照常验收。此外,Agent Teams 的队友会话以 `team-message` 作为任务边界,因此队友会话同样可以触发(并遵守)任务级门控;Team 任务验收与计划预审都要求裁判给出显式的 `Verdict: <A-T>` 行,解析不出来时:计划预审放行(预算耗尽时 deny 会死锁 plan mode,只能放行),**Team 任务验收在 strict 下照常阻断**,与其它自动阶段一致。
|
|
518
520
|
|
|
519
521
|
`track` 采用**离线**打分:判官在给较早的检查点打分时已经看到了它之后的内容,因此曲线偏乐观。门控只用**最新**检查点(它之后没有内容,不存在"未来泄露"),曲线展示时请把它读作"判官回看整段会话时的判断",而不是逐步在线估计;上游的 `ProgressTracker` 是逐步在线形态,代价是每一步一次调用,本插件不采用。
|
|
@@ -2157,6 +2157,27 @@ function inspectUserInteractionPause(events, taskStartSeq, currentTurn) {
|
|
|
2157
2157
|
}
|
|
2158
2158
|
}
|
|
2159
2159
|
}
|
|
2160
|
+
/**
|
|
2161
|
+
* Whether the session is currently in plan mode.
|
|
2162
|
+
*
|
|
2163
|
+
* The host logs one `plan/mode` event per committed transition and folds the log as
|
|
2164
|
+
* "empty log → inactive, last event wins" (its own projection does exactly this). Hosts
|
|
2165
|
+
* without plan mode never log the event, so nothing changes there. While planning, the
|
|
2166
|
+
* agent is expected to research and PROPOSE: any automatic route or acceptance verdict at
|
|
2167
|
+
* the turn-stopping boundary can only fail against the missing implementation and steer
|
|
2168
|
+
* "actually implement it" — commanding execution the human has not approved yet. The
|
|
2169
|
+
* `exit_plan_mode` pre-review is the one gate that still runs in this state.
|
|
2170
|
+
* @param events - Session event log (the whole log is folded; the mode may predate the task).
|
|
2171
|
+
* @returns True when the newest `plan/mode` event activated plan mode.
|
|
2172
|
+
*/
|
|
2173
|
+
function planModeActive(events) {
|
|
2174
|
+
let active = false;
|
|
2175
|
+
for (const event of events) {
|
|
2176
|
+
if (event.type !== "plan/mode") continue;
|
|
2177
|
+
active = event.data?.active === true;
|
|
2178
|
+
}
|
|
2179
|
+
return active;
|
|
2180
|
+
}
|
|
2160
2181
|
function analyzeAutoTask(events, policy, sessionId) {
|
|
2161
2182
|
const taskStartSeq = latestDirectUserSeq(events);
|
|
2162
2183
|
if (taskStartSeq === void 0) return {
|
|
@@ -2168,6 +2189,7 @@ function analyzeAutoTask(events, policy, sessionId) {
|
|
|
2168
2189
|
manualVerificationAccepted: false,
|
|
2169
2190
|
pendingSubagents: false,
|
|
2170
2191
|
pendingUserInteraction: false,
|
|
2192
|
+
planMode: planModeActive(events),
|
|
2171
2193
|
eligible: false,
|
|
2172
2194
|
reason: "no-direct-user-task"
|
|
2173
2195
|
};
|
|
@@ -2227,6 +2249,7 @@ function analyzeAutoTask(events, policy, sessionId) {
|
|
|
2227
2249
|
});
|
|
2228
2250
|
const pendingSubagents = hasPendingSubagents(events, taskStartSeq);
|
|
2229
2251
|
const pendingUserInteraction = inspectUserInteractionPause(events, taskStartSeq) !== void 0;
|
|
2252
|
+
const planMode = planModeActive(events);
|
|
2230
2253
|
if (policy.mode === "manual") return {
|
|
2231
2254
|
taskStartSeq,
|
|
2232
2255
|
toolCalls,
|
|
@@ -2236,9 +2259,23 @@ function analyzeAutoTask(events, policy, sessionId) {
|
|
|
2236
2259
|
manualVerificationAccepted,
|
|
2237
2260
|
pendingSubagents,
|
|
2238
2261
|
pendingUserInteraction,
|
|
2262
|
+
planMode,
|
|
2239
2263
|
eligible: false,
|
|
2240
2264
|
reason: "manual-mode"
|
|
2241
2265
|
};
|
|
2266
|
+
if (planMode) return {
|
|
2267
|
+
taskStartSeq,
|
|
2268
|
+
toolCalls,
|
|
2269
|
+
completedToolResults,
|
|
2270
|
+
consequentialToolCalls,
|
|
2271
|
+
hasManualSessionVerification,
|
|
2272
|
+
manualVerificationAccepted,
|
|
2273
|
+
pendingSubagents,
|
|
2274
|
+
pendingUserInteraction,
|
|
2275
|
+
planMode: true,
|
|
2276
|
+
eligible: false,
|
|
2277
|
+
reason: "plan-mode-active"
|
|
2278
|
+
};
|
|
2242
2279
|
if (manualVerificationAccepted) return {
|
|
2243
2280
|
taskStartSeq,
|
|
2244
2281
|
toolCalls,
|
|
@@ -2248,6 +2285,7 @@ function analyzeAutoTask(events, policy, sessionId) {
|
|
|
2248
2285
|
manualVerificationAccepted,
|
|
2249
2286
|
pendingSubagents,
|
|
2250
2287
|
pendingUserInteraction,
|
|
2288
|
+
planMode,
|
|
2251
2289
|
eligible: false,
|
|
2252
2290
|
reason: "already-verified"
|
|
2253
2291
|
};
|
|
@@ -2260,6 +2298,7 @@ function analyzeAutoTask(events, policy, sessionId) {
|
|
|
2260
2298
|
manualVerificationAccepted,
|
|
2261
2299
|
pendingSubagents: true,
|
|
2262
2300
|
pendingUserInteraction,
|
|
2301
|
+
planMode,
|
|
2263
2302
|
eligible: false,
|
|
2264
2303
|
reason: "pending-subagents"
|
|
2265
2304
|
};
|
|
@@ -2272,6 +2311,7 @@ function analyzeAutoTask(events, policy, sessionId) {
|
|
|
2272
2311
|
manualVerificationAccepted,
|
|
2273
2312
|
pendingSubagents,
|
|
2274
2313
|
pendingUserInteraction: true,
|
|
2314
|
+
planMode,
|
|
2275
2315
|
eligible: false,
|
|
2276
2316
|
reason: "user-interaction-paused"
|
|
2277
2317
|
};
|
|
@@ -2284,6 +2324,7 @@ function analyzeAutoTask(events, policy, sessionId) {
|
|
|
2284
2324
|
manualVerificationAccepted,
|
|
2285
2325
|
pendingSubagents,
|
|
2286
2326
|
pendingUserInteraction,
|
|
2327
|
+
planMode,
|
|
2287
2328
|
eligible: false,
|
|
2288
2329
|
reason: "no-consequential-work"
|
|
2289
2330
|
};
|
|
@@ -2296,6 +2337,7 @@ function analyzeAutoTask(events, policy, sessionId) {
|
|
|
2296
2337
|
manualVerificationAccepted,
|
|
2297
2338
|
pendingSubagents,
|
|
2298
2339
|
pendingUserInteraction,
|
|
2340
|
+
planMode,
|
|
2299
2341
|
eligible: false,
|
|
2300
2342
|
reason: "no-completed-evidence"
|
|
2301
2343
|
};
|
|
@@ -2308,6 +2350,7 @@ function analyzeAutoTask(events, policy, sessionId) {
|
|
|
2308
2350
|
manualVerificationAccepted,
|
|
2309
2351
|
pendingSubagents,
|
|
2310
2352
|
pendingUserInteraction,
|
|
2353
|
+
planMode,
|
|
2311
2354
|
eligible: false,
|
|
2312
2355
|
reason: "insufficient-tool-evidence"
|
|
2313
2356
|
};
|
|
@@ -2320,6 +2363,7 @@ function analyzeAutoTask(events, policy, sessionId) {
|
|
|
2320
2363
|
manualVerificationAccepted,
|
|
2321
2364
|
pendingSubagents,
|
|
2322
2365
|
pendingUserInteraction,
|
|
2366
|
+
planMode,
|
|
2323
2367
|
eligible: true,
|
|
2324
2368
|
reason: policy.mode + "-eligible"
|
|
2325
2369
|
};
|
|
@@ -2487,6 +2531,6 @@ function selectRouteFeedbackDetail(candidates, result, maxChars = MAX_ROUTE_FEED
|
|
|
2487
2531
|
].join("\n"));
|
|
2488
2532
|
}
|
|
2489
2533
|
//#endregion
|
|
2490
|
-
export {
|
|
2534
|
+
export { routedRepeats as A, SingleFlight as B, estimateRoutedCalls as C, latestDirectUserSeq as D, itemBudget as E, verificationVerdict as F, stableHash as H, extractSession as I, sanitizeVerifierText as L, semanticReferencesVisible as M, semanticRouteHint as N, nextDiagnosticCycleId as O, verificationFailed as P, sessionEvents as R, buildSemanticRouteView as S, inspectRecoverySignal as T, resolveCacheFile as V, RECOVERY_FAILURE_CONTEXT_CHARS as _, compareRouteFeedbackDetail as a, buildEvidenceIndex as b, inspectUserInteractionPause as c, planModeActive as d, selectRouteFeedbackDetail as f, MAX_ROUTED_CHECKPOINTS as g, AutoVerifierRouter as h, automaticFeedback as i, semanticDecision as j, parseSemanticRoute as k, isAwaitingUserText as l, topScoreIndices as m, PROPOSAL_FEEDBACK_NOTE as n, failedAcceptanceCriteria as o, sessionAccepted as p, analyzeAutoTask as r, hasPendingSubagents as s, MAX_ROUTE_FEEDBACK_CHARS as t, isSubagentSession as u, analyzeStructuredRoute as v, inspectDeliveryPhase as w, buildSemanticRoutePrompt as x, boundDecision as y, ScoreCache as z };
|
|
2491
2535
|
|
|
2492
|
-
//# sourceMappingURL=auto-
|
|
2536
|
+
//# sourceMappingURL=auto-DpNooy0d.js.map
|