- 人工智能
- 大模型
- AI 应用
- 交互助手
- 本地部署
【免费下载链接】cherry-studio
🍒 Cherry Studio 是一款支持多个 LLM 提供商的桌面客户端
导读
本技术指南围绕 Cherry Studio 的一次消息删除行为变更展开:自 2026-08-06 起,首轮消息可以与其他消息一样按"拼接(splice)"语义删除,删除多模型回复组时只会移除各模型产生的 assistant 回复,而用户的提问与后续消息将原样保留,删除动作不再误伤整个会话分支子树。读完本文,你将理解这次变更的触发场景、前端删除可用性的判定机制(not-loaded/generating两种禁用原因)、多选删除与分组删除的实现细节,以及配套国际化文案的更新内容。
变更概述
变更前的问题
在旧行为中,当用户删除一条位于会话分支中部的消息时,删除动作会以该消息为根,将其整棵后续消息子树一并移除。这在大多数普通对话里是符合预期的——删除一条用户提问,往往意味着连同其所有回复一起清理。然而在多模型回复组(multi-model reply group)场景下,这种"级联删除"会造成误伤:
- 一条用户提问可能同时触发多个模型分别作答,界面中它们以"同一组"的形式并列展示;
- 用户只想删掉其中一个模型的回答,但旧逻辑会连同用户提问与整条分支一并删除;
- 或者用户想删掉整组 assistant 回复、保留自己的提问继续追问,旧逻辑同样做不到。
变更后的新行为
本次变更(引入 PR #17996,变更类别为changed,影响级别notice)明确规定了三条新规则:
- 首轮消息可删除:会话的第一轮(first-turn)消息现在可以像其他消息一样执行删除,并遵循与其他消息相同的 splice 拼接行为——即只移除该消息本身,不级联删除后续内容;
- 多模型回复组删除语义:删除一个多模型回复组时,只移除其中的 assistant 回复(各模型的回答),用户提问与之后的消息均被保留;
- 生成期间的删除保护:当被涉及的 assistant 回复仍在生成中时,单条删除、多模型组删除以及多选删除三种操作均不可用。
从用户视角看,这次变更带来的核心收益是:删除消息不再因为动作只针对一个多模型回复组而连带移除整个会话子树,会话分支结构因此得以保全。变更属于自动生效的行为调整,用户无需任何手动配置。
删除可用性的前端判定机制
新行为在前端代码中对应一套显式的"删除可用性(delete availability)"模型。该模型定义在 ChatWriteContext.ts 中:
export interface DeleteMessageOptions { // ... } export type MessageDeleteAvailability = | { enabled: true } | { enabled: false; reason: 'not-loaded' | 'generating' }即每条消息的删除可用性只有三种状态:
| 状态 | 含义 | 触发时机 |
|---|---|---|
{ enabled: true } | 可以删除 | 消息已加载完毕,且不处于生成中 |
{ enabled: false; reason: 'not-loaded' } | 暂时不可删除 | 消息列表仍在加载中 |
{ enabled: false; reason: 'generating' } | 暂时不可删除 | 该消息所属组的 assistant 回复仍在生成 |
负责把禁用原因翻译成用户可读提示的是 messageDeleteAvailability.ts,核心逻辑如下:
export function getMessageDeleteUnavailableText( reason: MessageDeleteUnavailableReason | undefined, t: TFunction ): string | undefined { if (reason === 'not-loaded') return t('message.delete.root_unavailable') if (reason === 'generating') return t('message.delete.generating_unavailable') return undefined }该工具函数被消息组菜单栏、多选操作弹层(MultiSelectActionPopup)等多个删除入口复用,保证"同一禁用原因、同一提示文案"的语义一致。
测试对生成期禁用行为的验证
在 MultiSelectActionPopup.test.tsx 中,测试用例逐一验证了两种禁用原因:
[ ['not-loaded', 'message.delete.root_unavailable'], ['generating', 'message.delete.generating_unavailable'] ] as const)('disables only deletion for %s', (deleteDisabledReason, tooltip) => { render(<MultiSelectActionPopup {...controlledProps()} deleteDisabledReason={deleteDisabledReason} />) // ... expect(buttonFor('delete-icon')).toBeDisabled() expect(buttonFor('delete-icon').parentElement).toHaveAttribute('data-tooltip-content', tooltip) })注意这里断言的是"只禁用删除"(disables only deletion)——生成期间其他操作(复制、导出、保存等)仍保持可用,只有删除按钮被禁用并展示对应 tooltip,这正是本次变更中"生成期间三种删除路径全部不可用"这一约束的可执行化体现。
删除动作的调用链与分组删除
单条删除:message.delete 命令
单条删除由命令message.delete触发,实现在 messageMenuBarActions.tsx:
registerCommand('message.delete', async ({ actions, message }) => { await actions.abortMessageTranslation?.(message.id) await actions.deleteMessage?.(message.id, { modelName: getMessageListItemModelName(message) || undefined }) })删除前会先中止该消息可能存在的翻译任务,再携带模型名调用deleteMessage。deleteMessage与分组删除、多选删除相关的动作,统一声明在 MessageListActions 中:
getMessageDeleteAvailability?: (messageId: string) => MessageDeleteAvailability deleteMessage?: (messageId: string, options?: DeleteMessageOptions) => void | Promise<void> // ... deleteMessageGroup?: (messageIds: readonly string[]) => void | Promise<void> deleteMessageGroupWithConfirm?: (messageIds: readonly string[]) => void | Promise<void>其中:
deleteMessage:单条消息删除,也是多模型回复组内单条 assistant 回复的删除入口;deleteMessageGroup/deleteMessageGroupWithConfirm:整组删除(后者带确认弹窗),即变更文档所述的"删除多模型回复组只移除 assistant 回复"的实现入口;deleteSelectedMessages:多选模式下的批量删除,与MultiSelectActionPopup联动。
从源码结构看,这三类删除入口在调用前都需要通过getMessageDeleteAvailability或等价的deleteDisabledReason判定,这也解释了为何"生成期间单条、整组、多选三种删除全部不可用"——它们共享同一套可用性判定。
多选删除:useMessageSelectionController
多选删除由 useMessageSelectionController.ts 管理,其通过useCache('chat.multi_select_mode')与useCache('chat.selected_message_ids')维护多选模式与选中集合,并将deleteMessage注入为deleteSelectedMessages的底层实现。选中消息为空时弹出chat.multiple.select.empty提示,避免空删。测试用例 useMessageSelectionController.test.tsx 与 MessageGroupMenuBar.test.tsx 覆盖了这些交互路径。
多模型组删除的确认文案更新
新增:生成期不可删除提示
本次变更为 release manager 指出的第二处配套改动是新增了message.delete.generating_unavailable文案,用于向用户解释"为什么生成期间无法删除"。该文案已同步到全部 13 个语言包,例如:
- 英文(en-us.json):
message.delete.generating_unavailable:"A reply in this group is still generating and cannot be deleted yet."message.delete.root_unavailable:"Messages are still loading and cannot be deleted yet."message.delete.confirm.title:"Delete Confirmation"message.delete.confirm.content:"Are you sure you want to delete the selected {{count}} message(s)?"
- 简体中文(zh-cn.json):
message.delete.generating_unavailable:"该分组中仍有回答正在生成,暂时无法删除。"message.delete.root_unavailable:"消息仍在加载,暂时无法删除。"message.delete.confirm.title:"删除确认"message.delete.confirm.content:"确认删除选中的 {{count}} 条消息吗?"
更新:多模型组删除确认文案
多模型组删除的确认弹窗文案(message.delete.confirm.*)也已同步改写,用于描述"哪些消息会被保留"——即明确告知用户:删除动作只移除 assistant 回复,用户提问与后续消息不受影响。这避免了用户因担心"删一个回答会清空整条对话"而不敢执行删除。
变更影响总结与注意事项
| 维度 | 变更前 | 变更后 |
|---|---|---|
| 首轮消息删除 | 不支持/行为特殊 | 与其他消息一致,按 splice 语义删除 |
| 删除多模型回复组 | 可能级联移除整条子树 | 仅移除 assistant 回复,保留用户提问与后续消息 |
| 生成期间的删除 | 行为未明确定义 | 单条、整组、多选删除全部禁用,并提示原因 |
| 会话分支保全 | 删除可能破坏分支结构 | 分支得以保留 |
注意事项:
- 自动生效,无用户操作:本变更是客户端行为调整,升级到包含该变更(PR #17996)的版本后自动生效;
- 生成期保护是硬约束:只要被涉及的 assistant 回复还在生成,删除入口就处于禁用状态并展示
message.delete.generating_unavailable提示,此时应等待生成完成后再删除; - 文案已本地化:新增与更新的文案(
message.delete.generating_unavailable、message.delete.root_unavailable、message.delete.confirm.*)已随 13 个语言包同步发布,i18n 资源目录 是排查文案问题的首选位置; - 测试保障:删除可用性判定与禁用交互均有对应的单元测试覆盖(MultiSelectActionPopup.test.tsx、MessageGroupMenuBar.test.tsx、useMessageSelectionController.test.tsx),后续改动可据此回归。
延伸阅读
- 变更声明原文:2026-08-06-message-deletion-preserves-branches.md
- 删除可用性类型定义:ChatWriteContext.ts
- 删除禁用原因→文案映射:messageDeleteAvailability.ts
- 消息列表动作契约(
MessageListActions):types.ts - 删除命令注册与分组删除:messageMenuBarActions.tsx
- 多选删除控制器:useMessageSelectionController.ts
- 人工智能
- 大模型
- AI 应用
- 交互助手
- 本地部署
【免费下载链接】cherry-studio
🍒 Cherry Studio 是一款支持多个 LLM 提供商的桌面客户端
相关推荐
Cherry Studio 删除 Workspace 的行为变更:级联清理其下所有 Agent Session,磁盘目录原样保留
Cherry Studio 删除 Workspace 的行为变更:级联清理其下所有 Agent Session,磁盘目录原样保留 本文基于 Cherry Stu
人工智能大模型AI 应用交互助手本地部署Cherry Studio 消息树虚拟根(Virtual Root)模型:单根不变量、兄弟组与删除语义深度解析
Cherry Studio 消息树虚拟根(Virtual Root)模型:单根不变量、兄弟组与删除语义深度解析 Cherry Studio 的主题(Topic)
AI 应用大模型桌面应用本地部署RAGRoo Code 2.2.43 消息删除功能详解:单条删除与级联回退的对话控制机制
Roo Code 2.2.43 消息删除功能详解:单条删除与级联回退的对话控制机制 导读 Roo Code 2.2.43 为任务对话引入了消息删除能力:用户可以
人工智能AI Agent代码智能体开发工具工具调用MCP Clients
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考