Conversation
共享 Host 原本就透传 ACP SessionUpdate,但 macOS 只处理消息、工具、 标题、配置和用量,其余更新被丢弃。本次补齐四类标准更新: - agent_thought_chunk:独立的可折叠思考块,流式输出时展开、回复或 工具到达后收起;缓冲按角色切分,思考与回复不再混在一起;导出 Markdown 以引用块保留,历史消息数不计思考 - plan:计划栏固定在活动统计栏上方,显示进度与当前步骤;每次整体 替换,空计划清除 - available_commands_update:输入 / 弹出 Agent 上报的命令补全,前缀 优先;Codex 的 $Skill 补全为 $name(codex-acp 不解析 /$name), 输入 $ 只列 Skill;macOS 14+ 支持方向键与 Tab - current_mode_update:Agent 自行切换模式时同步权限模式选择器 另外把模型层的兜底文案、stopReason 提示和工具证据标题改为本地化, 补齐 zh-Hans 翻译。 fixture 新增四类事件样例并加入 Rust 往返测试;更新功能矩阵与 shared-acp Agent Note。真实 Agent 已在协议层确认 Codex/Claude 会上报 命令列表、Claude 会上报思考,界面层验证仍待完成。
为输入区保留可编辑行,空间不足时在对话布局中显示可点击的命令浮层。搜索临时展开匹配思考块,清空后恢复手动选择。补充三项回归测试并同步功能矩阵与架构笔记。
1lck
left a comment
There was a problem hiding this comment.
Review 结论
Findings
[P2] 命令补全列表会把输入框挤没
位置: macos/Sources/Lithe/Views/Agent/AgentComposerView.swift:48-54,AgentSessionGuidanceViews.swift:175-176
实际影响:
- 补全列表放在输入区内部,
.frame(maxHeight: 168)。输入区默认高度约 210pt,扣掉上下栏(contextBar 30、toolbar 38、padding)后,ScrollView 容纳 TextField 的空间会被压到 0。 - 在 Codex 这类有大量命令的 Agent(11 个内置 + 约 38 个 $Skill)里输入
/,用户看不到自己在输入什么。剩余约 46pt 的溢出会盖住分隔条或把工具栏推出边界。 - 附带文件时还要再占 34pt。
触发条件: 连接命令很多的 Agent,输入框保持默认高度或更矮,输入 / 或 $。
修复建议:
- 把补全列表改成锚定在输入区上方的
overlay(alignment: .top)或 popover,向上浮在 transcript 上,不占输入区高度。 - 或者按输入区可用高度动态限制列表高度(例如最多
可用高度 − 输入框最小行高),并保证 TextField 至少保留一行。 - 加一条布局测试:在默认和最小高度的
AgentConversationLayout中渲染带 10 条以上命令的 composer,断言 TextField 高度大于 0,且内容不超出 sized pane。
[P3] 模式同步能力被并进斜杠命令矩阵行
位置: shared/platform-feature-matrix.json:344-366
实际影响:
current_mode_update同步权限模式选择器是可独立验收的能力,但只出现在agent-slash-commands行验证文案的最后一句。- 该行 evidence 没有列出真正实现它的
AgentConnectionModel.swift。 - 和 develop-lithe 里每行对应一个可独立验证的能力的规则不一致。
修复建议:
- 为
current_mode_update单独加一行矩阵(例如agent-mode-sync),evidence 写AgentConnectionModel.swift和对应测试,然后重新生成 Markdown/CSV。 - 或者把这句验证移到已有的
agent-acp-conversation行(模型/权限配置所在行),并补上 evidence。
观察项(不阻塞)
- 思考流式输出期间会同时出现两个思考中…:
AgentThoughtRow标题和底部等待行AgentThinkingRow。文案一样,但语义不同。可以考虑在有活跃思考块时调整其中一个的措辞。 AgentCommand.id直接用name。如果上游列表里出现同名命令,ForEach和scrollTo会遇到重复 ID。- 输入框的补全交互(Return 补全或发送、Esc 优先关闭、↑↓/Tab)没有自动化测试,只测了模型层的
suggestions(for:in:)。建议在真实界面走查时重点覆盖。 - 断开连接后,未附着会话仍保留上一个进程上报的
availableCommands,输入/会显示旧列表。发送时会先触发 load,由新进程重新上报,实际影响有限。
Summary
模型层改动集中、正确,状态都落在 LitheAgentConversationModule/Application,视图不解析原始更新,符合 Note 规定的边界。fixture 加 Rust 往返测试把四类更新锁定为合法 ACP。主要缺口在输入区内补全列表的布局:大命令列表在默认高度下会挤掉输入框,现有截图测试没覆盖这种组合。
CI 全绿。思考块、计划栏和模式同步还没在真实界面上走查过,Windows 端也还没接入(矩阵标为 pending/missing)。
|
已在
本地 Swift 6.3.3 运行 Agent 测试:102 项通过、1 项原有集成测试默认跳过;矩阵、Agent Notes、共享契约和 bundle 只读检查通过。已合入最新 preview 并解决生成文档冲突。 真实 Agent 思考、计划、模式同步的完整端到端仍待验收,矩阵继续保持 CI 修复补充( 原失败是 最新 Windows frontend job 已通过:真实安装一次完成(1,595 个包、175.4 秒),类型检查与前端测试成功。新增四项 Windows 回归测试全部通过,分别验证失败后恢复、永久失败、成功后残留子进程以及卡住超时;最慢 9.484 秒,均低于 30 秒预算。Windows 整个工作流已通过,包括 Rust 与真实 JDT;最新提交的 macOS Swift、Rust/Swift 桥接、arm64/x86_64 打包、数据库、插件、Agent Notes 和功能矩阵检查也全部成功。当前 PR 的全部 CI 检查 已通过。 |
概述
参考 jetbrains-cc-gui 的对话体验,补齐 macOS Agent 面板对四类标准 ACP 会话更新的展示:思考过程、执行计划、斜杠命令补全、模式同步。
共享 Host(
lithe-agent-host)一直把 ACPSessionUpdate原样转发给 Swift,但AgentConnectionModel.apply之前只处理消息、工具、标题、配置和用量,下面这四类更新都落进default: break被丢弃了。本 PR 不改 Rust Host、C ABI 或 fixture 结构,只在 macOS 功能模型和视图层补上解析与展示。改动内容
1. 思考块(
agent_thought_chunk).thought,思考内容单独成一条消息,不再并入 Agent 回复。AgentThoughtRow:正在流式输出的最后一段思考默认展开(显示“思考中…”),回复或工具到达后自动收起为“思考过程”;用户手动展开/收起后保持;搜索命中时临时展开,即使此前手动收起也能看到命中文字,搜索期间保持可见,清空搜索后恢复原来的手动选择。>引用块输出,和回复区分;历史列表的消息数只统计用户和 Agent 回复,不计思考。2. 执行计划(
plan)AgentPlan(AgentSessionGuidance.swift)。ACP 规定每次发送完整计划,所以整体替换;空列表清除计划;格式错误的更新忽略;最多保留 100 条;未知状态的条目丢弃而不是猜测。AgentPlanView固定在活动统计栏上方:折叠时显示“计划 已完成/总数 · 当前步骤”,展开后逐条显示待办 / 进行中 / 已完成。session/load回放历史时计划自然恢复。3. 斜杠命令补全(
available_commands_update)新类型
AgentCommand,按会话保存 Agent 上报的命令列表(最多 200 条)。输入框以
/开头、且命令名中还没有空白时弹出AgentCommandSuggestionList,显示名称、说明和参数提示;前缀匹配排在包含匹配之前。选择后只把
/name填入草稿,命令仍作为普通 prompt 原样发送,由 Agent 自己解释。Lithe 不内置命令表,也不扫描 SKILL.md,列表与 Agent 真实能力保持一致。Codex Skill 兼容:实测 codex-acp 1.13.1 把 Skill 以
$pdf形式放进同一个命令列表,但它的命令解析会跳过/$pdf。因此$开头的命令补全为$name(不加/);输入$只列 Skill;Agent 没有上报 Skill 时$仍是普通字符,不会被拦截。键盘:Return 在命令名未输完时补全、输完时发送;macOS 14+ 支持 ↑↓ 和 Tab 导航(
onKeyPress需要 macOS 14,macOS 13 保留鼠标选择和 Return);Esc 先关闭补全,回复中再按 Esc 才停止。补全布局修复:
AgentComposerDraftArea优先保留 36pt 的可编辑输入行,空结果、短列表和长列表按实际内容与剩余高度分配空间。最小输入区放不下一整行命令时,使用对话布局内的锚点浮层,让列表既可见也能鼠标点击;浮层不改变输入焦点,不向会话模型发布几何尺寸,也不新增全局监听。4. 模式同步(
current_mode_update)category == "mode"且包含该值的配置选项,不向上游回发设置请求;选项中没有的模式 ID 忽略,不显示原始 ID。5. 本地化补齐
String(localized:)并补齐 zh-Hans:Tool call、Allow the Agent to continue?、The Agent request failed.、三条 stopReason 提示(token 上限 / 请求次数上限 / 拒绝继续)。Output/Content/Diff/Terminal/Unsupported content本地化。6. 契约、文档与矩阵
shared/fixtures/agent/acp-events-v1.json新增agentThoughtChunk、plan、availableCommands、currentModeUpdate四个事件样例,并加入 Rust 往返测试serialized_events_match_the_shared_fixture,证明它们是官方 ACP SDK 可原样往返的合法格式(Windows 后续接入可直接复用)。2026-09-25-shared-acp-agent-conversation.md新增“思考、计划、斜杠命令与模式通知”一节,记录处理规则、正反例和资源边界。agent-reasoning-display、agent-plan-display、agent-slash-commands、agent-mode-sync(macOSimplemented/pending,Windowsmissing),并重新生成 Markdown/CSV 视图。7. 按审查意见修正
current_mode_update新增独立功能矩阵行agent-mode-sync,补齐AgentConnectionModel.swift、测试与 fixture 证据;从斜杠命令行移除模式同步验收语句并重新生成 Markdown/CSV。macOS 保持implemented/pending,Windows 保持missing/not-applicable。主要文件
macos/Sources/LitheAgentConversationModule/Application/AgentSessionGuidance.swiftAgentPlan、AgentCommand及解析、补全过滤macos/Sources/LitheAgentConversationModule/Application/AgentConnectionModel.swiftmacos/Sources/LitheAgentConversationModule/Application/AgentConversationState.swift.thought角色;会话增加plan、availableCommandsmacos/Sources/Lithe/Views/Agent/AgentSessionGuidanceViews.swiftmacos/Sources/Lithe/Views/Agent/AgentComposerView.swiftmacos/Sources/Lithe/Views/Agent/AgentComposerDraftArea.swiftmacos/Sources/Lithe/Views/Agent/AgentTranscriptView.swift测试与验证
自动化测试(已合入最新 preview
afb7a766;审查修复提交ccc5dbbd)test-stability-macos.sh -- --filter Agent,10 个套件 102 项通过,1 项原有集成测试默认跳过;新增 14 个测试(原功能 6 个、首次修复 3 个、本次审查修复 5 个):interleavedReasoningAndReplyBecomeSeparateMessagesInArrivalOrder:思考/回复交替时的切分、顺序与导出格式planUpdatesReplaceTheWholePlanAndAnEmptyPlanClearsIt:整体替换、未知状态丢弃、空计划清除、格式错误忽略advertisedCommandsArePerSessionAndFilterOnlyWhileTypingAName:按会话隔离、前缀优先过滤、$Skill 补全规则、命令原样发送agentReportedModeChangeMovesOnlyTheMatchingModeSelector:只更新模式选择器、不回发请求、忽略未知模式reasoningSplitsToolTimelinesAndIsSearchableButNotCountedAsAMessage:思考分隔工具组、可搜索、不计入消息数planReasoningAndCommandListsFitNarrowAndWidePanelsInBothAppearances:窄(280pt)/宽(620pt)面板 × 深/浅主题布局(已人工查看截图,长文本正常截断)thoughtSearchRevealsAManuallyCollapsedMatchAndRestoresItsPreference:手动收起后搜索仍展开,搜索期间保持可见,清空后恢复选择thoughtStreamingCollapsesAutomaticallyButKeepsManualExpansion:流式结束自动收起、手动展开仍保持commandSuggestionsKeepAWritingLineAtDefaultAndMinimumComposerHeights:在真实AgentConversationLayout中托管生产AgentComposerContent与原生 TextField,覆盖 400/700pt 对话高度、280/620pt 宽度、有无附件、0/1/40/200 条命令;验证默认输入区与最小输入区、输入滚动容器至少 36pt、TextField 可见且在 sized pane 内、完整命令行、浮层位置和对话范围commandKeysCompleteWithoutSendingAndSubmitFullInvocations:方向键循环选择、Tab/Return 只补全、完整命令 Return 发送及$Skill格式escapeDismissesSuggestionsBeforeCancellingAndEditingReopensThem:Esc 先隐藏建议、再次停止,编辑草稿重新显示,空匹配列表也遵守优先级unavailableCommandKeysLeaveOrdinaryTypingAndChangedListsUsable:普通文字、无匹配、未上报 Skill 的$和命令参数不拦截导航;列表缩短或断连清空时安全处理activeThoughtKeepsOneThinkingLabelAndTheWaitingTimer:活跃思考时等待行显示“回复中…”,取消优先显示“正在停止…”duplicateAdvertisedCommandsKeepTheFirstDefinitionAndUniqueRowIdentities:同名命令保留首条定义,ID 唯一,读取最多前 200 条agentExitKeepsTranscriptAndRequiresReloadAfterReconnect:所有会话断连清空旧命令,重连加载后只显示新进程能力,显式 stop 同样清空cargo test -p lithe-agent-host71 个测试通过,cargo fmt --check通过。verify-platform-feature-matrix、verify-platform-feature-matrix-change、verify-agent-notes、verify-shared-contracts、verify-runtime-bundle-immutability、测试稳定性静态检查均通过。真实 Agent 协议验证
用临时探针按 ACP 直连本机安装的 adapter,各建会话发一条消息(工具权限一律拒绝,未修改任何文件):
available_commands_update$xxxSkillagent_thought_chunkplan/current_mode_update上述协议探针没有覆盖所有更新。已核对两个 adapter 源码:Codex 的计划来自 turn plan 事件;Claude 的计划来自 TodoWrite/任务工具,退出计划模式时依次发送
current_mode_update和config_option_update。推送格式与 fixture 一致。探针还发现了上面的/$name问题,已在本 PR 修复。真实界面验证(本次修复):生产预览连接本机 Claude 配置,显示 Opus 4.6,取得会话实际上报的命令列表。默认和拖到最小输入区时输入区域均保留 36pt;方向键选中最后一条后列表滚动跟随,Tab 填入命令;真实鼠标点击浮出的
/design后填入/design;Esc 关闭建议并保留草稿。验证只补全,没有执行这些命令或发送模型请求。思考块另用编译当前生产视图及状态代码的原生探针验证“手动收起 → 搜索展开 → 清空后恢复收起”,只替换样式依赖。真实思考、计划与模式同步的完整端到端验证仍未完成,功能矩阵继续标为
pending。应用、探针及关联子进程均已退出,临时探针注销并归档。已知问题(与本 PR 无关)
verify-service-boundaries.sh因AppModel+RunConfiguration.swift为 616 行(上限 600)而失败,preview 基线上同样失败,本 PR 未触及该文件。test-macos.sh时约 20 个 Git / 文档 / 回滚相关的并发测试失败,preview 基线上同样失败;串行(--no-parallel)重跑全部通过。不在本 PR 范围
Windows 端尚未接入 Agent 对话 UI(矩阵中标为
missing)。后续计划另开 PR:流式渲染性能、块级 Markdown 与代码高亮、输入框排队与@文件补全、ACPfs/terminal客户端能力。Windows CI 安装失败修复(
cd7315bf)原失败发生在
tree-sitter-cli下载超时:Bun 返回失败后,并行生命周期脚本仍占用tree-sitter-kotlin目录,导致冷重试的清理阶段再次失败。原失败任务重跑已通过,另外补上进程清理保证:node_modules、两个 workspace 的依赖目录与.artifacts/bun-tmp,复用脚本测试、CI 文档与工程决策笔记同步更新。本地缓存校验、资源复用测试(7 项)、测试稳定性、Windows 边界、bundle 只读、Agent Notes 和矩阵检查通过。新安装回归用例在 macOS 明确跳过,已由 本次 Windows frontend CI 在 Windows 执行并全部通过(4 项,最慢 9.484 秒)。真实安装一次成功(1,595 个包、175.4 秒),类型检查和前端测试全部通过。下载的前端计时报告共 1,018 条通过记录,含重复验证;最新提交的 6 个工作流、20 项 CI 检查全部成功(包含 macOS Swift、Rust/Swift 桥接、双架构打包、数据库、插件、Agent Notes 和矩阵)。