
AionUi ACP 单聊消息发送与文件处理全解析从队列机制、文件引用到/btw上下文注入【免费下载链接】AionUi免费、本地、开源的 24/7 全天候 Cowork 应用以及适用于 Gemini CLI、Claude Code、Codex、OpenCode、Qwen Code、Goose CLI、Auggie 等的 OpenClaw | 喜欢就点star吧项目地址: https://gitcode.com/iOfficeAI/AionUi本文以 docs/prds/conversations/acp/messaging.mdF-MSG-01 ~ F-MSG-08 F-FILE-02覆盖 S-MSG-01 ~ S-MSG-12、S-FILE-03为核心骨架结合 AionUi 桌面端 renderer 源码与单元/E2E 测试逐项拆解 ACPAgent Client Protocol单聊场景下消息发送、文件引用、规则注入、静默消息、输入历史、重试撤销、/btw上下文注入与 AI 文件读写等能力的设计细节、实现状态与验收标准。读完本文你将掌握 AionUi 在 ACP 对话链路中消息即发即显、排队自动补发、多种文件引用、后台静默消息、首条规则注入等机制的前端实现原理并能据此评估各功能点的完成度与可测试性。文档背景说明本文涉及的 PRD 由 PM 从prd-acp-scenarios.md抽取并与源文档保持同步功能点状态已实现 / 部分实现 / 未实现以 docs/prds/conversations/acp/README.md 中的功能点总表与 skip 白名单为准。其中 F-MSG-07重试与撤销明确标注 skip: undo/redo 未实现并在 E2E 测试中整体跳过。1. 功能全景9 个功能点的实现状态一览ACP 单聊消息模块共包含 9 个独立功能点F-MSG-01 ~ 08 F-FILE-02从实现状态看呈现多数已落地、少量留白的局面功能点标题实现状态覆盖场景F-MSG-01发送文本消息部分实现S-MSG-01/02/09/10/11/12F-MSG-02在消息中引用文件部分实现S-MSG-03/07、S-FILE-01/02/04F-MSG-03首条消息自动注入 AI 规则已实现S-MSG-04/05/06F-MSG-04隐藏消息与静默消息已实现S-MSG-08F-MSG-06输入框历史记录已实现—F-MSG-07重试与撤销上一轮对话未实现—F-MSG-08/btw追加上下文部分实现—F-FILE-02AI 读取和写入文件已实现S-FILE-03两个部分实现的功能点F-MSG-01、F-MSG-02均有明确的实现差距记录F-MSG-07 属于代码库中尚无任何实现的待办项。下文将按此顺序逐一展开。2. F-MSG-01发送文本消息部分实现2.1 用户故事与正常流程作为用户我希望在输入框中输入文字并发送能立即看到我的消息出现在对话中同时 AI 开始回复。正常流程用户视角为用户在输入框中输入文本点击发送用户的消息立即出现在对话区域无需等待 AI 后端连接完成会话在列表中的排序位置更新为最新系统自动完成后台连接若尚未连接AI 开始流式输出回复内容。2.2 AI 回复期间的消息队列AI 正在回复时输入框仍可输入。用户发送的消息进入等待队列具体规则队列中的消息可以逐条编辑或删除也支持一键清空队列当前 turn 结束后队列中的消息自动发出如果队列中有多条消息系统在等待期间将其合并为一条发出。实现差距消息队列基础功能已实现入队 / 编辑 / 删除 / 清空 / 自动发送但缺少多条排队消息合并为一条发出。从源码看这一机制在 ACP 平台的发送组件与命令队列工具中均有落地。在 AcpSendBox.tsx 中注释明确指出 The queue (panel, runner, auto-send) is always live: backends that can …即队列面板、队列执行器与自动发送在 ACP 场景下始终处于存活状态而在 useConversationCommandQueue.ts 中可以看到队列状态机createDefaultQueueState、满队列queueFull、队列过大queueTooLarge以及立即发送排队命令Failed to send queued command now等分支逻辑对应了队列编辑、删除、清空、自动补发的完整生命周期。队列条目过长时还会给出inputTooLong提示This queued command is too long. Shorten it before sending.。2.3 异常情况与跨后端差异场景系统行为未输入任何内容点击发送系统不响应AI 后端连接失败用户的消息已显示在对话中系统显示错误提示告知连接失败原因并建议操作AI 回复过程中发生错误系统显示错误消息随后恢复输入框为可用状态会话不存在或已被删除系统提示「会话未找到」Qwen 后端内部错误系统提供增强的错误提示信息2.4 验收标准用户消息立即显示不等待后端连接会话列表排序实时更新AI 连接失败时显示明确的错误提示错误发生后界面恢复可用状态不卡在加载中已缓冲的部分 AI 回复在发生错误时不丢失AI 回复期间可继续输入并发送消息到队列队列中的消息可编辑、删除、一键清空当前 turn 结束后队列消息自动发出多条队列消息在等待期间合并为一条发出当前缺口。3. F-MSG-02在消息中引用文件部分实现3.1 用户故事与前置条件作为用户我希望能以多种方式将文件内容提供给 AI以便 AI 能基于这些文件进行回复。前置条件用户已设置工作区目录Add to Chat 方式需要。3.2 文件引用的三种方式方式一Add to Chat从工作区目录树引用用户在工作区目录树中右键点击某个文件或目录选择「Add to Chat」文件/目录以路径形式添加到输入框发送时系统自动读取文件内容并附加到消息中也可以手动在输入框中输入文件名触发自动补全。该能力在前端有完整的目录树上下文菜单支撑。在 explorerModel.test.ts 中可以看到explorerContextMenuSections的菜单分组逻辑当能力位addToChat: true时菜单第一组为[addToChat]与copyRelativePath、revealInFolder、newFile、rename、delete等操作按能力位组合出现而 explorerAddToChatNoPreview.dom.test.tsx 则通过 DOM 测试验证了在预览场景下点击conversation.explorer.contextMenu.addToChat菜单项后文件能被正确添加到发送框。自动补全的底层解析逻辑集中在 atFileQuery.test.ts 对应的buildAtFileInsertion、resolveAtFileMenuKey、getActiveAtFileQuery等工具函数中。方式二上传文件用户点击上传按钮或拖拽文件到输入框区域文件显示在输入框附近的预览区域用户输入消息文本并点击发送文件随消息一起发送给 AI。前端发送框 SendBox/index.tsx 中引入了useDragUpload钩子renderer/hooks/file/useDragUpload与文件附件按钮组件配合mergeFileSelectionItems等工具实现拖拽上传与多文件合并去重的展示。方式三粘贴板用户复制文件内容或截图后在输入框中粘贴文本内容直接粘贴为消息文本图片内容作为附件添加到消息中。3.3 异常情况与跨后端差异引用的文件不存在系统将原始filename文本直接传递给 AI由 AI 自行处理引用的是二进制文件如图片、编译产物系统不内联读取内容而是将文件引用传递给 AI 后端处理同时通过多种方式引用了同一文件系统自动去重当前缺口Gemini 后端上传的文件会被临时复制到工作区目录中AI 完成回复后临时文件自动清理可在配置中决定是否保留其他后端文件通过路径引用或内容内联的方式传递。3.4 验收标准Add to Chat 方式从目录树选择文件/目录后以路径添加到输入框上传方式支持拖拽和按钮上传粘贴板方式支持粘贴文本和图片文件内容被附加到消息中供 AI 参考二进制文件不做内联读取多种方式引用同一文件时自动去重当前缺口附件路径以工作区相对路径形式展示工作区外的文件仅显示文件名AI 收到的消息不包含界面展示用的路径标记路径标记剥离不完整为当前缺口之一上传失败不阻塞消息发送Gemini 后端下上传文件自动复制到工作区回复后自动清理用户可配置是否保留。4. F-MSG-03首条消息自动注入 AI 规则已实现用户故事作为用户我希望每个新会话的第一条消息自动包含 AI 的行为规则和技能索引以便 AI 从一开始就按照正确的规则工作我无需每次手动说明。正常流程用户在新会话中发送第一条消息系统自动在消息中附加预设的 AI 规则和可用技能信息用户不可见AI 基于这些规则开始工作后续消息不再重复注入规则。异常情况没有可用的规则和技能消息原样发送不做任何包装用户使用自定义工作区系统使用文本注入方式而非目录符号链接方式注入规则。技能索引的读取在发送链路中已具备实现基础发送框组件中通过useSWR(loadedSkills.length 0 ? skills-index : null, …)按需拉取技能索引并构建skillName - description映射见 SendBox/index.tsx这正对应首条消息注入可用技能信息的数据来源。该功能与 docs/prds/conversations/acp/skills.mdF-SKILL-01 AI 技能自动发现与注入相辅相成。验收标准新会话首条消息自动注入 AI 规则仅首条消息注入后续消息不重复注入内容对用户不可见自定义工作区场景下规则仍能正确注入。5. F-MSG-04隐藏消息与静默消息已实现用户故事作为系统定时任务、频道集成等我需要能够发送不显示在用户界面中的消息给 AI以便后台自动化任务能够无干扰地运行。两种消息类型的语义区别是关键静默消息系统后台发送的消息完全不在界面中显示也不记录到消息历史用户完全无感知隐藏消息消息存在于历史记录中但不在对话界面中显示用于后台自动化场景。验收标准静默消息不出现在对话界面静默消息不记录到消息历史隐藏消息不出现在对话界面但保留在历史中。这一能力是 AionUi 后台自动化如 docs/prds/conversations/cron 定时任务、远程频道集成能无感驱动 AI 的关键基础设施。6. F-MSG-06输入框历史记录已实现用户故事作为用户我希望在输入框中通过上下键浏览历史输入以便快速复用之前发过的消息内容。正常流程焦点在输入框时用户按上键 → 显示上一条历史输入内容继续按上键 → 继续往前翻历史按下键 → 往后翻历史回到更近的输入用户可以基于历史内容编辑后直接发送。验收标准上下键在输入框为空或光标在首/末行时触发历史浏览历史记录按时间倒序排列选择历史内容后可编辑再发送。注意该功能与输入框的提及、斜杠命令等组合交互共用同一焦点与键盘事件体系实现时需避免上下键在普通多行编辑场景与历史浏览之间的误触发。7. F-MSG-07重试与撤销上一轮对话未实现实现差距代码库中无任何 redo/undo 相关实现该功能点在 docs/prds/conversations/acp/README.md 的功能点总表中标注 skip: undo/redo 未实现E2E 测试整项跳过。用户故事作为用户我希望能够编辑并重新发送最后一轮对话中的消息重试或撤销最后一轮对话回到发送前的状态以便修正提问或尝试不同的表述。前置条件最后一个 prompt turn 已结束AI 已完成回复。正常流程设计预期重试Redo用户点击最后一条用户消息的「重试」按钮 → 该消息内容回到输入框供编辑 → 编辑后重新发送 → AI 基于编辑后的内容重新回复撤销Undo用户点击「撤销」→ 最后一轮对话用户消息 AI 回复从对话历史中移除 → 回到上一轮对话的状态。异常情况对话历史为空重试和撤销按钮不可用AI 正在回复中重试和撤销按钮不可用需等待当前 turn 结束。跨后端差异设计预期此功能可能依赖 ACP 协议和 Agent 后端是否支持会话历史回滚。不支持的后端可能无法实现撤销功能仅支持重试重新发送编辑后的消息。验收标准作为未来实现基线最后一轮用户消息可编辑后重新发送撤销操作移除最后一轮对话用户消息 AI 回复AI 回复中时重试/撤销不可用后端不支持回滚时撤销按钮不显示或提示不支持。8. F-MSG-08/btw追加上下文部分实现8.1 用户故事与流程用户故事作为用户我希望在 AI 回复过程中通过/btw命令追加补充信息AI 能在不中断当前回复的情况下参考这些补充内容。前置条件AI 正在回复中。正常流程用户视角AI 正在回复用户输入/btw 补充内容并发送补充信息被注入到 AI 的当前上下文中AI 在后续回复中参考这些补充内容不会重新开始回复。8.2 实现状态与差距实现差距/btw已实现但采用fork session 独立回答方式非注入当前 AI 上下文不支持的后端直接提示不支持而非入队。从源码看/btw的界面与交互层已相当完整浮层组件 BtwOverlay/index.tsx 以 Portal 方式渲染一个独立的侧问面板包含问题气泡右对齐、回答气泡左对齐支持 Markdown 渲染、加载态Spin conversation.sideQuestion.loading与父任务运行提示conversation.sideQuestion.parentTaskRunning浮层定位会避开顶部聊天布局 header宽度被限制在 320px ~ 760px最小高度 180px并随窗口 resize/scroll 实时重算位置VIEWPORT_MARGIN_PX 16、OVERLAY_GAP_PX 8键盘关闭做了防误触设计按下 Enter 提交/btw后延迟 200ms 才绑定 Escape/Enter/空格 的关闭监听DISMISS_BIND_DELAY_MS 200避免提交动作立即关掉尚未展示结果的浮层命令支持性检测在 BtwOverlay/useBtwCommand.ts 中处理不支持时弹出conversation.sideQuestion.unsupported警告并返回 unsupported 分支。跨后端差异目前仅Claude后端支持此功能其他后端/btw消息进入等待队列等当前 turn 结束后作为普通消息发出注意这与 PRD 中不支持的后端直接提示不支持而非入队的实现差距相关。8.3 验收标准Claude 后端下/btw消息实时注入到 AI 上下文不支持的后端下/btw消息进入等待队列/btw消息在对话界面中有区别于普通消息的展示。9. F-FILE-02AI 读取和写入文件已实现9.1 用户故事与流程用户故事作为用户我希望 AI 能够按需读取我工作区中的文件、以及在工作区中创建或修改文件以便 AI 可以帮我完成代码编写、文档编辑等任务。前置条件用户已设置工作区目录。正常流程用户视角用户在对话中要求 AI 读取某个文件或修改某个文件AI 自动执行文件读取或写入操作对话中显示 AI 执行的文件操作记录读取了哪个文件、编辑了哪个文件如果是写入操作用户可以在编辑器中看到文件内容的实时更新。异常情况读取不存在的文件AI 收到错误信息并在对话中告知用户写入时目标目录不存在系统自动创建所需目录。9.2 实现状态说明实现差距V2 路径缺少 auto-mkdir 和编辑器通知但当前走 V1 路径V1 完整实现。即当前生产路径V1已覆盖自动创建目录与编辑器实时更新通知两项关键能力V2 路径作为演进方向存在差距。9.3 验收标准AI 能读取工作区内的文本文件AI 能在工作区内创建新文件或修改现有文件文件操作以工具调用的形式展示在对话中与 docs/prds/conversations/acp/display.md 中 F-DISPLAY-03 AI 工具调用展示联动写入时自动创建不存在的目录文件写入后编辑器实时收到内容更新通知。10. 总结从 PRD 到源码的实现链路结合 docs/prds/conversations/acp/README.md 的功能点总表与 skip 白名单可以得出如下工程结论消息发送主链路已成熟即时显示、连接失败提示、回复期间排队、队列编辑/删除/清空/自动补发均已实现剩余缺口是多条排队消息合并为一条文件引用三通道齐备Add to Chat目录树右键 补全、拖拽/按钮上传、粘贴板三种方式均有代码与测试佐证剩余缺口是多方式引用去重与路径标记剥离完整性自动化消息通道完备静默消息不显示、不入历史与隐藏消息入历史、不显示已实现支撑定时任务与频道集成的无感后台驱动/btw交互层完整、协议层受限浮层 UI、定位、键盘防误触、加载/错误态一应俱全但当前采用 fork session 独立回答而非注入当前上下文且仅 Claude 后端支持明确留白项F-MSG-07 重试/撤销在代码库中尚无实现属于 E2E skip 白名单项AI 文件读写走 V1 路径读取、创建、修改、auto-mkdir、编辑器实时通知均已落地工具调用过程在对话中以结构化形式展示。对于希望继续深入源码的读者推荐按以下路径展开发送框入口 SendBox/index.tsx → ACP 平台发送组件 AcpSendBox.tsx → 命令队列 useConversationCommandQueue.ts → 文件查询 atFileQuery.ts → 目录树 Add to Chat 测试 explorerAddToChatNoPreview.dom.test.tsx/btw相关阅读 BtwOverlay/index.tsx 与 useBtwCommand.ts。若需了解 ACP 单聊全模块会话、配置、权限、展示、可靠性、技能可继续参阅 docs/prds/conversations/acp/README.md 索引目录下的其余模块文档。【免费下载链接】AionUi免费、本地、开源的 24/7 全天候 Cowork 应用以及适用于 Gemini CLI、Claude Code、Codex、OpenCode、Qwen Code、Goose CLI、Auggie 等的 OpenClaw | 喜欢就点star吧项目地址: https://gitcode.com/iOfficeAI/AionUi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考