@roaming-ai/dsh-group-chat 0.3.0 → 0.3.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.
Files changed (80) hide show
  1. package/README.md +93 -28
  2. package/lib/client.js +295 -326
  3. package/lib/client.js.map +1 -1
  4. package/lib/index.js +234 -221
  5. package/lib/types/client/components/AsidePanel.d.ts +3 -19
  6. package/lib/types/client/components/NavPanel.d.ts +9 -11
  7. package/lib/types/client/components/RoleDrawer.d.ts +3 -2
  8. package/lib/types/client/components/ToolRow.d.ts +2 -2
  9. package/lib/types/client/hooks/useGroupChatState.d.ts +0 -16
  10. package/lib/types/client/lib/model.d.ts +1 -7
  11. package/lib/types/client/utils/utils.d.ts +4 -4
  12. package/lib/types/core/json.d.ts +6 -0
  13. package/lib/types/core/types.d.ts +59 -64
  14. package/lib/types/host/engine/defaults.d.ts +13 -0
  15. package/lib/types/host/persistence/persistence.d.ts +2 -4
  16. package/lib/types/host/persistence/store.d.ts +5 -1
  17. package/lib/types/host/service.d.ts +2 -2
  18. package/lib/types/host/state.d.ts +1 -0
  19. package/lib/types/host/tools/tools.d.ts +2 -1
  20. package/lib/types/index.d.ts +3 -0
  21. package/lib/types/shared/file-mention-grammar.d.ts +3 -12
  22. package/package.json +4 -1
  23. package/src/client/GroupChatPanel.tsx +9 -56
  24. package/src/client/components/AsidePanel.tsx +40 -15
  25. package/src/client/components/ChatPanel.tsx +1 -1
  26. package/src/client/components/Composer.tsx +2 -2
  27. package/src/client/components/ConstraintList.tsx +1 -6
  28. package/src/client/components/MessageFlow.tsx +2 -1
  29. package/src/client/components/NavPanel.tsx +96 -78
  30. package/src/client/components/RoleDrawer.tsx +29 -7
  31. package/src/client/components/ToolRow.tsx +2 -2
  32. package/src/client/hooks/useComposer.ts +14 -53
  33. package/src/client/hooks/useGroupChatState.ts +2 -13
  34. package/src/client/lib/model.ts +1 -14
  35. package/src/client/lib/styles.ts +6 -2
  36. package/src/client/utils/utils.ts +6 -6
  37. package/src/core/constraints.ts +6 -12
  38. package/src/core/errors.ts +2 -12
  39. package/src/core/json.ts +17 -0
  40. package/src/core/types.ts +29 -20
  41. package/src/host/api/actions.ts +14 -13
  42. package/src/host/engine/conversation.ts +50 -51
  43. package/src/host/engine/defaults.ts +28 -0
  44. package/src/host/engine/fold.ts +2 -17
  45. package/src/host/engine/retitle.ts +9 -31
  46. package/src/host/materials/materials.ts +2 -0
  47. package/src/host/persistence/persistence.ts +57 -34
  48. package/src/host/persistence/store.ts +5 -1
  49. package/src/host/service.ts +4 -4
  50. package/src/host/state.ts +5 -2
  51. package/src/host/tools/tools.ts +42 -48
  52. package/src/index.ts +7 -5
  53. package/src/shared/file-mention-grammar.test.ts +1 -38
  54. package/src/shared/file-mention-grammar.ts +7 -33
  55. package/lib/types/client/Bubble.d.ts +0 -10
  56. package/lib/types/client/Glyph.d.ts +0 -12
  57. package/lib/types/client/GroupChatPanel.old.d.ts +0 -10
  58. package/lib/types/client/GroupChatSettingsSection.d.ts +0 -15
  59. package/lib/types/client/PermissionSelect.d.ts +0 -13
  60. package/lib/types/client/RoleDrawer.d.ts +0 -17
  61. package/lib/types/client/ThinkRow.d.ts +0 -9
  62. package/lib/types/client/ToolRow.d.ts +0 -9
  63. package/lib/types/client/api.d.ts +0 -8
  64. package/lib/types/client/components.d.ts +0 -22
  65. package/lib/types/client/drawer.d.ts +0 -17
  66. package/lib/types/client/glyph.d.ts +0 -12
  67. package/lib/types/client/model.d.ts +0 -78
  68. package/lib/types/client/panel.d.ts +0 -10
  69. package/lib/types/client/settings.d.ts +0 -15
  70. package/lib/types/client/styles.d.ts +0 -10
  71. package/lib/types/client/ui.d.ts +0 -17
  72. package/lib/types/client/utils.d.ts +0 -22
  73. package/lib/types/host/actions.d.ts +0 -34
  74. package/lib/types/host/conversation.d.ts +0 -25
  75. package/lib/types/host/http.d.ts +0 -16
  76. package/lib/types/host/materials.d.ts +0 -32
  77. package/lib/types/host/persistence.d.ts +0 -31
  78. package/lib/types/host/routes.d.ts +0 -11
  79. package/lib/types/host/store.d.ts +0 -65
  80. package/lib/types/host/tools.d.ts +0 -28
package/README.md CHANGED
@@ -1,57 +1,122 @@
1
1
  # dsh-group-chat
2
2
 
3
+ ![模型群聊面板](assets/banner.png)
4
+
3
5
  DSH Web GUI 的「模型群聊」插件:多模型角色群组对话面板。
4
6
 
7
+ 兼容:`dsh >= 0.1.5-rc.1`(Web profile)
8
+
5
9
  ## 功能
6
10
 
7
11
  - **群组管理**:新建、重命名、删除(至少保留一个群组);左栏搜索框按群组名/会话名过滤
8
- - **会话目录树**:每个群组内多个会话,左栏以「群组 → 会话」目录树呈现(展开/收起、新建、重命名、删除);消息挂在会话上,会话各有主题
9
- - **角色-模型绑定**:群组内每个角色绑定一个 provider/model(可各不相同),配置人设、标识色、Temperature、深度思考开关;开启深度思考时可选**推理级别**(选项取自 DSH 当前模型设置的推理选项,未配置则用默认);角色为群组级,全会话共享;配置走右侧滑出抽屉
12
+ - **会话目录树**:每个群组内多个会话,左栏以「群组 → 会话」目录树呈现(展开/收起、新建、重命名、删除,至少保留一个会话);消息挂在会话上。会话行名称前状态点对齐主会话列表:进行中 / 等待确认(命令闸门)/ 已完成 / 已出错;打开该会话即清「输出完毕」标记
13
+ - **角色-模型绑定**:群组内每个角色绑定一个 provider/model(可各不相同),配置人设、标识色、Temperature、深度思考开关、单独启用/停用;开启深度思考时可选**推理级别**(选项取自 DSH 当前模型设置的推理选项,未配置则用默认);角色为群组级,全会话共享;配置走右侧滑出抽屉
10
14
  - **群内共享对话**:所有消息对全群共享;发言以「【角色名】内容」形式注入每个角色的上下文(最近 40 条原文),流式显示
15
+ - **会话标题与主题**:会话头可手改主题。每轮结束后后台用 DSH 默认模型整理——占位名「新会话」生成一次「类别 emoji + 对象|目标」,主题为演进式一句话摘要并注入后续角色上下文;手动改名/改主题后该字段不再自动改
11
16
  - **会话约束备忘**:超过 40 条窗口后,被挤出的旧消息后台折成无主「已定 / 否决 / 未决」,作为「结论备忘」卡插在消息流折点;只读、空则不占位;清空消息时一并清除
12
- - **消息渲染**:角色发言以宿主同款 markdown 渲染(标题、列表、表格、代码块、公式);开启「深度思考」的角色发言带可折叠的思考行(折叠时显示摘要,展开看全文,流式时实时跟随)
13
- - **多轮对话**:发送消息后选择参与角色按顺序自动多轮对话(1–10 轮),可随时停止
14
- - **@点名**:裸 `@` 弹出成员候选(↑↓ 选择、Enter/Tab 插入);被 @ 的成员优先作为本轮参与角色。`@` 后继续键入则在群工作区内检索文件,插入 `@path` 芯片(只写入路径,不把文件正文再灌进 prompt)
15
- - **三区工作台**:左栏导航(搜索 + 目录树);中栏会话流(色环头像 + 模型徽章 + 时间,贴底自动跟随、可回到底部);右栏上下文(角色卡 + 工作区目录),可一键收起,窄面板时覆盖式呈现
17
+ - **消息渲染**:角色发言以 DSH 同款 markdown 渲染(标题、列表、表格、代码块、公式);开启「深度思考」的角色发言带可折叠的思考行(折叠时显示摘要,展开看全文,流式时实时跟随)。用户/角色消息悬停可复制;发言失败保留为该角色失败卡(人话标题 + 可展开原文),常驻「复制 / 重试」(原地覆盖同一条;对话进行中或角色停用则不可重试)
18
+ - **清空会话**:会话头可清空本会话消息(含结论备忘),确认弹窗说明范围与不可恢复;对话进行中需先停止
19
+ - **多轮对话**:发送前用 chips 选择本轮参与角色;发送后按顺序自动多轮(1–10 轮,一轮 = 参与角色各说一次),可随时停止。被 @ 的成员优先作为本轮参与角色
20
+ - **@点名**:裸 `@` 弹出成员候选(↑↓ 选择、Enter/Tab 插入);`@` 后继续键入则在群工作区内检索文件,插入 `@path` 芯片(只写入路径,不把文件正文再灌进 prompt)
21
+ - **三区工作台**:左栏导航(搜索 + 目录树);中栏会话流(色环头像 + 模型徽章 + 相对时间,贴底自动跟随、可回到底部);右栏上下文(角色卡 + 工作区目录)。左右栏均可经接缝钮收起,窄面板时右栏覆盖式呈现
16
22
  - **群组工作区目录**:每个群组指定一个目录(群级、全会话共享;无独立笔记或文件清单)。角色发言时自动读取目录**根下一层**文本文件(扩展名白名单、跳过隐藏项、最多 20 个;单文件 16k / 总量 48k 截断)注入全体角色 system 提示词的「共享资料」块;支持 `~`、绝对路径与相对 DSH 工作区根解析,右栏内置目录选择浏览器;未设置则不注入、不暴露工具
17
- - **工具执行(docs/TOOLS.md)**:设置工作区后角色可调用 `read_file` / `list_dir` 主动查看工作区(realpath 硬边界,逃逸/软链越界一律拒绝);**权限档位**于消息输入框下方左下角芯片切换(对齐主会话 `/permission` 三档:仅可查看 / 工作区内修改 / 完全权限;默认仅可查看,按群组记忆持久化)——工作区内修改档角色可请求执行 shell 命令(cwd 固定为工作区、超时 120s),**每条命令在会话流内逐条确认**(允许 / 拒绝 / 停止,命令全文展示不截断);完全权限档免确认直接执行,切换时经主会话同款风险确认弹窗;工具调用以折叠行内嵌于角色消息(含耗时与状态),摘要注入后续发言上下文;不支持 tools 的模型自动降级为纯文本
23
+ - **工具执行(docs/TOOLS.md)**:设置工作区后角色可调用 `read_file` / `list_dir` 主动查看工作区(realpath 硬边界,逃逸/软链越界一律拒绝);**权限档位**于消息输入框下方左下角芯片切换(对齐主会话 `/permission` 三档:仅可查看 / 工作区内修改 / 完全权限;默认仅可查看,按群组记忆持久化)——工作区内修改档角色可请求执行 shell 命令(经 DSH `ctx.shell` 沙箱执行器:cwd 与沙箱策略均收紧到工作区、超时 120s),**每条命令在会话流内逐条确认**(允许 / 拒绝 / 停止,命令全文展示不截断);完全权限档免确认直接执行(对齐 DSH danger-full-access 语义),切换时经主会话同款风险确认弹窗;工具调用以折叠行内嵌于角色消息(含耗时与状态),摘要注入后续发言上下文;不支持 tools 的模型自动降级为纯文本
18
24
  - **设置启用**:设置页「模型群聊」分区提供启停开关(持久化于 settings.yaml);关闭时隐藏侧边栏入口并中止进行中的对话
19
25
 
20
26
  ## 架构
21
27
 
22
- 双平面插件(对齐 [dsh-web](https://github.com/zhu1090093659/dsh-web) 家族的 dsh-usage 包形状):
28
+ dual-face 插件(对齐 [dsh-web](https://github.com/zhu1090093659/dsh-web) 家族的 dsh-usage 包形状)。包名 `@roaming-ai/dsh-group-chat`,bundle 行 `id: group-chat`(`cordis.patch.yml`)。
23
29
 
24
- - **源码与构建**:TypeScript 源码于 `src/`(`core/` 纯逻辑、`host/` 宿主半、`client/` 浏览器半);`pnpm build` 先 `tsc` 产声明到 `lib/types/`,再 `tsdown`(`shared/tsdown.client.ts` 预设拷贝自 dsh-web)产出双半产物 `lib/index.js`(ESM)+ `lib/client.js`(闭包工厂)
25
- - **Host 半**(`src/index.ts` + `src/host/`,host 进程组合插件):群组/会话/角色/工作区/消息内存状态机;群组与会话增删改;角色发言经 `llm` 服务按绑定路由流式生成,设置工作区后进入「生成⇄工具」循环(read_file/list_dir 自动执行,run_command `confirmCommand` 逐条确认闸门);工作区文本文件经 `fs` 服务读取并注入;经 `webServer` 暴露:
30
+ - **源码与构建**:TypeScript 源码于 `src/`(`core/` 纯逻辑、`host/`、`client/`、`shared/` 两边共用的路径语法);`pnpm build` 先 `tsc` 产声明到 `lib/types/`,再 `tsdown`(`shared/tsdown.client.ts` 预设拷贝自 dsh-web)产出 `lib/index.js`(host ESM)+ `lib/client.js`(client 闭包工厂)
31
+ - **host**(`src/index.ts` + `src/host/`):`inject = ['llm', 'fs', 'webServer', 'workspaceRegistry']`,设置命名空间 `group-chat`。同名包每进程至多挂一次(`mountOnce`)。组合根 `service.ts` 装配:
32
+ - `state` — 群组/会话/角色/消息内存表 + run 运行态
33
+ - `persistence/` — 会话级文件落盘与启动 hydrate
34
+ - `materials/` — 工作区路径解析、根下一层文本注入、目录浏览、`@` 文件检索
35
+ - `tools/` — `read_file` / `list_dir` / `run_command` 沙箱与确认闸门
36
+ - `engine/` — `runLoop` 串行发言;设置工作区后进入「生成⇄工具」循环(只读工具自动执行,`run_command` 经 `confirmCommand` 逐条确认);整次循环结束后后台 `retitle`(标题/主题)与 `fold`(约束备忘),立刻 idle、不占 run
37
+ - `broadcast` — 全量快照 + SSE 120ms 节流
38
+ - `api/` — HTTP 护栏与动作分发
39
+ - **HTTP**:
26
40
  - `GET /api/group-chat/state` — 全量快照
27
- - `POST /api/group-chat/action` — `{kind: mutate|send|stop|confirmCommand|models|efforts|browse|fileSearch, ...}`(`efforts` 查询 provider/model 的推理级别选项,60s 缓存;`browse` 为右栏目录浏览器;`fileSearch` 为输入框 @ 文件检索)
41
+ - `POST /api/group-chat/action` — `{kind: mutate|send|retrySpeak|stop|confirmCommand|models|efforts|browse|fileSearch, ...}`(`retrySpeak` 原地覆盖失败卡;`efforts` provider/model 推理级别,60s 缓存;`browse` 为右栏目录浏览器;`fileSearch` 为输入框 @ 文件检索)
28
42
  - `GET /api/group-chat/events` — SSE,状态变化推送(120ms 节流)
29
- - 路由带回环 + 同源信任栏(`src/host/http.ts`,语义对齐 dsh-web 家族的 loopback fence)
30
- - **浏览器半**(`src/client/`,`dsh.client` 模块):侧边栏 `sidebar.panellist` 入口 + `main` 键面板 + `settings.section` 设置页;经 fetch/SSE 访问 Host APIUI 使用宿主 DSW 原语(`@deepseek-ai/dsh-client-ui-primitives`,shell 静态种子模块)——Button/Input/Switch/Tooltip/统一描边图标与 `MarkdownText` 渲染器
43
+ - 路由带回环 + 同源信任栏(`src/host/api/http.ts`,语义对齐 dsh-web 家族的 loopback fence)
44
+ - **client**(`src/client/`,`dsh.client` 模块,`inject = ['slots', 'settingsScope']`):侧边栏 `sidebar.panellist` 入口 + `main` 键面板 + `settings.section` 设置页;经 fetch/SSE 访问 host API,按 `sessionId` 本地过滤渲染。UI 使用 DSW 原语(`@deepseek-ai/dsh-client-ui-primitives`,shell 静态种子模块)——Button/Input/Switch/Tooltip/统一描边图标与 `MarkdownText` 渲染器。未发送草稿按会话分槽、模块级跨挂载存活(主会话⇄群聊会卸载 composer)。
31
45
 
32
46
  设计文档位于 `docs/`:`PRODUCT.md`(产品定义)、`DESIGN.md`(界面设计契约)、`PERSISTENCE.md`(持久化契约)、`TOOLS.md`(工具执行护栏)。
33
47
 
34
- ## 安装(本 profile)
48
+ ## 安装
49
+
50
+ 通过官方 `dsh plugin` 装进 web profile。它在 `$DSH_HOME/profiles/web` 里转发给 pnpm;本包声明了 `dsh.bundle`,安装成功后会按真实包名 `@roaming-ai/dsh-group-chat` 自动写入 `dsh.profile.bundles`。不要手改 profile 的 `package.json` 或 `cordis.patch.yml`。
51
+
52
+ 要求:已能运行 `dsh web`;Node `^22.19.0 || >=24`;PATH 上有 `pnpm`。
53
+
54
+ ### 从 GitHub 安装
55
+
56
+ ```sh
57
+ dsh plugin --profile web add github:localSummer/dsh-group-chat#main
58
+ ```
59
+
60
+ 等价:`dsh plugin --profile web add git+https://github.com/localSummer/dsh-group-chat.git`
61
+
62
+ 本包的 `prepare` 会在安装时构建 `lib/`。pnpm 若拦截构建脚本,把提示的 key 写进 `$DSH_HOME/profiles/web/pnpm-workspace.yaml` 的 `allowBuilds`,再重跑同一条命令。
63
+
64
+ ### 从本地检出安装(开发)
65
+
66
+ 相对路径按**调用目录**锚定(`dsh plugin` 的 cwd 是 profile 目录,不要在 profile 里写 `.` / `../`)。
67
+
68
+ ```sh
69
+ git clone https://github.com/localSummer/dsh-group-chat.git
70
+ cd dsh-group-chat
71
+ pnpm install && pnpm build
72
+ dsh plugin --profile web add link:$(pwd)
73
+ ```
74
+
75
+ 也可以给绝对路径:`dsh plugin --profile web add /path/to/dsh-group-chat`。
76
+
77
+ 开发辅助(在本仓库内):`pnpm watch`(tsdown 增量构建)、`pnpm test`、`pnpm typecheck`。`link:` 安装后改源码需重建产物;host 通常仍要重启 `dsh web`。
78
+
79
+ ### 安装后
80
+
81
+ 重启 `dsh web`(或 `dsh --profile web`)。用 dump 确认组合层已挂上:
82
+
83
+ ```sh
84
+ dsh --profile web --dump-config
85
+ ```
86
+
87
+ 应出现 `# == @roaming-ai/dsh-group-chat` 层,且含 `id: group-chat` 行。侧边栏有「群聊」入口,设置页有「模型群聊」开关。
35
88
 
36
- `~/.dsh/profiles/web/package.json` 的 `dependencies` 已含 `"dsh-group-chat": "link:/home/.../plugins/dsh-group-chat"`,且 `dsh.profile.bundles` 已列 `dsh-group-chat`。本包改为 TS 源码 + 构建产物形态,修改源码后在本目录执行:
89
+ ## 卸载
37
90
 
38
- ```bash
39
- cd ~/.dsh/profiles/web/plugins/dsh-group-chat && pnpm install && pnpm build
91
+ ```sh
92
+ dsh plugin --profile web remove @roaming-ai/dsh-group-chat
40
93
  ```
41
94
 
42
- 重启 `dsh web` 生效。开发辅助:`pnpm watch`(tsdown 增量构建)、`pnpm test`(core/store 冒烟测试)、`pnpm typecheck`。
95
+ 然后重启 DSH。会话数据留在 `~/.dsh/storages/group-chat/`,卸载不会删除。
43
96
 
44
97
  ## 数据与持久化
45
98
 
46
- - 会话级文件隔离持久化于 `~/.dsh/storages/group-chat/`(设计详见 `docs/PERSISTENCE.md`;gitignore 已覆盖):
47
- - `ledger.json` — 群组/会话清单(`schema: 2`,纯清单)
48
- - `<group-id>/roles.json` — 群组角色定义(`schema: 1`)
49
- - `<group-id>/workspaceDir` — 群组工作区目录设置(纯文本一行)
50
- - `<group-id>/sessions/session-<uuid>.json` — 一个会话一个文件(自包含名称/主题/创建时间/消息,可选约束备忘)
51
- - 事件驱动写:变更按文件标脏,同一 tick 内合并,流式 partial 不落盘
52
- - 原子写(tmp + fsync + rename,每个实际发生 rename 的目录一次 fsync)、单实例 `.lock`(PID 存活检测,崩溃残留自动清理)
53
- - 写失败保留脏标记,下次 flush 自动重试;插件卸载时同步最终 flush 后再释放锁
54
- - 损坏处理:单会话文件坏仅丢该会话消息(隔离 `.corrupt-*`,每前缀保留最近 1 份);ledger 坏可扫描群组目录回收;行级校验丢弃孤儿条目
99
+ 会话级文件隔离,根目录 `~/.dsh/storages/group-chat/`(`DSH_GROUP_CHAT_STORE` 可覆盖;设计详见 `docs/PERSISTENCE.md`):
100
+
101
+ ```
102
+ ~/.dsh/storages/group-chat/
103
+ ├── .lock
104
+ ├── ledger.json # schema: 3,纯清单;群组含 permissionTier
105
+ └── <group-id>/
106
+ ├── workspaceDir # 纯文本一行路径
107
+ ├── roles.json # schema: 1,该群角色(含 thinking / reasoningEffort)
108
+ └── sessions/
109
+ └── session-<uuid>.json # schema: 1,自包含
110
+ ```
111
+
112
+ - **ledger.json**(`schema: 3`):群组 id/名/`permissionTier` + 会话 id 归属与顺序。v2 遗留 `allowCommands` 读取时迁移(true → 工作区内修改,false/无 → 仅可查看)
113
+ - **roles.json**:角色定义;`groupId` 由目录归属,不写入文件
114
+ - **session-\<uuid\>.json**:名称/主题/`createdAt`/消息;可选 `namePinned` / `topicPinned`、`constraints` / `constraintsUpToSeq`(空数组与水位 0 省略)、消息上的 `toolCalls` / `error` / `failedRoleId`
115
+ - 工作区文件内容不写入本目录;每次发言由 materials 实时读盘。全量保留,不裁剪
116
+ - 事件驱动写:变更按文件标脏,同一 tick 内合并;流式 partial 不落盘。会话文件与 `roles.json` 紧凑序列化,ledger pretty
117
+ - 原子写(`@deepseek-ai/dsh-atomic-write` 的 `writeFileAtomic`:wx 独占创建 + 随机后缀 tmp + rename,无 per-file fsync 对齐 DSH 基座标准;每个实际发生 rename 的目录一次 fsync)、单实例 `.lock`(PID 存活检测,崩溃残留自动清理)
118
+ - 写失败保留脏标记,下次 flush 自动重试;插件卸载时先唤醒确认等待并 kill 子进程,再等待挂起 flush 并最终落盘、释放锁(异步 disposer,cordis await)
119
+ - 损坏处理:单会话文件坏仅丢该会话消息(隔离 `.corrupt-*`,每前缀保留最近 1 份);ledger 有 id 而文件缺失则空消息重建;`roles.json` 坏仅空该群角色;ledger 坏可扫描群组目录回收(仅丢群组名);行级校验丢弃孤儿条目;hydrate 清 `.tmp-*`
55
120
  - v1 双文件布局(ledger.json + messages.json)首次启动自动迁移(幂等;旧 messages.json 归档为 `.migrated-*`,从不删除)
56
121
  - 锁不可得(双进程)时降级为内存态运行并告警
57
- - 设置页的 `enabled` 开关经 settings 服务持久化于 `settings.yaml`;进行中的对话运行态(run)不持久化
122
+ - 设置页的 `enabled` 开关经 settings 服务持久化于 `settings.yaml` 的 `group-chat` 段;进行中的对话运行态(run,含「输出完毕」标记)不持久化,重启即清