dsh-llm-verifier 0.9.0 → 0.9.3
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/client.js +73 -18
- package/lib/client.js.map +1 -1
- package/lib/types/client.d.ts +20 -3
- package/lib/types/client.d.ts.map +1 -1
- package/lib/types/client.js +31 -6
- package/lib/types/client.js.map +1 -1
- package/package.json +24 -24
- package/src/client.test.ts +21 -3
- package/src/client.tsx +45 -7
- package/src/router.test.ts +14 -0
- package/src/session.test.ts +18 -0
package/README.md
CHANGED
|
@@ -98,12 +98,14 @@ 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` 解析,已随宿主推进到 `0.2.0-rc.
|
|
101
|
+
typecheck 门禁按 `package.json` 的 `devDependencies` 解析,已随宿主推进到 `0.2.0-rc.2`(此前从 `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
|
`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
|
|
|
105
105
|
`0.2.0-rc.1` 也是只换版本线:插件消费的宿主面在这一线全是加法(`dsh-session` 新导出 `ToolCallRecovery`、`ui-conversation` 提交契约新增可选 `source` 参数与 `MessageSubmission`、`ui-primitives` 新增 `pointerModality` 导出、`api/remotes` 新增 productAnalytics remote)。唯一的行为变化在宿主侧:step 抛错时 agent-loop 会为未完成的工具调用补写合成的失败 `tool/result` 事件(`role: 'tool'` 消息、消息级 `isError: true`、`error.code` 为 `TOOL_NOT_STARTED` / `TOOL_OUTCOME_UNKNOWN`)——这正是 0.1.7 形态的工具结果,`toolResultFailed()` 原样读出"失败",路由不会把合成结果当作观测证据,插件无需任何适配代码。
|
|
106
106
|
|
|
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
|
+
|
|
107
109
|
其中一处更隐蔽的差异是 `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`。
|
|
108
110
|
|
|
109
111
|
### 发布到 npm
|
|
@@ -112,7 +114,7 @@ typecheck 门禁按 `package.json` 的 `devDependencies` 解析,已随宿主
|
|
|
112
114
|
|
|
113
115
|
发布内容由 `package.json` 的 `files` 字段决定:`lib`(构建产物、source map 与 `lib/types` 类型声明)、`src`、`cordis.patch.yml`、`README.md`。`tsconfig.local.json` 之类的本机文件不会进入 tarball。
|
|
114
116
|
|
|
115
|
-
`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.2.0-rc.
|
|
117
|
+
`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.2.0-rc.2`,与本机 `dsh --version` 报告的运行版本一致。
|
|
116
118
|
|
|
117
119
|
统计数据有两条传输路径:优先走 `/api/llm-verifier/statistics`(Connection 的 exact Fetch 路由,带 Host/Origin 栅栏与浏览器鉴权),宿主较旧时回落到插件自己的 `/llm-verifier` RPC 通道(同样经过鉴权)。裸的 webServer 路由已被移除。
|
|
118
120
|
|
package/lib/client.js
CHANGED
|
@@ -3421,7 +3421,8 @@ window.__ModuleLoader__.load({
|
|
|
3421
3421
|
//#endregion
|
|
3422
3422
|
//#region src/client.tsx
|
|
3423
3423
|
/**
|
|
3424
|
-
*
|
|
3424
|
+
* The one glyph still borrowed from the host, resolved by name across the two vocabularies this
|
|
3425
|
+
* plugin spans.
|
|
3425
3426
|
*
|
|
3426
3427
|
* DSH 0.1.7 renamed the whole host icon set from a size suffix to a stroke suffix
|
|
3427
3428
|
* (`IconDataOutline16` → `IconDataOutlineRegular`). The icon module is external to this bundle, so
|
|
@@ -3429,9 +3430,11 @@ window.__ModuleLoader__.load({
|
|
|
3429
3430
|
* React throws on an undefined element type, which would take the entire settings page down
|
|
3430
3431
|
* instead of dropping one glyph. Probing the namespace at runtime keeps one bundle working on
|
|
3431
3432
|
* either line; a name that neither line defines renders nothing.
|
|
3433
|
+
*
|
|
3434
|
+
* The statistics mark is deliberately NOT in this list: every host glyph paints on `currentColor`,
|
|
3435
|
+
* so as a guide entry it rendered grey-on-navy. `VerifierSidebarIcon` paints its own brand ramp.
|
|
3432
3436
|
*/
|
|
3433
3437
|
const hostIcons = _deepseek_ai_dsh_client_ui_primitives;
|
|
3434
|
-
const IconData = hostIcons.IconDataOutlineRegular ?? hostIcons.IconDataOutline16 ?? (() => null);
|
|
3435
3438
|
const IconRefresh = hostIcons.IconRefreshOutlineRegular ?? hostIcons.IconRefreshOutline16 ?? (() => null);
|
|
3436
3439
|
const NS = "llm-verifier";
|
|
3437
3440
|
const shell = {
|
|
@@ -5014,12 +5017,9 @@ window.__ModuleLoader__.load({
|
|
|
5014
5017
|
display: "grid",
|
|
5015
5018
|
placeItems: "center",
|
|
5016
5019
|
width: 34,
|
|
5017
|
-
height: 34
|
|
5018
|
-
borderRadius: 10,
|
|
5019
|
-
background: "color-mix(in srgb, var(--dsw-alias-state-business-primary) 14%, transparent)",
|
|
5020
|
-
color: "var(--dsw-alias-state-business-primary)"
|
|
5020
|
+
height: 34
|
|
5021
5021
|
},
|
|
5022
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
5022
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(VerifierSidebarIcon, { size: 26 })
|
|
5023
5023
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
5024
5024
|
style: {
|
|
5025
5025
|
margin: 0,
|
|
@@ -6039,17 +6039,72 @@ window.__ModuleLoader__.load({
|
|
|
6039
6039
|
})
|
|
6040
6040
|
});
|
|
6041
6041
|
}
|
|
6042
|
-
|
|
6043
|
-
|
|
6044
|
-
|
|
6045
|
-
|
|
6046
|
-
|
|
6047
|
-
|
|
6048
|
-
|
|
6049
|
-
|
|
6050
|
-
|
|
6051
|
-
|
|
6052
|
-
|
|
6042
|
+
/**
|
|
6043
|
+
* The statistics mark: a brand-gradient tile carrying the verifier's shield-and-check.
|
|
6044
|
+
*
|
|
6045
|
+
* The host's glyph vocabulary is monochrome by contract (every icon draws on
|
|
6046
|
+
* `currentColor`, and the guide capsule pins that ink to a grey label alias), so a
|
|
6047
|
+
* host icon registered as a guide entry always reads as grey-on-navy — dim next
|
|
6048
|
+
* to a plugin whose glyph is coloured. This mark therefore ships its own paint:
|
|
6049
|
+
* the same violet→blue→teal ramp the dashboard header already wears, a white
|
|
6050
|
+
* shield, and a check cut back out of the ramp in the badge's own coordinates.
|
|
6051
|
+
*
|
|
6052
|
+
* Props follow the host's `IconProps` shape (`size` is the square edge in px,
|
|
6053
|
+
* `className` is for placement), so the same component serves the guide capsule
|
|
6054
|
+
* (26px) and the dashboard header (26px in a 34px well).
|
|
6055
|
+
*
|
|
6056
|
+
* @param props - rendered size and placement class.
|
|
6057
|
+
* @returns the statistics badge.
|
|
6058
|
+
*/
|
|
6059
|
+
function VerifierSidebarIcon({ size = 26, className }) {
|
|
6060
|
+
const gradientId = `llm-verifier-badge-${(0, react.useId)().replace(/[^a-zA-Z0-9-]/g, "")}`;
|
|
6061
|
+
const paint = `url(#${gradientId})`;
|
|
6062
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
6063
|
+
width: size,
|
|
6064
|
+
height: size,
|
|
6065
|
+
viewBox: "0 0 24 24",
|
|
6066
|
+
fill: "none",
|
|
6067
|
+
"aria-hidden": "true",
|
|
6068
|
+
className,
|
|
6069
|
+
children: [
|
|
6070
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("defs", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("linearGradient", {
|
|
6071
|
+
id: gradientId,
|
|
6072
|
+
x1: "1.5",
|
|
6073
|
+
y1: "1",
|
|
6074
|
+
x2: "22.5",
|
|
6075
|
+
y2: "23",
|
|
6076
|
+
gradientUnits: "userSpaceOnUse",
|
|
6077
|
+
children: [
|
|
6078
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("stop", { stopColor: "#8A63FF" }),
|
|
6079
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("stop", {
|
|
6080
|
+
offset: "0.5",
|
|
6081
|
+
stopColor: "#4F7BFF"
|
|
6082
|
+
}),
|
|
6083
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("stop", {
|
|
6084
|
+
offset: "1",
|
|
6085
|
+
stopColor: "#2FC5C9"
|
|
6086
|
+
})
|
|
6087
|
+
]
|
|
6088
|
+
}) }),
|
|
6089
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
|
|
6090
|
+
width: "24",
|
|
6091
|
+
height: "24",
|
|
6092
|
+
rx: "7.5",
|
|
6093
|
+
fill: paint
|
|
6094
|
+
}),
|
|
6095
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
6096
|
+
d: "M12 4.4 18.4 6.9v5.2c0 3.6-2.7 6.4-6.4 7.6-3.7-1.2-6.4-4-6.4-7.6V6.9L12 4.4Z",
|
|
6097
|
+
fill: "#FFFFFF",
|
|
6098
|
+
fillOpacity: "0.94"
|
|
6099
|
+
}),
|
|
6100
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
6101
|
+
d: "M8.8 12.3 11 14.5 15.3 9.7",
|
|
6102
|
+
stroke: paint,
|
|
6103
|
+
strokeWidth: "2.1",
|
|
6104
|
+
strokeLinecap: "round",
|
|
6105
|
+
strokeLinejoin: "round"
|
|
6106
|
+
})
|
|
6107
|
+
]
|
|
6053
6108
|
});
|
|
6054
6109
|
}
|
|
6055
6110
|
function GlobalVerifierDashboard({ rpc }) {
|