dsh-llm-verifier 0.9.5 → 0.10.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.
- package/CHANGELOG.md +11 -0
- package/README.md +8 -2
- package/lib/index.js +28 -8
- package/lib/index.js.map +1 -1
- package/lib/types/index.d.ts +5 -3
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +33 -11
- package/lib/types/index.js.map +1 -1
- package/package.json +29 -26
- package/src/index.test.ts +58 -2
- package/src/index.ts +29 -13
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.10.0 - 2026-10-17
|
|
6
|
+
- **[DSH 0.2.1-alpha.5] 对齐宿主并采用新版兼容声明**
|
|
7
|
+
- 新增顶层 `engines.dsh`,供 0.2.1-alpha.3+ 宿主与插件市场优先读取;8 条 `@deepseek-ai/dsh-*` peer 保留为旧宿主回退,两套范围均覆盖 `0.2.1-alpha.1`–`alpha.5` 且由回归测试强制一致
|
|
8
|
+
- DSH 开发依赖精确锁定 `0.2.1-alpha.5`,避免 npm `next` 的 `0.2.1-rc.1` 被未审查地纳入类型门禁;`@deepseek-ai/cordis` 同步到 `4.0.5-alpha.2`,`pnpm peers check` 全绿
|
|
9
|
+
- **[修复] 子 Agent 动态在途探针改用真实执行状态**
|
|
10
|
+
- 不再把 `subagents.listChildren()` 的持久目录项误读为 `kind/activity` 活动记录;改用 `AgentRegistry.list()` 按父子关系发现运行中的后代,并以 visited 集合防环
|
|
11
|
+
- 旧 Job-backed 回退按宿主契约修正为 `jobs.list(agent.id)`;新版 managed activation 继续复用既有启动回执与 `subagent-settled` 日志判定,不把所有后台 Job 纳入门控
|
|
12
|
+
- **[新能力评估] 不为换新而替换稳定路径**
|
|
13
|
+
- 话题侧车不迁到实验性的 `appendPluginRecord()`;裁判传输不改写为 `prepareCall()`;PTC 展示 `meta` 不作为模型证据;`working-directory/change` 不改变侧车归属
|
|
14
|
+
- `index.test.ts` 新增清单一致性与 Agent/Job 动态探针回归
|
|
15
|
+
|
|
5
16
|
## 0.9.5 - 2026-10-15
|
|
6
17
|
|
|
7
18
|
- **[UI / 打包] 补上插件包图标**
|
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.2.1-alpha.5`(此前从 `0.1.1-rc.2` 上移到 `0.1.7-alpha.1` 并持续推进):客户端面的图标名在 0.1.7 才改名,一份源码只能对齐一侧,宿主面的旧形态兼容由运行时代码与回归测试保证。本次 npm `next` 已是更高的 `0.2.1-rc.1`,所以开发依赖不用 caret,避免门禁悄悄浮到尚未逐 tag 审查的版本。从 `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
|
`0.1.7-rc.2` 同样只换版本线:这一版给宿主加了「动态工具更新」机制,对插件全是新增的可选面(`dsh-llm` 的 `GenerateOptions.toolHistory?` 与 `ToolUpdate`、`dsh-session` 的 `Session.toolHistory()`、`dsh-tools` 的 `PreToolDecision.ask.displayReason?`)。插件不消费这套机制,宿主新增的事件与块类型也读不到它:宿主在工具名变化时追加的 `developer/message`(`role: 'developer'`,内容为 `tool-addition` / `tool-removal` 块)不属于观测证据,插件的 `if/else` 分发自然跳过它们;验收的"过期"判定只统计有结果的工具调用与 PTC 派发,因此这类中途追加的消息不会让已完成的验收失效。另需注意 DeepSeek provider 在这一版裂成两个包(`llm-deepseek-api-key` 与 `llm-deepseek-account`),但 profile 里的**条目 id 仍是 `llm-deepseek`**,设置命名空间与其中的 `baseURL` / `apiKeyEnv` 都没变,直连 logprobs 通道照常读到;新增的 `deepseek-account` provider 走账号令牌、没有 API key,直连通道对它不适用,按设计降级到显式标签通道。
|
|
104
104
|
|
|
@@ -106,6 +106,12 @@ typecheck 门禁按 `package.json` 的 `devDependencies` 解析,已随宿主
|
|
|
106
106
|
|
|
107
107
|
`0.2.0-rc.2` 同样是只换版本线:宿主落地「计时用户提问的两阶段结算」(前台超时返回 pending 工具结果,迟到回答以 `source.kind: 'user-question-reply'` 的 user-role 消息 steer 注入)与「定时提醒固定 framing」(消息以 `source.kind: 'schedule'` 注入),插件的 `session.ts`(`extractSession`)与 `router.ts`(`latestDirectUserSeq`)任务边界识别保持只认 `user` 与 `team-message`,迟到回答与定时提醒天然不会被误认为任务边界或任务陈述;`api/remotes` 新增挂载 `userQuestionsRemote`,`ui-primitives` 新增导出 `MenuGroup`,对插件均为可选/无破坏性增强,插件源码零改动。
|
|
108
108
|
|
|
109
|
+
`0.2.1-alpha.1`–`alpha.5` 的对齐包含三项实际改动:
|
|
110
|
+
|
|
111
|
+
- **兼容声明与依赖**:新增顶层 `engines.dsh`,供新版宿主兼容检查与插件市场读取;8 条 `@deepseek-ai/dsh-*` peer 保留为旧宿主回退,三者使用同一范围。开发依赖精确锁到 `0.2.1-alpha.5`,`@deepseek-ai/cordis` 同步到本地宿主要求的 `4.0.5-alpha.2`,`pnpm peers check` 不再有不满足项。
|
|
112
|
+
- **子 Agent 在途探针**:新版 managed activation 不再使用 Job-backed delegation,现有 `started subagent <id>` / `subagent-settled` 日志判定保持不变。动态补充探针不再把 `listChildren()` 的持久目录项误当活动状态,改用 `AgentRegistry.list()` 检查运行中的后代;旧 Job 回退则按宿主契约修正为 `jobs.list(agent.id)`。
|
|
113
|
+
- **新 API 取舍**:不把侧车迁到实验性的 `appendPluginRecord()`(格式迁移只尽力保留),不把裁判调用改为 `prepareCall()`(现有明确参数、直连 logprobs 与旧宿主回退没有收益),也不把 PTC 新增的展示用 `meta` 当作模型证据。
|
|
114
|
+
|
|
109
115
|
其中一处更隐蔽的差异是 `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`。
|
|
110
116
|
|
|
111
117
|
### 发布到 npm
|
|
@@ -114,7 +120,7 @@ typecheck 门禁按 `package.json` 的 `devDependencies` 解析,已随宿主
|
|
|
114
120
|
|
|
115
121
|
发布内容由 `package.json` 的 `files` 字段决定:`lib`(构建产物、source map 与 `lib/types` 类型声明)、`src`、`cordis.patch.yml`、`README.md`。`tsconfig.local.json` 之类的本机文件不会进入 tarball。
|
|
116
122
|
|
|
117
|
-
`peerDependencies`
|
|
123
|
+
`engines.dsh` 与 `peerDependencies` 中逐个列出的预发布范围都是必需的,而且从 DSH 0.1.7-rc.1 起**由宿主强制执行**:0.2.1-alpha.3 起,包自己的 `engines.dsh` 单独决定兼容性并忽略 DSH peers;该字段缺失时才回退为逐个检查 `@deepseek-ai/dsh` / `@deepseek-ai/dsh-*` peer。本插件保留两套完全相同的声明以覆盖新旧宿主,并用回归测试防止它们漂移。按 semver 规则,预发布版本只有在同一 `x.y.z` 段存在带预发布的比较符时才算满足,因此不能简化成 `>=0.1.1-rc.2 <0.2.0`(那样会漏掉 `0.1.2-alpha.*`、`0.1.5-rc.*`、`0.1.7-alpha.*` 等宿主)。判定使用 `semver.satisfies(运行版本, 范围, { includePrerelease: true })`,任何一条不满足就把插件行停用(bundle 层直接跳过整个 bundle),并在 stderr 写出原因;应急可用 `dsh plugin allow-version` 做精确版本豁免。当前声明覆盖到 `0.2.1-alpha.5`,与本机 checkout 一致;`@deepseek-ai/cordis` 不参与这道宿主门禁,但仍须满足包管理器的 peer 解析。
|
|
118
124
|
|
|
119
125
|
统计数据有两条传输路径:优先走 `/api/llm-verifier/statistics`(Connection 的 exact Fetch 路由,带 Host/Origin 栅栏与浏览器鉴权),宿主较旧时回落到插件自己的 `/llm-verifier` RPC 通道(同样经过鉴权)。裸的 webServer 路由已被移除。
|
|
120
126
|
|
package/lib/index.js
CHANGED
|
@@ -4983,26 +4983,46 @@ const PROBE_B = "The test should pass now.";
|
|
|
4983
4983
|
/** Bound the probe: a diagnostics button must not sit on the configured 5-minute timeout plus retries. */
|
|
4984
4984
|
const PROBE_TIMEOUT_MS = 3e4;
|
|
4985
4985
|
/**
|
|
4986
|
-
* Probe live
|
|
4986
|
+
* Probe live Agent and Job registries for delegated work owned by the agent that remains active.
|
|
4987
4987
|
*
|
|
4988
|
-
*
|
|
4988
|
+
* Catalog readers are not execution-state APIs: `listChildren()` returns durable identities, while
|
|
4989
|
+
* `listDescendants().activity` reports Session residency rather than unfinished work. Runtime probes
|
|
4990
|
+
* gracefully degrade when a registry is missing; the Session log remains the other evidence source.
|
|
4989
4991
|
* @param ctx - plugin Context.
|
|
4990
4992
|
* @param agent - calling Agent.
|
|
4991
4993
|
* @param signal - cancellation signal.
|
|
4992
|
-
* @returns True when live subagents or
|
|
4994
|
+
* @returns True when live subagents or legacy Job-backed subagents are actively running.
|
|
4993
4995
|
*/
|
|
4994
4996
|
async function hasLiveActiveSubagents(ctx, agent, signal) {
|
|
4997
|
+
if (signal?.aborted) return false;
|
|
4995
4998
|
try {
|
|
4996
|
-
const
|
|
4997
|
-
if (typeof
|
|
4998
|
-
const
|
|
4999
|
-
|
|
4999
|
+
const registry = (typeof ctx.get === "function" ? ctx.get("agents") : void 0) ?? ctx.agents;
|
|
5000
|
+
if (typeof registry?.list === "function") {
|
|
5001
|
+
const childrenOf = /* @__PURE__ */ new Map();
|
|
5002
|
+
for (const child of registry.list()) {
|
|
5003
|
+
const { parentSession, origin } = child.session.header;
|
|
5004
|
+
if (parentSession === void 0 || origin !== "subagent") continue;
|
|
5005
|
+
const siblings = childrenOf.get(parentSession) ?? [];
|
|
5006
|
+
siblings.push(child);
|
|
5007
|
+
childrenOf.set(parentSession, siblings);
|
|
5008
|
+
}
|
|
5009
|
+
const pending = [agent.id];
|
|
5010
|
+
const visited = /* @__PURE__ */ new Set();
|
|
5011
|
+
while (pending.length > 0) {
|
|
5012
|
+
const parentId = pending.shift();
|
|
5013
|
+
if (visited.has(parentId)) continue;
|
|
5014
|
+
visited.add(parentId);
|
|
5015
|
+
for (const child of childrenOf.get(parentId) ?? []) {
|
|
5016
|
+
if (child.status === "running") return true;
|
|
5017
|
+
pending.push(child.id);
|
|
5018
|
+
}
|
|
5019
|
+
}
|
|
5000
5020
|
}
|
|
5001
5021
|
} catch {}
|
|
5002
5022
|
try {
|
|
5003
5023
|
const jobs = (typeof ctx.get === "function" ? ctx.get("jobs") : void 0) ?? ctx.jobs;
|
|
5004
5024
|
if (typeof jobs?.list === "function") {
|
|
5005
|
-
const list = jobs.list(agent);
|
|
5025
|
+
const list = jobs.list(agent.id);
|
|
5006
5026
|
if (Array.isArray(list) && list.some((job) => (job.status === "running" || job.status === "stopping") && (job.kind === "subagent" || job.kind === void 0))) return true;
|
|
5007
5027
|
}
|
|
5008
5028
|
} catch {}
|