@morlay/ui-conversation-message-actions 0.0.17 → 0.0.19-alpha.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.
Files changed (45) hide show
  1. package/README.md +29 -98
  2. package/dist/client.cjs +1380 -0
  3. package/dist/client.d.cts +6 -0
  4. package/dist/client.d.mts +6 -0
  5. package/dist/index.d.cts +98 -0
  6. package/dist/index.d.mts +3 -10
  7. package/dist/index.mjs +460 -2
  8. package/dist/invariant.d.cts +7 -0
  9. package/dist/{plan-BSa7k9HO.d.mts → plan-CT_6Y1fD.d.cts} +11 -9
  10. package/dist/plan-Cm9hCord.d.mts +101 -0
  11. package/dist/plan.d.cts +2 -0
  12. package/dist/plan.d.mts +2 -2
  13. package/dist/plan.mjs +145 -11
  14. package/dist/shared-LK3nImWW.mjs +55 -0
  15. package/dist/testing.d.cts +3242 -0
  16. package/dist/testing.d.mts +25 -19
  17. package/dist/testing.mjs +2140 -3939
  18. package/package.json +35 -32
  19. package/src/client/chat-node/MessageIconActions.styles.ts +76 -0
  20. package/src/client/chat-node/MessageIconActions.tsx +30 -11
  21. package/src/client/chat-node/MessageItem.styles.ts +247 -0
  22. package/src/client/chat-node/MessageItem.tsx +32 -39
  23. package/src/client/chat-node/message-chrome.ts +0 -2
  24. package/src/client/chat-node/register.ts +3 -4
  25. package/src/client/chat-node/use-calendar-day.ts +0 -4
  26. package/src/client/composer-stats/StatsPills.styles.ts +57 -0
  27. package/src/client/composer-stats/StatsPills.tsx +384 -0
  28. package/src/client/composer-stats/register.ts +17 -0
  29. package/src/client/composer-stats/stat-dialog.styles.ts +70 -0
  30. package/src/client/composer-stats/stat-dialog.ts +52 -0
  31. package/src/client/composer-stats/token-format.ts +85 -0
  32. package/src/client/composer-stats/turn-reading.ts +35 -0
  33. package/src/client/controller.ts +32 -114
  34. package/src/client/index.ts +8 -24
  35. package/src/index.ts +102 -111
  36. package/src/plan.ts +189 -24
  37. package/src/shared.ts +1 -1
  38. package/src/testing.ts +1 -5
  39. package/src/types.ts +1 -1
  40. package/dist/client.js +0 -806
  41. package/dist/src-B4HwXsob.mjs +0 -499
  42. package/src/client/chat-node/MessageIconActions.module.css +0 -86
  43. package/src/client/chat-node/MessageItem.module.css +0 -290
  44. package/src/client/css-modules.d.ts +0 -4
  45. package/src/client/import-action.tsx +0 -74
package/README.md CHANGED
@@ -1,105 +1,36 @@
1
1
  # @morlay/ui-conversation-message-actions
2
2
 
3
- `rewind / retry / recall / fork` 的**编排层**:在 `@morlay/session-branch` 的 provider
4
- 抽象之上组装完整功能(产品语义对齐 [dsh-message-edit](https://github.com/Moeblack/dsh-message-edit)),
5
- 并提供**浏览器半**(client bundle):替换 `conversation.chat.node` 的
6
- `user` / `steering` 渲染,在 user 消息行内直接挂编辑 / 重试入口。
7
-
8
- ## 服务面(`ctx.sessionEditor`)
9
-
10
- | 操作 | 语义 |
11
- | ---------- | --------------------------------------------------------------------------------- |
12
- | `edit` | 编辑已落定文本块(用户消息 / 助手块),**就地**(rewind + 重写,session id 不变) |
13
- | `reroll` | 重生成最后一条已落定助手回复(使用原用户输入) |
14
- | `retry` | 重试任意历史回合(`truncate` 只重放目标输入 / `preserve` 重放后续全部) |
15
- | `rewind` | 截断式回退:原会话回退到闭合 `turn/end` 边界 |
16
- | `recall` | 撤回 user 消息到输入框:只 `rewind` 截断,不重写、不重放(交给用户改后重发) |
17
- | `fork` | 从任意闭合边界派生**新会话**(唯一产生新 id 的操作) |
18
- | `timeline` | 版本树投影(HTTP:`GET /session-editor?sessionId=…`) |
19
-
20
- ## 就地编辑语义
21
-
22
- - **edit / retry / reroll 是就地操作**:`rewind` 截断到目标轮之前的闭合
23
- `turn/end` 边界,再 `append` 版本效果 + 手工回合 / 重放输入回**同一会话**
24
- ——session id 不变,版本树保持单根;
25
- - **重放复用目标轮号**:轮首 user 编辑(含未闭合轮)整轮截断,重放接回原
26
- 轮号;编辑 assistant 写入 manualTurn 后同步 agent 的轮次游标;
27
- - **空轮吸收**:目标轮之前的空轮(`turn/start` 后直接 `turn/end`,早期重放
28
- 缺陷的遗留形状)随截断一并删除,重放按保留前缀续号——轮次导航不再出现
29
- 点不开的空项与轮号空洞;manualTurn 的轮号同样按保留前缀收敛(正常会话
30
- 等于目标轮号)。版本效果仍记录**原**目标轮号(操作历史);
31
- - **只有 `fork` 创建新 id**(`ForkOperation` / `forkFrom`,纯 append 派生);
32
- - **`recall` 只截断不重写**:轮内消息沿用 `edit` 的轮首规则(轮首整轮截断到前一轮
33
- `turn/end`,无前轮则清空全部;轮内 followup exclusive drop),轮外 user 消息
34
- (`location` 无轮次归属的排队落定消息)按消息自身位置 exclusive drop(截断该消息
35
- 及其后全部),但只 `rewind` 即返回——不写版本效果、不重放;被撤回的 user 文本由
36
- 浏览器半回填到 composer,用户修改后自行发送;
37
- - 版本效果事件(`session-branch/version`)携带 `ignorable: true`:**原样落库**
38
- (rdb 不按信封过滤,与 JSONL 一致),非 branch 读者凭信封跳过;
39
- - 重放输入经 agent 驱动(见下)排队到原会话,agent 基于截断后历史回复。
40
-
41
- ## agent 驱动(重放排队输入)
42
-
43
- `agents` 服务以 duck-typed 接口使用(不硬依赖 `@deepseek-ai/dsh-agent`),
44
- 缺失时退化为「已 durable 的就地版本」(可随时 resume 续跑):
45
-
46
- - **live agent**(会话驻留 / 已恢复):直接 `followup` 排队,不重建、不换 id;
47
- - **rewind 前必须停止运行中的 loop**:每次 rewind(edit / retry / reroll /
48
- recall / HTTP `rewind`)都先对驻留 agent `cancel({ kind: "user" }, { keepInbox: true })`
49
- 再 `whenIdle()`,然后才截断——截断会重写 agent 的 session 内存 log,不能与
50
- 运行中的 loop 并发;`keepInbox` 表示停止本身不丢弃待处理输入,残留排队输入由
51
- rewind 在截断后强制 durable 取消(session-rdb 的 live 会话钩子 `inbox.clear`);
52
- 实现无 `cancel` 能力时退化为等待其自然停下
53
- ([ADR 0005](./docs/adr/0005-rewind前主动停止运行中的loop.md));
54
- - **cold 会话**:`resume` 已持久化会话(`create` 对已持久化日志必失败),
55
- resume 后 agent 驻留(不 dispose,避免 session 被移出 store 破坏客户端窗口);
56
- - 模型 provider/model 在 **rewind 之前**从 `request/header` 解析(就地编辑
57
- 可能截断掉 header,编辑第一轮 boundary = -1 时尤甚)。
58
-
59
- ## 浏览器半(client bundle)
60
-
61
- `dist/client.js` 经 `__ModuleLoader__.load` 手递,替换 `conversation.chat.node`
62
- 的 `user` / `steering` 渲染:
63
-
64
- - **shadow 注册**:`user` / `steering` 两个 key 以 `priority: -1` 重新注册
65
- (最低优先级渲染,shadow 上游默认注册);其余 key 沿用上游渲染器;
66
- - **编辑 / 重试按钮只挂在 user 消息**(`UserMessageNodeView`):编辑只要消息存在
67
- 可编辑文本块就显示(不要求轮次归属——`location` 无 turn/step 的已落定消息同样
68
- 可撤回),点击后不再打开编辑弹窗,而是确认(`Modal` + `Button`)后调用
69
- `recall`——服务端只 `rewind` 截断,客户端把消息文本 `setDraft` 回填到主输入框
70
- (`conversation.input`),交给用户修改后自行发送;重试仍先弹确认,且只对已闭合
71
- 轮次开放;
72
- - **操作后刷新**:就地编辑后优先调用客户端会话级 `resync()`(重置窗口并重新
73
- 拉取历史,不整页重载——rewind 的删除无法经 append-only 事件流表达,seq
74
- 回退只做增量会残留旧节点),随后丢弃该会话的全部投影行
75
- (`projections.truncate(-1)`)——投影 store 按 higher-seq-wins 保留 rewind
76
- 前的高 seq 旧值,截断后的正确值 seq 更小,永远覆盖不上(轮次导航残留已
77
- 删除的轮次);不可用时回退 `location.reload()`;
78
- - **构建约束**:client bundle 必须是**单文件**(client-modules 只服务/加载
79
- `client.js`)——`deps.neverBundle` 保持 react 与 `@deepseek-ai/*` external
80
- (平台 seed 词或独立插件,内联会把别的插件的 `__ModuleLoader__.load` 嵌进来
81
- 导致 duplicate factory),其余依赖全部内联,`inlineDynamicImports` 合并动态
82
- import;CSS Modules 经 lightningcss 内联 + `<style data-plugin>` 注入。
83
-
84
- ## 分层边界
3
+ `rewind / retry / recall / fork` 的**编排层**:在 `@morlay/session-branch` 的 provider 抽象之上组装完整功能(产品语义
4
+ 对齐 [dsh-message-edit](https://github.com/Moeblack/dsh-message-edit)),并提供**浏览器半**(client bundle):替换
5
+ `conversation.chat.node` 的 `user` / `steering` 渲染(在 user 消息行内直接挂编辑 / 重试入口),并覆盖
6
+ `conversation.composer.dock` 的 `stats` 行(composer 统计:修好的 token 口径 + `data-composer-stats`)。
7
+
8
+ ## 用法
9
+
10
+ 装配只需在 profile 的 `dsh.profile.bundles` 里列出本包——本包自带 bundle patch
11
+ ([`cordis.patch.yml`](./cordis.patch.yml))插入插件行并注册 `ctx.sessionEditor`。依赖 `ctx.sessionBranch` /
12
+ `ctx.sessionPersistence`(需先装配 provider 实现,如 `@morlay/session-rdb`)与 `ctx.sessions`;`agents` 可选,缺失时
13
+ 重放退化为「已 durable 的就地版本」。
14
+
15
+ ```ts
16
+ // host:装配后直接调服务
17
+ await ctx.sessionEditor.retry({ action: "retry", sessionId, turn: 2, cascade: "truncate" });
18
+ const timeline = await ctx.sessionEditor.timeline({ sessionId });
19
+ ```
85
20
 
86
- - 数据层(`forkFrom` / `rewind` / `readBranchPrefix`)来自
87
- `ctx.sessionBranch`(provider 实现,如 `@morlay/session-rdb`);
88
- - 本服务只做**编排**:闭合轮次扫描、版本效果事件构造、派生 seed 组装、
89
- rewind 命令透传、agent 驱动、HTTP 面(`POST /session-editor` 执行
90
- edit / reroll / retry / rewind / recall / fork)。
21
+ HTTP 面:web 模式 `POST` / `GET /session-editor`;宿主内嵌客户端走 `connection.fetch` 的 `/api/session-editor`。
91
22
 
92
- ## 装配
23
+ ## 结论
93
24
 
94
- ```yaml
95
- # cordis.patch.yml
96
- - insert:
97
- - id: ui-conversation-message-actions
98
- name: "@morlay/ui-conversation-message-actions"
99
- ```
25
+ edit / retry / reroll 就地重写**同一会话**(session id 不变、版本树单根),只有 `fork` 派生新 id;`recall` 只截断并把文本
26
+ 交回 composer,由用户改后自己发
27
+ ([ADR 就地编辑重写同一会话而非新建会话](./.agents/adrs/20260917-就地编辑重写同一会话而非新建会话.md))。
100
28
 
101
- 依赖 `ctx.sessionBranch` / `ctx.sessionPersistence`(需先装配
102
- `@morlay/session-rdb` 等 provider 实现)与 `ctx.sessions`;`agents` 可选。
29
+ ## 文档
103
30
 
104
- 端到端装配真实 rdb 后端,验证 retry / rewind / fork / timeline 闭环,
105
- 以及 live 会话的 rewind(内存 log 截断 / handle cursor 对齐)与 agent 重放。
31
+ - 操作语义全文(服务面 / 就地编辑 / agent 驱动 / 浏览器半 / 分层边界):
32
+ [设计 20260917-编排层操作语义](./.agents/designs/20260917-编排层操作语义.md)
33
+ - 决策:[`.agents/adrs/`](./.agents/adrs)(接管官方 `ui-conversation` 行、client bundle 单文件与 shadow 渲染、引用解析、
34
+ 编辑入口门控…)
35
+ - 接缝、测试落点与未覆盖:[本包规范 how-to-verify](./.agents/standards/how-to-verify.md)
36
+ - 整体设计:[设计 20260917-系统设计](../../../.agents/designs/20260917-系统设计.md)