@deepseek-ai/dsh-client-ui-message-feedback 0.1.3-alpha.2 → 0.1.5-alpha.2

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.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/client/ui-message-feedback/README.md
5
- README.md: 171a812acc836eec243eb9f596270359c0a3aa9c
6
- README.zh.md: e34eba9014779fc27bbd5a7ef071a086e8982f45
5
+ README.md: 8ffcf87a59ec95fe783a0379423b93d4bf965a3e
6
+ README.zh.md: a29448eaaddf0f089d8fc12c1315732fd13fc304
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "Per-message feedback for the Web GUI: the Like/Dislike pair and optional note in the finalized assistant message's action row; for users and maintainers of the feedback experience."
2
+ description: "The Web feedback surface: the Like/Dislike pair in the finalized assistant message's action row, the feedback dialog behind Dislike and `/feedback`, and the acknowledgement toast; for users and maintainers of the feedback experience."
3
3
  kind: "package-reference"
4
4
  ---
5
5
 
@@ -9,7 +9,7 @@ English | [中文](README.zh.md)
9
9
 
10
10
  ## Summary
11
11
 
12
- This package adds per-message feedback to the Web GUI: a Like/Dislike pair plus an optional note, contributed as the `feedback` entry of the finalized assistant message's action strip. It renders on the closing assistant message of each turn earlier steps of a multi-step turn produce tool rows rather than a rateable body. One controller per Session backs every message control in that Session, so a single list read seeds the whole transcript. Ratings and notes are log-only Session events: they never enter model context. Deletion retracts the current item without erasing its earlier log entries.
12
+ This package is the Web GUI's feedback surface: the Like/Dislike pair in the finalized assistant message's action strip, the feedback dialog with its acknowledgement toast in the composer overlay, and a decoration that opens the dialog from a bare `/feedback`. Like records at once and shows the toast; Dislike opens the dialog, which collects a category and an optional description. One surface per Session backs every entry, so a single list read seeds the whole transcript and one dialog serves the Session and its messages. Ratings, categories, and notes are log-only Session events that never enter model context.
13
13
 
14
14
  ## Table of Contents
15
15
 
@@ -25,11 +25,11 @@ This package adds per-message feedback to the Web GUI: a Like/Dislike pair plus
25
25
  <a id="use-this-package"></a>
26
26
  ## Use this package
27
27
 
28
- Mount this plugin alongside `ui-conversation`; the Like/Dislike pair then appears in the action row of each turn's closing assistant message, between copy and branch. Clicking the recorded rating retracts the feedback; switching sides carries the existing note forward. The note editor is a dialog popover anchored under its trigger, so the row keeps its single line whether the editor is open or closed.
28
+ Mount this plugin alongside `ui-conversation` and `ui-commands`; the Like/Dislike pair then appears in the action row of each turn's closing assistant message, between copy and branch, and the Feedback row of the composer menu opens the dialog. A recorded rating shows the filled glyph and stays visible without hover. Like records immediately and the toast thanks the user for the feedback. Dislike opens the dialog: seven category chips and a detail box, both optional; Submit records a negative judgment carrying whatever was filled in, and the conversation log travels with every feedback event. Clicking the recorded rating retracts it. A bare `/feedback`, picked from the menu or typed and sent without text, opens the same dialog for the Session; `/feedback <text>` keeps the Host command path and its acknowledgement row.
29
29
 
30
30
  ### Failures
31
31
 
32
- A rating or list-load failure shows inline in the row; a note-save failure shows inside the popover, which stays open so the draft can be corrected. Only finalized messages reach the slot — an interruption-frozen partial carries no `messageId` and therefore no feedback controls.
32
+ A rating or list-load failure shows inline in the row; a submission failure shows inside the dialog, which stays open so the draft can be corrected. Only finalized messages reach the message entry — an interruption-frozen partial carries no `messageId` and therefore no feedback controls.
33
33
 
34
34
  -----
35
35
 
@@ -39,7 +39,9 @@ A rating or list-load failure shows inline in the row; a note-save failure shows
39
39
  <details>
40
40
  <summary>Implementation internals — click to expand</summary>
41
41
 
42
- The package contributes the `feedback` entry (order 10) of `conversation.chat.assistant-actions`, declared by ui-conversation and rendered inside the finalized assistant message's IconActions row. One `MessageFeedbackController` per Session backs every message control in that Session, so a single `messageFeedback.list` read seeds the whole transcript; the read is deferred to the first hover or focus rather than fired on mount. Mutations go through `ctx.remote.messageFeedback`; the Host owns per-item compare-and-set. Every `put` and `delete` carries the `version` this controller last observed, and a `version-conflict` reply carries the authoritative item, so a lost race reconciles from the reply itself instead of refetching. Mutations serialize per Session, so a queued operation always compares against the committed version.
42
+ The package contributes the `feedback` entry (order 10) of `conversation.chat.assistant-actions`, declared by ui-conversation and rendered inside the finalized assistant message's IconActions row, and the `feedback-dialog` entry (order 2) of `conversation.input.overlay`, which renders the Modal and Toast primitives through body portals and centers the toast over the composer card it mounts inside. The `/feedback` decoration is an `action` registered through `ctx.commandUi.decorate`, so a menu pick or a bare Enter consumes the trigger token and opens the dialog while an argued line still reaches the Host command.
43
+
44
+ Per Session, one `MessageFeedbackController` backs every message control and one `FeedbackDialogController` owns the dialog draft, the submission, and the toast sequence. The message controller reads `messageFeedback.list` once, deferred to the first hover or focus rather than fired on mount, and serializes mutations so each carries the version last observed; a `version-conflict` reply carries the authoritative item and reconciles the view without refetching. `toggle` reports the rating now committed, so the row acknowledges a recorded Like and not a retraction. The dialog controller submits by target: a message target puts a negative judgment with the dialog's note and category through the message controller, and the Session target records through `ctx.remote.sessionFeedback`. Success closes the draft and raises the toast; a late success from a superseded draft raises the toast without closing the new draft; a failure keeps the draft open with its code.
43
45
 
44
46
  </details>
45
47
 
@@ -48,10 +50,12 @@ The package contributes the `feedback` entry (order 10) of `conversation.chat.as
48
50
  <a id="further-exploration"></a>
49
51
  ## Further Exploration
50
52
 
51
- Read these pages when the feedback surface is not enough. They move from the browser strip to the Session-log backend and the conversation shell.
53
+ Read these pages when the feedback surface is not enough. They move from the browser strip to the Session-log backends and the conversation shell.
52
54
 
53
55
  - [dsh-message-feedback](../../feedback/message-feedback/README.md) — the Session-log backend that owns per-item compare-and-set and persistence.
54
- - [ui-conversation](../ui-conversation/README.md) — declares the assistant-actions strip and renders the action row.
56
+ - [dsh-command-feedback](../../feedback/command-feedback/README.md) — the `/feedback` command, the `sessionFeedback` Remote, and the category taxonomy.
57
+ - [ui-commands](../ui-commands/README.md) — the command decoration contract the `/feedback` row goes through.
58
+ - [ui-conversation](../ui-conversation/README.md) — declares the assistant-actions strip and the composer overlay.
55
59
  - [Client package map](../README.md) — adjacent browser UI packages.
56
60
 
57
61
  -----
@@ -59,7 +63,7 @@ Read these pages when the feedback surface is not enough. They move from the bro
59
63
  <a id="model-experience"></a>
60
64
  ## Model Experience
61
65
 
62
- None, as ratings and notes are log-only events, not model input. Optional Session-log delivery uses request metadata rather than model context.
66
+ None, as ratings, categories, and notes are log-only events, not model input. Optional Session-log delivery uses request metadata rather than model context.
63
67
 
64
68
  #### KV Cache effect
65
69
 
@@ -72,7 +76,8 @@ None; feedback mutations leave the model-visible history unchanged.
72
76
 
73
77
  These limits define the current feedback surface. They are current package constraints, not a general rating comparison or a task backlog.
74
78
 
75
- - **Note size is a Host policy** — the deployment configures `maxNoteBytes` (8192 in the Web bundle) and the Host rejects an oversized note with `note-too-large`. The editor does not pre-check the limit, so an oversized note fails on save rather than while typing.
79
+ - **Note size is a Host policy** — the deployment configures `maxNoteBytes` (8192 in the Web bundle) and the Host rejects an oversized note with `note-too-large`. The dialog does not pre-check the limit, so an oversized description for a message fails on submit rather than while typing; a Session remark has no bound.
80
+ - **No note on a Like** — only the Dislike dialog collects a category and description; a Like records the bare judgment.
76
81
  - **No cross-tab push** — a second tab's rating becomes visible on reconnect or on the next conflict reply, not immediately; the controller does not consume feedback log events.
77
82
  - **Chat view only** — the trajectory and waterfall views render no feedback controls even though their assistant nodes carry the same `messageId`.
78
83
 
@@ -86,4 +91,4 @@ None.
86
91
 
87
92
  </details>
88
93
 
89
- **Runtime invariant:** No companion is published. The plugin owns one slot registration and one per-session controller map, both released by the same effect disposer. The lifecycle spec proves the registration is withdrawn and every controller is dropped when the owning fiber is disposed, so no second authority exists to check at runtime.
94
+ **Runtime invariant:** No companion is published. The plugin owns two slot registrations, one command decoration, and one per-session controller-pair map, all released by the plugin fiber's effect disposers. The lifecycle spec proves the registrations are withdrawn and every controller pair is dropped when the owning fiber is disposed, so no second authority exists to check at runtime.
package/README.zh.md CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "Web GUI 的逐消息反馈:已定稿助手消息动作行中的 Like/Dislike 对与可选备注;供反馈体验的用户与维护者阅读。"
2
+ description: "Web 反馈界面:已定稿助手消息动作行中的 Like/Dislike 对、点踩与 `/feedback` 背后的反馈弹窗,以及确认 toast;供反馈体验的用户与维护者阅读。"
3
3
  kind: "package-reference"
4
4
  ---
5
5
 
@@ -9,7 +9,7 @@ kind: "package-reference"
9
9
 
10
10
  ## 概述
11
11
 
12
- 本包为 Web GUI 增加逐消息反馈:一对 Like/Dislike 按钮加一个可选备注,作为已定稿助手消息动作条的 `feedback` 条目贡献。它渲染在每个轮次的收尾助手消息上——多步骤轮次中较早的步骤产出工具行而非可评分正文。每个 Session 一个控制器支撑该 Session 内所有消息的控件,因此一次列表读取即可填充整段对话。评分与备注是仅写日志的 Session 事件:它们绝不进入模型上下文。删除会撤回当前条目,但不会抹除早先的日志记录。
12
+ 本包是 Web GUI 的反馈界面:已定稿助手消息动作条中的 Like/Dislike 对、输入框浮层中的反馈弹窗及其确认 toast,以及让不带文本的 `/feedback` 打开弹窗的装饰。点赞立即记录并显示 toast;点踩打开弹窗,弹窗收集分类与可选描述。每个 Session 一个 surface 支撑所有条目,因此一次列表读取即可填充整段对话,一个弹窗同时服务 Session 与其消息。评分、分类与备注是仅写日志的 Session 事件,绝不进入模型上下文。
13
13
 
14
14
  ## 目录
15
15
 
@@ -25,11 +25,11 @@ kind: "package-reference"
25
25
  <a id="use-this-package"></a>
26
26
  ## 使用本包
27
27
 
28
- 与 `ui-conversation` 一起挂载本插件;Like/Dislike 对随即出现在每个轮次收尾助手消息的动作行中,位于复制与分支之间。再次点击已记录的评分会撤回反馈;切换到另一侧会保留既有备注。备注编辑器是一个锚定在其触发按钮下方的对话框浮层,因此无论编辑器是否打开,该行都保持单行。
28
+ 与 `ui-conversation`、`ui-commands` 一起挂载本插件;Like/Dislike 对随即出现在每个轮次收尾助手消息的动作行中,位于复制与分支之间,输入框菜单里的「反馈」行则打开弹窗。已记录的评分显示实心图标,不需要悬停也一直可见。点赞立即记录,toast 显示感谢反馈。点踩打开弹窗:七个分类标签和一个详情框,都可不填;提交会记录一条带上所填内容的差评,对话日志随每个反馈事件一起投递。再次点击已记录的评分会撤回它。不带文本的 `/feedback`,无论是从菜单选中还是直接输入后发送,都会为 Session 打开同一个弹窗;`/feedback <text>` 仍走宿主命令路径并显示确认行。
29
29
 
30
30
  ### 失败
31
31
 
32
- 评分或列表加载失败在行内展示;备注保存失败在浮层内展示,面板保持打开以便修正草稿。只有已定稿的消息能到达该槽位——被中断冻结的部分输出不带 `messageId`,因此没有反馈控件。
32
+ 评分或列表加载失败在行内展示;提交失败在弹窗内展示,弹窗保持打开以便修正草稿。只有已定稿的消息能到达消息条目——被中断冻结的部分输出不带 `messageId`,因此没有反馈控件。
33
33
 
34
34
  -----
35
35
 
@@ -39,7 +39,9 @@ kind: "package-reference"
39
39
  <details>
40
40
  <summary>实现细节——点击展开</summary>
41
41
 
42
- 本包贡献 `conversation.chat.assistant-actions` 的 `feedback` 条目(order 10),由 ui-conversation 声明并渲染在已定稿助手消息的 IconActions 行内。每个 Session 一个 `MessageFeedbackController` 支撑该 Session 内所有消息的控件,因此一次 `messageFeedback.list` 读取即可填充整段对话;该读取延迟到首次 hover focus 才发起,而非挂载时触发。变更经 `ctx.remote.messageFeedback` 提交,按条目的比较并交换由宿主负责。每次 `put` `delete` 都携带本控制器最后观察到的 `version`;`version-conflict` 响应带回权威条目,因此竞争失败时直接用该响应本身对账,无需重新拉取。变更按 Session 串行,排队中的操作总是与已提交的版本比较。
42
+ 本包贡献 `conversation.chat.assistant-actions` 的 `feedback` 条目(order 10),由 ui-conversation 声明并渲染在已定稿助手消息的 IconActions 行内;同时贡献 `conversation.input.overlay` `feedback-dialog` 条目(order 2),它通过 body portal 渲染 Modal Toast 基元,并让 toast 以其所在的输入框卡片为中心。`/feedback` 装饰是经 `ctx.commandUi.decorate` 注册的 `action`,因此菜单选中或不带参数的回车会消费触发 token 并打开弹窗,而带参数的命令行仍到达宿主命令。
43
+
44
+ 每个 Session 有一个 `MessageFeedbackController` 支撑所有消息控件,以及一个 `FeedbackDialogController` 拥有弹窗草稿、提交与 toast 序号。消息控制器只读取一次 `messageFeedback.list`,且延迟到首次 hover 或 focus 才发起,而非挂载时触发;变更串行执行,每次都携带最后观察到的版本,`version-conflict` 响应带回权威条目,据此对账视图而不重新拉取。`toggle` 会报告提交后的评分,因此该行只对记录成功的点赞做确认,撤回不做。弹窗控制器按目标提交:消息目标通过消息控制器 put 一条带弹窗备注与分类的差评,Session 目标通过 `ctx.remote.sessionFeedback` 记录。成功会关闭草稿并弹出 toast;被替换的旧草稿迟到的成功只弹 toast、不关闭新草稿;失败让草稿保持打开并带上失败码。
43
45
 
44
46
  </details>
45
47
 
@@ -48,10 +50,12 @@ kind: "package-reference"
48
50
  <a id="further-exploration"></a>
49
51
  ## 进一步探索
50
52
 
51
- 当反馈面不够用时阅读以下页面。它们从浏览器条带进入 Session 日志后端与会话外壳。
53
+ 当反馈界面不够用时阅读以下页面。它们从浏览器条带进入 Session 日志后端与会话外壳。
52
54
 
53
55
  - [dsh-message-feedback](../../feedback/message-feedback/README.zh.md)——拥有按条目比较并交换与持久化的 Session 日志后端。
54
- - [ui-conversation](../ui-conversation/README.zh.md)——声明助手动作条并渲染动作行。
56
+ - [dsh-command-feedback](../../feedback/command-feedback/README.zh.md)——`/feedback` 命令、`sessionFeedback` Remote 与分类表。
57
+ - [ui-commands](../ui-commands/README.zh.md)——`/feedback` 行所经过的命令装饰约定。
58
+ - [ui-conversation](../ui-conversation/README.zh.md)——声明助手动作条与输入框浮层。
55
59
  - [客户端包映射](../README.zh.md)——相邻的浏览器 UI 包。
56
60
 
57
61
  -----
@@ -59,7 +63,7 @@ kind: "package-reference"
59
63
  <a id="model-experience"></a>
60
64
  ## 模型体验
61
65
 
62
- 无。评分与备注是仅写日志的事件,不是模型输入。可选的 Session 日志投递使用请求元数据,而非模型上下文。
66
+ 无。评分、分类与备注是仅写日志的事件,不是模型输入。可选的 Session 日志投递使用请求元数据,而非模型上下文。
63
67
 
64
68
  #### KV Cache 影响
65
69
 
@@ -70,9 +74,10 @@ kind: "package-reference"
70
74
  <a id="known-limitations-and-deferred-work"></a>
71
75
 
72
76
 
73
- 这些限制界定了当前反馈表面。它们是当前包约束,不是通用评分对比或任务积压。
77
+ 这些限制界定了当前反馈界面。它们是当前包约束,不是通用评分对比或任务积压。
74
78
 
75
- - **备注大小是宿主策略**——部署方配置 `maxNoteBytes`(Web bundle 中为 8192),超长备注由宿主以 `note-too-large` 拒绝。编辑器不预先校验该上限,因此超长备注在保存时才失败,而不是在输入过程中。
79
+ - **备注大小是宿主策略**——部署方配置 `maxNoteBytes`(Web bundle 中为 8192),超长备注由宿主以 `note-too-large` 拒绝。弹窗不预先校验该上限,因此针对消息的超长描述在提交时才失败,而不是在输入过程中;Session 级备注没有上限。
80
+ - **点赞不带备注**——只有点踩弹窗收集分类与描述;点赞只记录判断本身。
76
81
  - **无跨标签页推送**——另一个标签页的评分要等到重连或下一次冲突响应才可见,不会立即出现;控制器不消费反馈日志事件。
77
82
  - **仅限对话视图**——trajectory 与 waterfall 视图不渲染反馈控件,尽管它们的助手节点也带有相同的 `messageId`。
78
83
 
@@ -86,4 +91,4 @@ kind: "package-reference"
86
91
 
87
92
  </details>
88
93
 
89
- **运行时不变式:** 不发布伴生入口。插件持有一个 slot 注册和按 Session controller map,两者由同一 effect disposer 释放;生命周期测试已直接观察该关系。
94
+ **运行时不变式:** 不发布伴生入口。插件持有两个 slot 注册、一个命令装饰和一个按 Session 的控制器对 map,全部由插件 fiber 的 effect disposer 释放;生命周期测试已直接观察注册被撤销、每对控制器被丢弃,因此运行时没有第二个可核对的权威。