36 KiB
对话区动态交互对标与验收
阶段状态(2026-10-08):按用户要求,对话区在本阶段收尾,暂不继续修改。当前进度汇总与剩余优先项作为恢复入口。本文保留各批次证据;历史实现描述以后续修正为准,不能当作双端原生流式1:1已完成。
用户于 2026-10-08 明确:目标包括后续真实流式交互的效果一致,不仅是历史对话静态外观一致。本文件与 原生渲染差异清单 同时使用;静态修复不代表动态完成。
通用组件路径补查(2026-10-08)
后续品牌统一:按用户要求移除source_app驱动的助手名称/头像切换;所有会话统一显示Ygent及其图标。来源元数据仅用于数据溯源。
新增全会话入口核验:普通会话2(12条消息)与参照会话5(829条)在真实1335×916 WebView2切换比较,工具摘要共同命中15px/26.25px、rgba(0,0,0,.5)、border-left:0。source_app仅用于来源溯源,不选择独立对话渲染器,也不切换助手名称/头像。普通完成/多工具组与特殊取消仍有不同过程容器及间距规则,不据此宣称所有状态已对标完成。
路径标签通过共享Markdown代码组件实现:来源关联元数据用于参照快照,普通对话使用所属会话工作目录下的真实IPC批量分类;不存在的路径保持普通代码,迟到查询不会污染另一个会话/代码标签,增量追加保留路径控件。原生IPC核实普通会话可识别真实.agent目录并排除不存在的候选;同一参照标签ygent与WB均68.25×20、15px/22.5px、padding1px 4px,图标15×15。内部推理正文未导入,仅恢复有来源事件的“深度思考”标题;无内容不提供假的折叠交互。未来模型的公开思考摘要/阶段事件仍未接入。
“运行命令”上下样式遗漏修复后,继续检查同一组件在不同容器/阶段的路径。新增确认并修复4项:
| 位置/触发 | 问题 | 修复及验证 |
|---|---|---|
TurnBlock取消状态按钮 → .turn-history |
收起父层直接卸载历史,工具/意图展开状态和结果节点丢失;下方ProcessGroup已保留 | 历史首次展开后保持挂载,hidden隐藏。组件回归和真实1335×916 WebView2均验证结果节点与两级展开状态保留;还原操作前展开状态 |
renderSegment单工具 → 同段第二条工具增量 |
ToolCard变成FoldGroup,第一条工具被重挂载,已打开详情关闭 | 单工具与多工具共用稳定FoldGroup边界,单条不显示组标题。组件回归检查节点身份和意图展开状态;未新增真实模型/WB流式验收结论 |
FoldGroup多个独立工具组 |
每组标题使用全回合toolCallCount,两个2条组均显示4 | 摘要仅计本组seg.items.length;两个工具组的组件回归通过 |
getCancelledTurnLayout含show_widget的末段 |
特殊取消布局把可视化工具传入ToolCard,绕过WidgetArtifact | 初次修复回退正常时间线;后续锚点分段保留产物/权限为独立visible段,不进入普通工具过程折叠;正常→取消及锚点布局回归确认iframe和权限操作仍存在 |
后续取消布局修复:工具摘要、意图/结果和工具组展开状态改由TurnBlock所属回合持有,以回合ID、消息ID及层级作为键;ToolCard/FoldGroup/ProcessGroup共享状态入口,跨父容器重新挂载时恢复原选择。自动折叠依据的上一次shouldFold/processExpanded也随组保存,普通增量或重新挂载不会再次覆盖手动选择;真正触发条件变化仍遵循现有自动折叠逻辑。回归覆盖多工具历史组和末段工具从流式→取消、手动打开组/详情、明确关闭另一条详情、取消后结果更新;全部通过。真实1335×916 WebView2的历史收起/重开仍通过。跨取消布局迁移的验证来自组件回归,没有向参考会话发送请求或注入状态,不声称双端原生动态验收完成。状态限定于当前回合组件生命周期,不写入数据库;迁移会重新创建DOM,此次未保证文字选择或结果面板滚动位置保持。
残留项:通用工具组与“过程消息”组的语义和箭头显示规则不同,不能直接统一所有行为。通用组的色彩、箭头方向及标题到内容的留白已按下节修正;摘要分类、子项间距、非命令工具取消时的图标语义仍待核实。
验证:pnpm check:chat、node scripts/fe-check.mjs、pnpm build通过。以上是路径一致性修复,未表示S04完整通过。
第一批动态P0实现结果(2026-10-08)
共用折叠样式与源码分组补查(2026-10-08)
依据当前安装的WorkBuddy产物renderer/assets/lib-chat-ui-BAUBpUwu.js中的UJ、$Jn、tYn及lib-chat-ui-B-axvvx6.css中的_metaFold*_9ymy5_*,仅分析渲染规则,没有读取或展开内部推理正文。以下明确区分源码证据和原生验收。
| 位置 | 本轮结果 / 下一步 |
|---|---|
通用多工具组标题.mf-head |
从蓝灰改为黑50%,字号仍使用六档统一变量,默认15px/26.25px。 |
标题末尾.mf-arrow |
原来收起时向下、展开时向上且离开鼠标隐藏;现在收起向右,展开向下并保持可见。通用组SVG16×16、margin-left:-4px;“过程消息”保留自身12×12及始终向下规则。 |
标题底→首个工具.meta-fold > .mf-body |
外层gap由8px改0,折叠体上下padding各2px。子项gap8px及相邻工具margin尚未对标,不将整个工具组间距标为完成。 |
折叠后的可见正文getTurnFoldLayout |
完成/取消已共用锚点规则:按trim后正文长度保留所有并列最长非空正文及最后正文,首个锚点前归历史、锚点之间归过程。不再要求至少三段或恰好两段可见正文;规则不依赖会话身份。双端动态折叠时机尚未完整验收。 |
通用组摘要FoldGroup |
动作摘要文字已接入:按动作分类、参数对象、相邻正文及状态生成摘要;离线与当前安装WB纯函数1760组对照一致。组头图标、推理事件参与分组及双端原生流式标题切换仍待补验;不把任意工具意图直接拼成摘要。 |
原生Ygent9335、1335×916、DPR1:会话5检测到130个通用组,本轮对首个组实测收起opacity0/rotate(-90deg),展开opacity1/transform:none,16×16、组gap0、body padding2px 0px,随后恢复展开状态及原会话。普通会话2没有通用多工具组,仅验证入口,不能算多工具验收通过。WorkBuddy9223当前可见区域没有通用MetaFold;展开两条已完成状态仍未出现该组件并已还原,此处通用组样式目标依据当前安装源码,尚缺同一通用组双端运行时对照。
验证:pnpm check:chat通过,覆盖增量、单→多工具、结束折叠、取消迁移及手动展开保留;没有向真实会话发送请求。原始源码和运行时记录保存在私有目录.ygent/imports/render-audit-20261008。
正文锚点分段实现与验收(2026-10-08)
本节记录最初取消回合实现;下节“完整时间线/摘要统一”取代仅打开前段历史的入口行为。
CancelledTurnLayout由固定firstReply/process/lastReply改为anchor/process/visible段序列;中间短正文与普通工具可共同进入过程折叠,多个最长锚点可产生多个过程组。权限和widget保留专用渲染器,位于过程之间时在原顺序显示,不当普通工具处理;历史首次展开后保留挂载。没有历史内容时显示静态取消状态,避免提供空历史折叠按钮。工具/意图展开选择仍由所属回合按稳定消息ID保存。
最后正文之后的真实工具保留在正文之后,不移到正文之前或丢失。WB源码tYn仅枚举锚点之前/之间的内容,本轮没有真实WB晚到工具事件对照,因此尾部事件策略仍待动态验收。既有导入快照中没有执行结果的占位调用保持不冒充已执行命令;数据库原消息不删除。权限/widget的折叠位置也需双端补验。
组件回归新增:最长在最前、并列最长(含前后空白)、单正文之前有工具、两正文之间有工具、空白正文、短正文夹在过程、widget/权限控件、末段之后真实工具顺序及导入无结果占位。原有运行→完成、运行→取消的组/工具/意图手动展开保留回归全部通过。
原生YG WebView2/CDP9335,1335×916、DPR1,真实参照会话5:目标取消回合保持2段可见正文、1个过程组;历史5段正文/5条工具、过程1条工具。父过程关闭隐藏结果面板、重开保留相同面板节点与意图展开状态、历史关闭保持挂载,3项通过,操作后恢复原会话及展开状态。记录为私有anchor-layout-native-check.json。未发送模型请求、未注入假数据;其他锚点排列来自组件回归,不能宣称已完成WorkBuddy双端流式验收。
完整时间线/摘要统一(2026-10-08)
getTurnFoldLayout不再限定取消状态。TurnBlock在回合结束后使用共用分段,运行中持续显示完整时间线;完成/取消状态按钮均切换完整时间线和锚点摘要,展开时不再只是补前段历史或强制打开所有工具组。无隐藏历史/过程时不提供无意义的整体展开按钮。待确认权限仍在时跳过整体折叠,保持操作可见。
依据当前WB源码D5n:整体折叠时渲染anchor/process,展开后恢复通常的内容/MetaFold段;不能把整体展开理解为每条工具详情都展开。Ygent完整时间线.turn-history和摘要.turn-folded互斥显示,首次挂载后以hidden保留节点;已在流式阶段挂载的时间线在完成后仍保留同一结果面板。两种呈现的工具/意图状态共享稳定消息ID;完成后的最终输出增量不会重置手动整体展开,摘要中的过程组选择也在整体往返后保留。新增.folded-layout统一终态布局样式,原.cancelled-layout不再作为专用呈现分支。
组件回归新增运行→完成的整体自动收起、完整时间线/结果节点身份、工具详情状态、最终输出更新、摘要过程展开及整体往返,完成/取消纯分段结果一致。pnpm check:chat及pnpm build通过。
原生YG9335、1335×916、DPR1:普通会话2的完成回合、会话5的完成/取消回合共3项样本,分别验证摘要与完整时间线互斥、关闭隐藏完整时间线、重开同一时间线与结果节点、意图状态保留,全部通过。会话5完成样本摘要1段/完整3段,取消样本摘要2段/完整7段;普通样本摘要/完整均1段,隐藏的是工具历史。证据私有full-turn-fold-native-check.json。WB9223同视口对“已完成11m33s”及“已取消4m28s”状态按钮往返,collapsed类正确切换并还原;本轮未获得可排除祖先裁剪/推理标记的可见正文计数,不据此宣称两端计数相等。
剩余:WorkBuddy活动回合资格/自动整体折叠触发时刻、模型底座真实流式终态、末段后事件策略、组头图标、组内间距及滚动锚点。工具动作摘要见下节。当前保留两种呈现的DOM会增加历史展开后的挂载量,超长会话性能待专门验收;不把节点保留直接等同于文字选择/滚动位置已通过。
工具动作摘要(2026-10-08)
src/lib/toolSummary.ts实现已安装WB的mJn/IJn/VJn规则,toolSummaryRules.ts记录40种动作及别名/简体中文词汇。对象按字段优先级在参数、嵌套结果、结果中查找;路径缩为末级名称、URL缩为主机名、中日文最多16字符、其他语言最多6词。命令不采用command内容作为摘要对象;同组动作聚合,混合组按数量取主要两阶段,有对象时优先对象、没有时使用经过前缀/后缀及泛词过滤的相邻正文主题;超过3类且没有主题时显示操作类别数量。未知工具使用“继续处理任务过程”,空摘要才走统计兜底。
运行中给可修饰摘要加“正在”,计划退出/提问按实际工具状态显示等待;全部取消保留取消状态。失败不再给动作标题追加“几个错误”,原toolError、失败图标、退出码和输出仍保留在工具层。computeTurnFold把本组摘要及后/前相邻正文交给通用FoldGroup;不同会话使用同一规则。标题单行,最大520px并以省略号裁剪,默认15px/26.25px且继续跟随六档字号。
验证分层:私有summary-oracle-check.mjs在离线隔离VM中仅执行安装产物的纯摘要函数(不执行整包、不读取内部推理),40种动作/别名、混合组合、完成/运行/取消、前后主题共1760组,与Ygent结果逐项一致。仓库tool-summary-check.mjs另覆盖命令正文排除、失败保留、未知动作、等待、URL、结果回退、非法增量JSON等17个场景;已纳入pnpm check:chat。组件回归确认“正在运行命令”→“运行命令”更新保留同一组头、手动展开及同一结果面板。
原生YG9335,1335×916、DPR1,真实会话5展开一条完整时间线后取3个组:6/5/18条工具对应README.md/App.tsx/lib.rs主题;实测15px/26.25px、max-width520px、ellipsis。折叠往返组头节点保留,通过;操作后还原原会话及状态。私有证据tool-summary-native-check.json。没有向参照会话发送请求或注入delta。纯函数一致不等同于真实WB原生流式标题切换通过,推理事件的组成员、组头图标、当前模型底座工具命名适配仍需单独补验。
S01、S02、S06的主链路已修改。以下为实现与验证状态,不表示双端WorkBuddy动态对照完成。
src/lib/chatRun.ts按请求/稳定块ID管理正文;工具切开正文,后续文字创建新块。工具start/update/end原位合并,并行工具按创建顺序排列,空结果进入完成态。- SQLite先按块创建顺序插入,再原位更新;写队列合并尚未写出的增量。v9增加tool_state,保存完成/取消;启动时恢复中断工具。切会话缓存保留未落库的块,重载依据行顺序。保存失败提示用户并保留内存。
- OMP用messageId:contentIndex定位正文,独立消费工具更新、保留完整输出;prompt_result.id关联提交命令。sessionSettled:false时保留绑定直到session_settled;同步本地命令依据agentInvoked:false结束。依据为项目内docs/reference/omp/rpc.md;旧版缺字段时使用单请求串行回退。
- Codex用thread/turn/item ID定位,outputDelta追加、aggregatedOutput替换最终快照。记录已完成turn和OMP message归属,拒绝旧通知;进程代次隔离旧reader。
- 两种底座和直连统一携带request_id/session;取消保留正文、终结工具及授权,关闭请求拒绝所有迟到事件。新请求等待取消IPC返回,OMP还须等待旧请求settled。ack超时不等于拒绝,保留绑定直到终态;没有终态时需恢复内核,不允许混叠发送。
- 直连SSE按字节缓存完整行后解UTF-8,中文/emoji跨HTTP包不再被逐包lossy解码损坏。
验证:pnpm check:chat通过(组件/模拟IPC事件回归);cargo test --lib共16项通过(含完整输出、块ID、未settled阶段、数据库交错完成顺序、请求写入前取消)。pnpm build通过,既有bundle大小提示仍存在。
原生YG端到端:真实Rust/Tauri IPC/WebView2,1335×916、DPR1,独立数据目录、本机受控SSE。跨包中文/emoji、代码容器身份、内容落库、取消标记、新请求不混旧流、重载内容一致,6项通过。时间线记录时刻、pending、文字长度和滚动尺寸;私有证据在 .ygent/imports/render-audit-20261008/native-stream-check.json。HTTP模型服务是受控测试服务,未替换IPC;不声称真实OMP/Codex或WB动态过程通过。
正式会话5(829条)未发送测试请求。隔离实例与SSE服务关闭,正常YG调试实例恢复9335。
剩余:WB的阶段序列/动画/自动展开策略,真实OMP/Codex原生验收,reasoning、单工具升级成组的双端原生动态验收、异步高度/滚动锚点、队列和操作栏。单工具升级的组件节点/展开状态回归已通过,不再列为未实现。崩溃恢复完整请求、保存失败自动重试、超大OMP分片协议尚未实现。
验收对象
同一输入、相同视口/字号/展开状态,比较两端从提交到结束的状态序列。模型输出内容和网络速度不同,不能据此要求每个 token 的墙钟时间一致;比较对应事件后的显示位置、块顺序、更新方式、折叠、滚动和操作反馈。具体动画时长、节流频率、自动展开策略须从当前 WorkBuddy 原生运行时取得,不凭旧产物或猜测设定。
不在参考历史会话内发送测试消息或执行工具。自动化回放应使用隔离测试会话和限定事件序列;组件回归及模拟事件只验证实现,不能作为两端真实流式验收。验收报告区分:源码确认、组件回归、YG原生实测、WB原生实测、双端对照通过。
P0:先解决事件和渲染状态
| ID | 位置及触发序列 | 当前确认的问题/状态 | 通过条件 |
|---|---|---|---|
| S01 | src/stores/chat.ts,正文A → 工具开始 → 工具结束 → 正文B |
chunk 都追加至 streamingId 的同一节点,未按正文块边界创建后续节点;旧快照的多个正文块不证明真实流式正确 |
A、工具、B保持事件顺序,各块ID稳定;持久化/重载保持该顺序,无复制或丢字 |
| S02 | src-tauri/src/sidecar/omp.rs → src/stores/chat.ts,工具 start → 多次 update → end |
OMP update 被归为 start/done,没有独立 update 映射;前端类型虽有 update,分支未消费;可能创建重复卡或过早完成。OMP结果还截为300字符 | 相同工具ID原位更新;进度更新不表示结束、不新增卡;完整输出保留,成功/失败/空输出正确 |
| S03 | src/components/Markdown.tsx,未闭合代码块持续追加,最后闭合 |
已去除随文本长度变化的key,并更新表格引用闭包依赖;组件回归通过。当前WB增量解析、动画、节流仍待实测 | 增量不重挂载稳定容器;复制/选择/横滚不被清空;未闭合围栏、表格、公式、mermaid的中间态按WB逐项验收 |
| S04 | src/lib/turnFold.ts、TurnBlock.tsx,工具1 → 工具2 → 后续正文 → 回合结束 |
单→多工具、终态折叠、完整/摘要往返、手动展开及节点保留已有回归;动作摘要纯函数1760组对照一致。组头图标、DOM选择/横滚、WB自动折叠时机及双端原生流式摘要仍待核实 | 自动折叠触发与WB一致;用户手动展开不被无关delta打回;组形态变化不丢内部状态;统计仅算本组,不用全回合计数 |
| S05 | ChatView.tsx:269附近,贴底 → 增量变高、上翻 → 增量变高 |
仅监听messages/atBottom;异步公式、widget及子组件展开引起的高度变化未统一处理,40px跟随阈值未与当前WB核对 | 贴底跟随;主动上翻不被拉回;回底重新跟随;展开/图片加载/字体变化不误判用户离底;记录scrollTop、scrollHeight、阅读锚点 |
| S06 | chat.ts的事件监听与全局streamSid/streamingId,取消 → 迟到事件 → 新请求 |
chunk/done/error缺少一致的请求身份过滤;工具事件未在取消后统一终结;任务切换时只有单套全局缓冲 | 取消即时停止,已有内容保留;迟到事件不污染新回合;未完成工具有明确终态;切会话不混流;恢复历史与即时显示一致 |
| S07 | 思考、首字等待、耗时、停止按钮及错误入口 | YG有等待动效、光标和pending按钮,但未取得WB对应动态序列;reasoning数据类型未接入 | 首字前、思考中、文字中、工具中、完成、错误、取消每一阶段的可见元素与参考一致;不伪造推理正文/模型/消耗 |
S01、S02、S06先于进一步像素微调;上表保留修复前基线,主链路结果见本文开头,双端动态证据尚未取得的部分仍未完成。
当前已验证的局部交互
ProcessGroup:过程、运行命令、意图、结果四层。意图独立折叠;关闭工具或过程再打开,保留意图和结果状态;第一次打开前不创建结果DOM,打开后隐藏而不卸载。- 真实YG WebView2 CDP9335、1335×916、DPR1、默认2档、真实会话5:意图关闭仅隐藏结果、工具往返保留意图、父过程关闭隐藏子层、父过程往返保留子层、结果节点身份稳定,5项均通过。
- 当前WB参考回合:同条件的状态dy36.5、过程dy140.25、运行命令dy168.5、意图dy198.75、面板dy227.25,与YG一致;面板752×198.75。此处只验证已有回合和折叠交互,不代表生成中策略一致。
node scripts/chat-render-check.mjs:增量Markdown保留代码容器和复制按钮;嵌套折叠往返;结果更新原位保留;多工具组运行→结束自动折叠→手动重开保留状态。脚本为组件测试,使用合成数据、无CSS、不调用后端。jsdom优先读取项目安装,未安装时沿用现有fe-check的本机workspace回退路径;跨机器需自行提供jsdom。
执行顺序
- 获取当前WB流式事件到DOM的映射及时间序列,补齐未知策略;同时修YG的正文分块、工具update和请求身份过滤。实现需以稳定turn/block/tool ID为依据,不能靠历史样本最后两段的排列模拟实时状态。
- 建立隔离、可重复的事件回放回归:逐字与批量delta、交错工具、并行工具、空输出、错误、取消、迟到事件、切会话和重载;验证内存和数据库都保持顺序、内容和终态。
- 用真实原生YG与WB执行受控交互,采集MutationObserver时间线、节点身份/rect、折叠状态、滚动量及必要的短录屏。比较事件后的阶段效果,组件回放通过后仍须原生验收。
- 再收敛动画、图标、回合操作栏和布局细节;每次结构调整复测流式/滚动/取消,避免为历史静态画面破坏实时行为。
必测序列
| 序列 | 必须记录的阶段与位置 |
|---|---|
| 发送与首字 | 输入草稿清理、用户气泡出现、助手等待、停止按钮、首字替换等待 |
| 正文流式 | 短delta、跨行、代码围栏半截、表格半行、公式、mermaid;正文尾部光标、布局跳动与已完成块节点身份 |
| 工具流式 | start/update/end、空结果、失败、两工具交错;摘要/意图/结果每层可见性、图标状态及输出累计方式 |
| 折叠 | 单工具升级为组、出现后续正文、done自动收起、手动展开后继续delta、父层关闭再打开 |
| 滚动 | 底部跟随、上翻不跟随、回底、展开变高、图片/widget/字体异步变高 |
| 结束与恢复 | 正常完成、停止、失败、重试、切会话、应用重启;耗时、操作栏、按钮终态、消息数量/顺序/内容 |
完成定义:这些序列获得双端原生对照证据,未验证项为零;当前静态清单中已修复项目不计作动态验收通过。
2026-10-08:生成过程工具列表刷屏修复
真实原生 Ygent 的 hello 会话在生成时连续展示 45 次 read/grep/todo 调用,正文尚未出现时工具组一直展开。用户确认优先问题是生成过程被工具列表刷屏。本次将连续两个及以上工具调用默认收成动作摘要和数量;生成中额外显示正在执行的工具动作,没有运行工具时显示“正在思考”。这行提示不带转圈图标,“正在思考”文字使用从左到右的扫光,减少动态效果设置下使用静态文字。单个工具不增加分组层级。已知工具使用共享中文动作/对象摘要,长标签省略显示。
组和工具详情仍使用所属回合的稳定消息 ID 保存展开选择。手动展开、收起不会被普通增量或完成事件重置;单工具升级为组时,用户已打开的结果也保留。消息数据和结果没有删除,点击摘要可查看全部调用。
活动提示进一步统一:原首字等待的三个圆点和“正在思考…”已移除。首字等待与工具间隙共用回合底部的 Thinking 组件,每回合最多一处活动提示,且不依赖工具组是否展开。“正在思考”四字使用 2.2 秒循环的逐字扫光/上浮,每字错开 0.14 秒,上浮最大 1px;执行工具时短动作前缀扫光(命令显示“正在执行命令”),对象文字静态。正文正在流式输出时沿用尾部光标,权限待确认时不显示思考提示,完成/取消/失败终态移除活动提示。减少动态效果下取消动画。
此次新增回归覆盖空正文与工具同时存在时提示去重、单工具执行、组展开保留活动提示、正文/授权/终态切换。原生 WebView2 辅助挂载组件检查实际字号、动画关键帧、逐字延迟、静态文件名、展开状态与提示数量,结果通过;未修改真实会话/IPC,也没有发送新的模型请求。证据为私有 activity-check.json。完整 check:chat、类型检查和构建通过;不将辅助挂载结果当作真实 OMP 流式端到端验收。
随后修复单工具升级为多工具组时的瞬时展开:原实现沿用单工具 open 状态渲染组头及列表,再由 useEffect 自动收起;现在分组策略变化时在本次渲染直接计算正确 open,effect 只同步持久状态。用户主动展开及已打开的子详情仍保留。组件与原生 WebView2 辅助 MutationObserver 回归检查升级过程没有出现组头 aria-expanded=true 后又自动收回的瞬态;真实用户刚才的瞬态没有录制,不能断言只存在这一种原因。私有证据为 flash-check.json。
按用户对动效质感的反馈,活动提示最终改为稳定文字和柔和整行扫光:取消逐字拆分、上浮和蓝色高光,使用次级灰色到弱化灰色的渐变,3秒一轮;12%前和72%后保持静止,光带连续从左到右经过整段动作文字。思考和工具动作共用同一效果,对象仍静态。原生 WebView2 辅助样式采样确认整个周期文字坐标、宽高稳定、无 transform,动画时长3秒且保留停顿;证据为私有 soft-shimmer.json。组件回归、类型检查和差异检查通过,未发送真实模型请求。
用户继续反馈思考上方闪出工具行/列表,补齐另一处切换策略:第一条实时工具原先直接展示 ToolCard,第二条才升级摘要。现生成中的单工具也直接使用摘要入口,后续增量复用同一组头节点,避免独立工具行先出现又被收回;本次运行中建立的摘要在完成后保留。已存在且未经过实时显示的历史单工具仍使用原来的直接工具卡。手动展开和取消布局迁移保持原行为。组件及原生 WebView2 辅助检查验证首条工具无独立工具行、1→2组头节点稳定、没有瞬时展开;未发送新真实模型请求。临时只读 flash audit 仅记录当前页面的状态/尺寸/类型,保存在页面内存,不采集正文。
首字衔接试验(已撤回,以下仅保留阶段记录):空的最新流式回复在自己的 ReplyText 容器中显示“正在思考”,首字到达后同一容器立即渲染原始 Markdown,同时进行120ms交叉淡入淡出;思考残影绝对定位、对辅助技术隐藏、不占第二行。后续 delta 不重新入场、不延迟正文、不模拟逐字播放。无空回复占位的等待及执行工具仍沿用原活动提示,工具分组/状态/存储/滚动代码未修改;历史已存在正文不新增入场动画,减少动态效果时直接切换。
组件回归验证首字前后容器稳定、增量代码节点保留、残影清理、后续增量不重播;既有发送/权限/工具分组/完成/取消回归通过。原生 WebView2 辅助采样确认等待与首段正文起点同为y=156.5,首段文字立即可读,后续段落节点稳定且动画停止;证据为私有 reply-handoff.json。没有发送新的真实模型请求,真实长回合滚动及双端动态对照仍待验收。
当前有效规则:整个生成期间固定播报
用户明确期望是“正在思考”后面像字幕一样过流式内容,并在整个生成期间保留。已撤回 ReplyText 淡出替换及相关 CSS,恢复原来的正文 Markdown 渲染。新增独立 StreamingActivity 展示层,放在助手回合正文上方;左侧固定思考扫光,右侧将该回合正文纯文本及工具动作按消息顺序组合为单行播报,隐藏代码围栏正文/表格行及 Markdown 标记。短内容直接显示,超长内容左移,达到已收内容末尾后停止且保留,新增内容继续推进;展开工具、正文输出和等待授权都不移除栏,授权提示在右侧说明。结束后移除栏,沿用原来的完成/取消/失败呈现。
播报只保留最近4000字符作为视觉缓冲,速度80~320px/s,过多积压跳到距末尾约两屏的位置;截掉旧内容时继续靠近新内容。减少动态效果下直接显示末尾;尺寸变化重新检查溢出,组件卸载清理 RAF/ResizeObserver/媒体监听。右侧不加入逐字辅助技术播报,避免与正常正文重复。工具分组和展开状态、发送/事件/数据库、正文流式速度与滚动逻辑未改动。
完整 check:chat 和类型检查通过;组件回归验证左侧持续挂载、正文增量独立更新、间隙保留内容、工具展开和授权不消失、终态移除。原生 WebView2 辅助播报测试验证 scrollLeft 连续增长、追到末尾后保持不动、新增内容恢复移动、栏和正文节点保留以及正文立即完整显示;证据为私有 broadcast-check.json。没有发送新的真实模型请求,真实长回合的阅读/滚动体验与双端动态对照仍待验收。
用户指出上述动作/文件名摘要仍经过整理,现播报数据源改为当前消息事件的原始字段:agent.text、工具 fn/toolArgs/toolIntent/result、权限 text,按消息顺序以换行连接。撤掉 summarizeTools、文件名缩短、Markdown 清理和代码/表格替代文字;显示区域仍为单行,所以换行仅作为视觉空白,DOM文本保留原始换行。最近4000字符的视觉缓冲、固定思考标签、暂停/续播机制和正常正文/工具卡均不变。“原始”限于现有接入事件的内容字段,不宣称接入网络协议帧或模型隐藏推理。组件回归及原生 WebView2 辅助检查确认代码围栏、完整路径、JSON参数和工具输出逐字保留,证据为私有 raw-broadcast-check.json;没有发送新的模型请求。
随后按用户要求缩短可见播报窗口:最大18em(当前字号实测270px),滚动速度改为240~720px/s,仅提高视觉播放速度,不改变模型输出速度或原始内容。原生辅助检查300ms内scrollLeft推进144px,完整参数仍保留;私有证据为 fast-broadcast-check.json,类型及差异检查通过。
位置及运行耗时修正:播报栏已从回合顶部移回正常正文/工具时间线下方,生成期间持续保留。助手头像/名称下方的既有状态位置新增“进行中+耗时”,使用本回合 startedAt(缺失时使用首条事件时间),独立组件每秒更新,流式暂停也计时;终态卸载定时器并保留原有完成/取消耗时逻辑。组件回归验证无delta时计时推进、播报位于时间线之后、终态不残留计时器组件;原生 WebView2 辅助检查确认status位于头像下方、播报位于history下方、25s→26s推进以及取消后保持“已取消25s”,私有证据为 live-time-check.json。未发送新的真实模型请求。
运行状态文案参考 WorkBuddy
当前安装的 WorkBuddy 5.7.6 产物 zh-cn-CEs_4LQ3.js 的 progress.phase.* 定义了“准备中”“等待模型响应”“生成回复中”“处理结果中”“调用工具中”及分工具动作、“等待授权”“等待回复”“重试中”等。workbuddy-provider-cuZEv46I.js 的 nu 根据 phase/toolName/streamingToolName/pendingInputKind 选择对应文案;这些状态来自事件,而不是耗时阈值。原生当前页面只处于终态“已完成6s”,未发送WorkBuddy请求采集这些阶段的实时序列。
Ygent 新增 liveTurnStatus,共享同一耗时位置,根据可观测消息状态切换:空回复或工具结束后等待后续事件为“等待模型响应”,最新正文正在streaming为“生成回复中”,running工具优先显示“正在读取文件/列出目录/写入文件/编辑文件/搜索文件/搜索内容/执行命令”,未知工具为“调用工具中”,pending权限优先为“等待授权”。文案参考WorkBuddy,但分类映射使用Ygent/OMP工具别名。耗时仍为本回合总耗时,不因阶段变化清零;底部固定思考/原始播报规则不变。
目前没有可靠事件区分准备、模型工具参数生成、重试、模型结束后的处理/快照同步,故没有伪造这些状态。用户问题/计划退出工具采用“等待用户确认”,更细的授权类型需额外事件字段;不能仅由参数文字猜测。组件回归与原生 WebView2 辅助检查覆盖等待→正文→读取→命令→再次等待→授权、同一播报节点和耗时保留;证据为私有 status-phases-check.json 和本机 asar 源码片段,check:chat与类型检查通过。尚不宣称双端原生状态序列已完成1:1验收。
验收:真实 Tauri WebView2 CDP 9335、1335×916、DPR 1,会话 7 的 45 次工具调用在完成后折叠为 26.25px 高的摘要行;展开后显示中文动作,再收起正常。组件回归覆盖 45→46 次调用、当前动作、节点身份、详情保留、手动收起与终态;npm run check:chat 和 npm run build 通过。此次没有发送新的真实 OMP 请求,生成中策略由组件增量回归验证,不能据此宣称双端原生流式对标全部完成。真实截图和 DOM 证据保存在用户私有 .ygent/imports/hello-layout-20261008/,不提交会话内容。
回复操作栏(2026-10-08)
已结束的助手回合底部统一显示复制、分支到新聊天和回复模型。复制整个回合的回复正文,沿用已复制/复制失败反馈。分支包含所选回合最后一条助手回复及其之前的上下文,不包含后续消息;OMP 使用原生 fork 和真实会话文件,直连使用数据库上下文。生成期间不显示该操作栏,生成中禁用其他回复的分支操作。
模型在请求开始时记录并随消息持久化,历史未记录的模型显示“模型未记录”,不使用当前选择冒充。回复时间紧跟模型名称,间距 10px;悬停助手回复区域或键盘聚焦操作栏时显示,提示中包含完整日期时间。
验证:组件回归覆盖整回合复制、复制反馈、末条回复分支、历史模型缺失和生成期间隐藏;Rust 回归覆盖包含助手回复的分支边界、元数据保留、重复文本与活动路径映射。类型检查、check:chat、Rust 25 项测试与前后端构建通过。真实 Tauri WebView2 9335(1335×916)使用临时受控 OMP 转录文件验证原生 fork、数据库前缀复制、模型元数据读写、时间位置和显隐;测试会话已删除,原会话未发送模型请求。这是原生分支/渲染验收,不代表真实模型流式或 WorkBuddy 双端对照已完成。
UI 优化回归补充(2026-10-10)
原生受控 Responses 回归发现等待空块在 text-end 被移除、首个工具事件尚未到达时,回合会短暂消失;首条消息 ID 随之变化也会重建整个回合。展示 key 现使用前置用户消息 ID;运行中最后一行只有用户消息时保留同一空回合,工具/正文按实际事件到达,展开作用域也使用稳定回合身份。无用户消息的历史回合仍使用原事件 ID。
真实 WebView2 + 实际 OMP 验证思考、参数、工具和正文之间播报节点保持身份、26.25px 状态行高稳定;原生滚轮上滚后不抢回阅读位置。完成、取消、HTTP 400 失败均清除播报;思考增量不写入历史。脚本 scripts/chat-activity-native-check.mjs,私有证据 .ygent/imports/ui-final-20261010/stream-final/。本轮也验证了问题选项键盘移动不提交、Enter 回传精确选项、回答重载/展开及授权拒绝/取消;不是 WorkBuddy 双端实时序列的全量 1:1 验收。