@khorsheed/dsh-client-message-tools 0.3.3 → 0.3.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/CHANGELOG.md +8 -0
- package/README.en.md +2 -2
- package/README.i18n.yaml +2 -2
- package/README.md +2 -2
- package/lib/client.js +15137 -914
- package/lib/typert.host.js +79 -32
- package/lib/typert.remote-client.d.ts +7 -2
- package/lib/typert.remote-client.js +73 -31
- package/lib/types/client/UserMessageView.d.ts +7 -6
- package/lib/types/client/UserMessageView.js +9 -7
- package/lib/types/client/WithdrawnDividerView.d.ts +5 -2
- package/lib/types/client/WithdrawnDividerView.js +7 -7
- package/lib/types/client/chat-hook.js +3 -0
- package/lib/types/client/dom-hider.d.ts +28 -5
- package/lib/types/client/dom-hider.js +70 -3
- package/lib/types/client/message-images.d.ts +30 -0
- package/lib/types/client/message-images.js +17 -0
- package/lib/types/client/slots.d.ts +18 -3
- package/package.json +15 -17
- package/lib/invariant.js +0 -27
- package/lib/types/invariant.d.ts +0 -16
- package/lib/types/invariant.js +0 -25
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# 变更记录
|
|
2
2
|
|
|
3
|
+
## 0.3.4(2026-10-22)
|
|
4
|
+
|
|
5
|
+
适配宿主 0.2.1 线:verifiedHost 前移至 0.2.1-rc.1,`@deepseek-ai/dsh-*` peer 区间加宽覆盖 0.2.1 并声明 `engines.dsh`(`>=0.1.5-rc.1 <0.3.0-0`);退役 load 期 invariant 伴生探针(本包为空仪式,无行为变化)。
|
|
6
|
+
|
|
7
|
+
- **shadow 渲染跟随宿主字号轴**(修复 [Khorsheed/dsh-plugins#1](https://github.com/Khorsheed/dsh-plugins/issues/1),841ab4c0):shadow 用户气泡与撤回分隔线此前硬编码字号行高(气泡 16px/24px,是官方气泡迁 token 前的旧克隆)——非默认 `ui-theme.fontSize` 下 shadow 气泡比官方面大约 23%,默认字号下也是 16px 对官方 14px。现在气泡、分隔线标题、回放条目的字号行高全部镜像官方(ui-chat MessageItem)并跟随 body 发布的字号轴,标记与前导几何随轴缩放;模型 chip 属 composer chrome 保持固定
|
|
8
|
+
- **用户消息图片改经 0.2.1 官方图片工厂渲染**:0.2.1-alpha.3 移除 `renderMessageImages`、官方图廊迁到 ui-attachment 的 `conversation.images.content` 工厂;shadow 的两个视图在自身渲染里就地调用该工厂(与官方槽位条目同一渲染路径,像素一致),旧宿主优先走 legacy prop——0.1.5 至 0.2.1-alpha.2 行为不变,组合里没有 ui-attachment 时按官方同款语义省略不渲染、工厂后到即自愈。minHost 不变。见 [Agent Note](../../.agents/notes/implemented/architecture/2026-10-18-host-021-message-tools-images-factory.md)
|
|
9
|
+
- **修复编辑/撤回后「已调用工具」折叠头残留**:宿主 ≥0.1.7-alpha.1 把一轮的过程行包进按组键盖章的容器,此前的隐藏规则只按节点键逐行生效——成员行藏了,折叠头容器还亮着,被撤回的内容看似「只剩工具行」。现在组成员关系读官方类型化分组契约(而非 DOM),全部成员隐藏的组容器一并隐藏,部分隐藏的组保留其头。见 [Agent Note](../../.agents/notes/implemented/bug-fix/2026-10-14-message-tools-group-row-hiding.md)
|
|
10
|
+
|
|
3
11
|
## 0.3.3(2026-09-30)
|
|
4
12
|
|
|
5
13
|
无功能变更。加宽 `@deepseek-ai/dsh-*` peer 区间以覆盖宿主 0.2.0(0.2.0 的兼容闸会禁用 peer 区间不覆盖宿主版本的已装插件)。
|
package/README.en.md
CHANGED
|
@@ -39,7 +39,7 @@ dsh plugin --profile web remove @khorsheed/dsh-client-message-tools
|
|
|
39
39
|
## Compatibility
|
|
40
40
|
|
|
41
41
|
- npm release line (`@deepseek-ai/dsh@0.1.5-rc.1`): ✅ full — adapted to the 0.1.5-rc.1 format v2/v3 (`assistant/attempt` replaces `assistant/chunk`; the surfaceOp replace fields `start`/`end` are renamed `startSeq`/`endSeq`), full build+test green; minHost moves up to 0.1.5-rc.1 — older hosts stay on the previous release line. The Session V4 producer-owned source (kind `message-tools`) also writes durably on a 0.1.5 host: 0.1.5's `user/message` admission only requires a non-empty kind string.
|
|
42
|
-
- source line (deepseek-harness master): ✅ (verifiedHost: 0.1.
|
|
42
|
+
- source line (deepseek-harness master): ✅ (verifiedHost: 0.2.1-rc.1) — host-021 wave: full build+test green against the 0.2.1-rc.1 tree: the image arm consumes the official `conversation.images.content` factory in place on 0.2.1 (the 0.1.5–0.2.0 lines take the legacy-prop retention path); the shadow renderer's font size follows the host axis (Khorsheed/dsh-plugins#1). Session V4 adaptation: the write side moved to the producer-owned source (kind `message-tools`; V4 native admission refuses the retired `kind: 'plugin'` wrapper), and the read side accepts the new kind, `plugin:message-tools` (the V3→V4 migrated form), and the released V3 wrapper (served verbatim on a 0.1.5 host); the `conversation.chat.node` rc.1 contract (the new hookContext/inject shapes, the `SessionEventLike` match-event union) re-verified; the ui-primitives icon rename (`Icon*Outline14/16` → `Icon*OutlineMedium`) followed. 0.1.7-alpha.1's conversation grouping folds a turn's process rows into a group container (the「已调用工具」fold header carries the group key on the same DOM attribute), so the DOM hider now also covers the container keys of groups whose members are all hidden, plus the composite groupPart row keys; pre-0.1.7 hosts render rows ungrouped and stay covered by the plain node-key rules, unchanged.
|
|
43
43
|
|
|
44
44
|
**Version line mapping**: the first release after 0.2.0 supports host `0.1.5-rc.1` and later; hosts on `0.1.2-rc.1` stay on `0.2.0`, hosts on `0.1.0-rc.6` ~ `0.1.1-rc.2` stay on the 0.1.x release line (last release `0.1.0`).
|
|
45
45
|
|
|
@@ -61,7 +61,7 @@ dsh plugin --profile web remove @khorsheed/dsh-client-message-tools
|
|
|
61
61
|
|
|
62
62
|
**Withdrawal** is real, not a marker: the host appends a `user/message` surface replacement (the compaction mechanism) spanning the target and every surface node after it, so the span leaves `session.surface` and never reaches the model again; the same cancel-and-settle choreography as edit keeps streaming content from landing after the replacement. The event carries the producer-owned source (kind `message-tools`), cites every shadowed node in `sourceEventSeqs`, and is durable (`SessionStore.flush`) before the method returns — it is the audit trail. No new event type is introduced: an out-of-harness type cannot carry `ignorable: true`, and a persisted unknown type would make session-persistence refuse the log on reload. A landed withdrawal backfills the target's original text into the composer draft (blank fills, non-empty appends a new line, info notice) — never auto-sent, nothing on failure; edits never backfill.
|
|
63
63
|
|
|
64
|
-
**Projection and hiding.** The plugin's Definition claims the replacement into a divider anchored at its seq. Hiding is two-layer: the shadowed user renderer renders nothing inside a hidden span, and a dynamic stylesheet drops every chat row whose `data-chat-flow-key` (`ChatNodeSeat.tsx`) anchors inside the span, covering assistant steps, tool calls, and turn tails. The hider probes that undocumented attribute on its first non-empty rule set and, on a miss, enters a bounded retry (MutationObserver plus deadline) so a not-yet-mounted chat doesn't disable it; only an expired window disables it — one `console.warn`, renderer-only hiding — and the observer outlives the disable, so late-mounting rows reactivate it. It never throws. The divider expands in place to a read-only replay of the span (user originals — text and the images sent with them — plus assistant text, folded from the live node store; images render through the
|
|
64
|
+
**Projection and hiding.** The plugin's Definition claims the replacement into a divider anchored at its seq. Hiding is two-layer: the shadowed user renderer renders nothing inside a hidden span, and a dynamic stylesheet drops every chat row whose `data-chat-flow-key` (`ChatNodeSeat.tsx`) anchors inside the span, covering assistant steps, tool calls, and turn tails. The hider probes that undocumented attribute on its first non-empty rule set and, on a miss, enters a bounded retry (MutationObserver plus deadline) so a not-yet-mounted chat doesn't disable it; only an expired window disables it — one `console.warn`, renderer-only hiding — and the observer outlives the disable, so late-mounting rows reactivate it. It never throws. The divider expands in place to a read-only replay of the span (user originals — text and the images sent with them — plus assistant text, folded from the live node store; images render through the host's gallery surface — the `renderMessageImages` owner prop passed by pre-0.2.1-alpha.3 hosts when present, otherwise the shared root-scoped `conversation.images.content` factory provided by ui-attachment (0.2.1-alpha.3 split the images slot into `conversation.chat.user.images`/`conversation.chat.message.images` and the factory now carries the official gallery); with the factory unregistered, images are omitted, matching the official images slots' empty behavior) with the 「恢复到对话末尾」 action; a span whose rows fell out of the loaded window shows 「撤回的内容不在当前已加载的历史中」 instead.
|
|
65
65
|
|
|
66
66
|
**Restore** is a tail replay of the whole withdrawn span, never an in-place repair: the surface fold is positional — a replaced span splices into exactly one node (`applySurfacePlan`) — so the span cannot re-enter the model context where it was, and its model-side hiding is never undone. The host walks the log interval `[start, seq)` delimited by the replacement itself and appends every replayable entry in original order: user messages verbatim (an edit replacement's content IS the last edit's text, so it replays as such) and each assistant reply's text as a framed producer-sourced user message — `assistant/message` requires the model source and the trace forbids assistant appends outside a step, so role fidelity is carried by the frame `(以下是先前被撤回、现随恢复放回的助手回复)`, stripped from display. An interrupted attempt without `assistant/message` is merged from its `assistant/attempt` event's embedded compact stream (reasoning-only content preserved). Tool calls/results never replay: the pairing cannot be re-entered and side effects are not replayable. Replayed rows render as the 「已恢复」 group — user bubbles with the full action row, assistant text via the official `MarkdownText` — and the divider carries a 「已恢复」 badge while a live restore row cites the span; withdrawing the restored rows again clears the badge and re-enables the action (restore events stay in the log).
|
|
67
67
|
|
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# last confirmed-consistent state. Both languages carry equal authority; after
|
|
3
3
|
# editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/message-tools/README.en.md
|
|
5
|
-
packages/message-tools/README.en.md:
|
|
6
|
-
packages/message-tools/README.md:
|
|
5
|
+
packages/message-tools/README.en.md: be0592512db6b390fa808027cde00fe99c4aec65
|
|
6
|
+
packages/message-tools/README.md: c86325e3a9f094fe71cf5c4439d206fff0ac88f3
|
package/README.md
CHANGED
|
@@ -39,7 +39,7 @@ dsh plugin --profile web remove @khorsheed/dsh-client-message-tools
|
|
|
39
39
|
## Compatibility
|
|
40
40
|
|
|
41
41
|
- npm 发布线(`@deepseek-ai/dsh@0.1.5-rc.1`):✅ 完整——适配 0.1.5-rc.1 的 format v2/v3(`assistant/attempt` 取代 `assistant/chunk`;surfaceOp replace 字段 `start`/`end` 更名 `startSeq`/`endSeq`),全量构建测试通过;minHost 前移至 0.1.5-rc.1,旧宿主请停留在旧发布线。Session V4 的生产者归属 source(kind `message-tools`)在 0.1.5 宿主同样合法落盘:0.1.5 的 `user/message` 准入只要求非空 kind 字符串。
|
|
42
|
-
- 源码线(deepseek-harness master):✅(verifiedHost: 0.1.
|
|
42
|
+
- 源码线(deepseek-harness master):✅(verifiedHost: 0.2.1-rc.1)——host-021 波对 0.2.1-rc.1 树全量 build+test 绿:图片臂在 0.2.1 上就地消费官方 `conversation.images.content` 工厂(0.1.5–0.2.0 线走 legacy prop 保留路径);影子渲染器字号跟随宿主轴(Khorsheed/dsh-plugins#1)。Session V4 适配:写侧改生产者归属 source(kind `message-tools`,V4 原生准入拒绝退役的 `kind: 'plugin'` 包装),读侧兼认新 kind、`plugin:message-tools`(V3→V4 迁移形态)与 V3 包装存量(0.1.5 宿主原位读取);`conversation.chat.node` rc.1 契约(hookContext/inject 新形状、match 事件 `SessionEventLike` 并集)复验通过;ui-primitives 图标改名(`Icon*Outline14/16` → `Icon*OutlineMedium`)跟进。0.1.7-alpha.1 的会话分组渲染把一回合的过程行收进分组容器(「已调用工具」折叠头以分组键挂在同一 DOM 属性上),DOM 隐藏器现并入「成员全隐藏」分组的容器键与 groupPart 复合行键;0.1.7 之前的宿主没有分组渲染,原有节点键规则已覆盖,行为不变。
|
|
43
43
|
|
|
44
44
|
**版本线对照**:0.2.0 之后的首个发布起支持宿主 `0.1.5-rc.1` 及以后;宿主 `0.1.2-rc.1` 请停留在 `0.2.0`,宿主 `0.1.0-rc.6` ~ `0.1.1-rc.2` 请停留在 0.1.x 发布线(末版 `0.1.0`)。
|
|
45
45
|
|
|
@@ -61,7 +61,7 @@ dsh plugin --profile web remove @khorsheed/dsh-client-message-tools
|
|
|
61
61
|
|
|
62
62
|
**撤回**是真撤回,不是打标记:host 追加一条 `user/message` surface replacement(与 compaction 同一机制),区间覆盖目标消息及之后的所有 surface 节点,该区间由此离开 `session.surface`,不再进入模型上下文;与编辑同款的 cancel-and-settle 编排保证流式内容不会落到 replacement 之后。事件为生产者来源(source kind `message-tools`),`sourceEventSeqs` 引用每一个被遮蔽节点,方法返回前经 `SessionStore.flush` 落盘——它本身就是审计轨迹。不引入新事件类型:harness 之外的类型无法携带 `ignorable: true`,持久化的未知类型会让 session-persistence 重载时拒绝整个日志。撤回成功后把目标原文回填到 composer 草稿(空草稿直接填入、非空换行追加、落 info 提示)——绝不自动发送,失败则不回填;编辑路径不触发回填。
|
|
63
63
|
|
|
64
|
-
**投影与隐藏。** 插件的 Definition 把 replacement 认领为锚定在其 seq 上的分隔线节点。隐藏分两层:被遮蔽的用户渲染器对区间内用户消息渲染为空;一张动态样式表把 `data-chat-flow-key`(`ChatNodeSeat.tsx`)锚点落在区间内的聊天行一律隐藏,覆盖助手步骤、工具调用、turn 尾部。隐藏器在首个非空规则集探测这个未文档化属性,探测落空进入有界重试(MutationObserver 加截止时限),避免聊天区尚未挂载时误停用;只有窗口耗尽仍探不到行才停用——`console.warn` 一次,退化为仅渲染器隐藏——且 observer
|
|
64
|
+
**投影与隐藏。** 插件的 Definition 把 replacement 认领为锚定在其 seq 上的分隔线节点。隐藏分两层:被遮蔽的用户渲染器对区间内用户消息渲染为空;一张动态样式表把 `data-chat-flow-key`(`ChatNodeSeat.tsx`)锚点落在区间内的聊天行一律隐藏,覆盖助手步骤、工具调用、turn 尾部。隐藏器在首个非空规则集探测这个未文档化属性,探测落空进入有界重试(MutationObserver 加截止时限),避免聊天区尚未挂载时误停用;只有窗口耗尽仍探不到行才停用——`console.warn` 一次,退化为仅渲染器隐藏——且 observer 在停用后仍存活,行晚到会重新生效,绝不报错。分隔线可就地展开只读回放撤回区间(用户原文与随消息发出的图片、加助手文本,从实时节点存储折叠;图片经宿主画廊面渲染——0.2.1-alpha.3 之前的宿主透传的 `renderMessageImages` owner prop 在场时走它,否则经 root 作用域的共享 `conversation.images.content` 工厂(ui-attachment 提供;0.2.1-alpha.3 把原图片槽位拆分为 `conversation.chat.user.images`/`conversation.chat.message.images` 后由它承载官方画廊);工厂未注册时图片不渲染,与官方图片槽位空缺时的行为一致)并提供「恢复到对话末尾」;行已掉出加载窗口的区间显示「撤回的内容不在当前已加载的历史中」。
|
|
65
65
|
|
|
66
66
|
**恢复**是整个被撤回区间的尾部重放,不是原位修复:surface 折叠是位置性的——被替换区间只接续成一个节点(`applySurfacePlan`)——区间无法回到模型上下文原位,其模型侧隐藏也永不回退。host 沿撤回 replacement 自身划定的日志区间 `[start, seq)` 把可重放内容按原始顺序逐条追加到尾部:用户消息逐字重放(编辑替换的内容就是最后一次编辑的新文本,恢复时即以此为准),每条助手回复的文本以带框架的生产者来源用户消息重放——`assistant/message` 只能携带 model 来源,且轨迹不允许在 step 之外追加助手消息,因此角色保真由框架 `(以下是先前被撤回、现随恢复放回的助手回复)` 承担,UI 上不显示该框架。未落成 `assistant/message` 的中断尝试从其 `assistant/attempt` 事件内嵌的紧凑流合并重放(只有 reasoning 时保留 reasoning)。工具调用/结果永不重放:配对无法重新进入,副作用不可重放。重放行渲染为「已恢复」组——用户气泡带完整操作行,助手文本走官方 `MarkdownText`——分隔线在存在引用该区间的存活恢复行期间显示「已恢复」徽标;再次撤回这些恢复行会清掉徽标并重新启用恢复操作(恢复事件始终留在日志里)。
|
|
67
67
|
|