Files
ycode/docs/reference/ygent-chat-parity.md
T

12 KiB
Raw Blame History

Ygent ↔ WorkBuddy 对话区对标清单

对话区于2026-10-08按用户要求阶段收尾。最新阶段进度汇总已实现、证据边界及剩余工作;本文路线图中的历史状态不能替代当前实现和双端动态验收。

用户要求包含后续流式交互效果一致。当前优先处理 动态交互P0:正文分块、工具增量和取消/迟到事件。旧静态分析及下文路线图不能代替当前版本的双端动态验收。

最新原生验收依据:2026-10-08精确渲染差异清单。下文“已实现/可1:1”是路线图状态,不等于真实窗口验收通过;当前真实样本829条消息,不再适用“几十条消息”的规模假设。

状态:路线图与实现状态(2026-10-08) 依据:WorkBuddy lib-chat-ui 静态分析(2070 个 i18n 键 + 组件 props)、OMP 协议文档 口径:对标可见对话区及 Ygent 已有数据能支撑的交互;平台级分享服务、朗读和消耗体系不复制


结论先说

能做到接近 1:1,但「1:1」要分开看两层:

层 判断
渲染与交互层 待双端动态验收;需要前端与事件协议/持久化共同调整,当前数据缺reasoning、工具增量映射等,不能认定纯前端即可完成
能力语义层(消息编辑/回退/排队/压缩/分页) 🔧 OMP 已提供核心协议,Ygent 按交互逐项接入;编辑重发已接通
产品体系层(敏感保护/IM/插件/积分/媒体生成) ❌ 不对标,需要 WorkBuddy 那种平台规模

最重要的一个判断:高级对话交互并非不可对标,OMP 已提供多项底层能力,差别在 Ygent 是否完成接线与状态建模;本轮已接通消息编辑后的分支重发。


A. ✅ 可 1:1(纯渲染层,Ygent 数据已够)

能力 WorkBuddy 证据 Ygent 现状
对话顶栏与工作台 搜索、分享、最近任务、任务概览、右侧工作台 顶栏入口已实现;工作台正在按当前 WorkBuddy 的标签容器接入真实目录、文本预览和 Git 变更。内嵌浏览器、终端、富文档与来源区尚未完成,详见 工作台进度
Markdown 段落/列表/引用/表格 markdown.* ✅ 已有
表格悬浮「添加到对话」 .cr-message-quote-table-menu ✅ 悬停菜单按 116×38px 规格实现;点击后将原始 Markdown 放入输入草稿
代码块:语言标签 + 复制 markdown.copy/copied ✅ 本轮已做
图片渲染 — ✅ 已有
mermaid 流程图 mermaid.*(12 键) ✅ 已有按需渲染和源码回退
KaTeX 公式 markdown 域 ✅ 已有按需加载
交互式 widget show_widget / widget.* ⚠️ 已加入 sandbox iframe、尺寸上报、CDN 白名单与独立时间线段;1200×762 实窗核对后,卡片宽度与时间线一致,参照 SVG 的 iframe 仍有 5px 高差
代码 diff(改文件时) tool-diff 组件 ✅ write/edit 参数可展开查看
消息悬浮工具栏 message.* ⚠️ 用户气泡下方支持时间、复制、编辑;OMP/直连支持编辑后分支重发,Codex 仍只保留草稿
助手身份与回合完成耗时 .cr-agent__header / metaFold.turnCompletedWithDuration ✅ 导入参照会话按来源显示 WorkBuddy 名称与头像;普通会话显示 Ygent;含工具的已完成回合默认收起过程,可展开
全局字号 六档字号级别 / WorkBuddy 字号滑杆 ✅ 设置中提供 1–6 级离散滑杆;Markdown 根字号逐档匹配,常规控件偏移在第 5、6 档封顶为 +2px
消息状态:思考中 message.loading.thinking ✅ 本轮已做
消息状态:已中断 message.interrupted / userCancelled ⚠️ 有「已停止生成」,可对齐文案
消息状态:未发送 message.notSent / notSentFailed ⚠️ 同步接收失败时保留输入并回滚用户记录;已接收后的异步服务错误仍显示在时间线
消息时间 message.time.* ⚠️ 用户消息悬浮时显示时分;相对日期待做
空会话占位 message.empty ✅ 本轮已做
滚动到底部 action.scrollToBottom ✅ 自动跟随 + 手动回底按钮
加载更多(历史分页) message.loadingMore + get_messages_page ❌ 见 B 类
工具卡状态 + 回合折叠 metaFold.*(132 键) ✅ 连续工具组按正文/回合结束折叠;回合完成行可收起/展开过程;show_widget 独立保序
结构化错误 errorBanner.*(16 键) ⚠️ 有简易错误占位,可增强

B. 🔧 可对标 —— 高阶交互与接通状态

这一组是重点:OMP 协议提供基础能力,Ygent 正在逐项接入。

能力 OMP 命令(已存在) Ygent 要做的
编辑用户消息并重发 branch { entryId } ✅ OMP 持久 entryId + 独立子会话;直连按选中消息前的历史重放;Codex 暂不支持
回退到某条消息 fork { entryId } 仍待实现:任意历史点回退及分支切换
忙时消息排队 steer / follow_up / set_follow_up_mode 输入框在 pending 时允许发送并排队;队列 UI(messageQueue.* 11 键可参考)
队列项操作(编辑/删除/立即发送) remove_queued_message / promote_queued_message 队列条 UI
上下文压缩提示 compact / set_auto_compaction 对话内系统事件流(conversationEvent.contextCompaction.*)
历史分页(加载更多) get_messages_page(游标 + session_busy/stale_cursor) list_messages 改分页
模型切换提示 已有 set_model 对话内事件条(conversationEvent.modelChange.*)
权限能力清单(文件/互联网/终端三档确认) — Ygent 已有 grants / audit_log,扩展成能力清单即可

conversationEvent 这一组(12 键)揭示了一个 Ygent 完全没有的概念:对话内的「系统事件流」——压缩、历史更新、模型切换、会话边界都作为一类非消息事件渲染在时间线里。这是个值得单独设计的东西。


C. ❌ 不对标(Ygent 无对应能力 / 平台级)

能力 为什么不列
平台分享链接、朗读(TTS)、消耗/积分 Ygent 提供本地选择、复制和 Markdown 导出;不接 WorkBuddy 的外部分享服务与平台权益体系
IM 接入(im.* 159 键) WorkBuddy 是 IM 客户端,Ygent 不是
插件系统(plugins.* 109 键)、MCP(mcp.* 68 键) 平台规模能力
企业版标识、模型积分速度(model.badge.enterprise / credits.*) 商业化体系
敏感内容保护(sensitiveProtection.* 15 键) 需要凭据检测 + 出入站拦截,是平台级安全能力
媒体生成(mediaGeneration.* 11 键) Ygent 无此能力
计划编辑器的设计配置(planEditor.designConfig.*) 面向建站/设计场景,Ygent 无
沙箱相关(sandbox.* 35 键) Ygent 用项目工作目录做边界,模型不同

D. ⚠️ 不建议对标(Ygent 规模不需要)

能力 原因
虚拟列表 Ygent 消息量是「几十条」量级;已有块级 memo 缓存
widget 分组(presentationGroupId) widget 已独立渲染并保序;把解释正文与 widget 绑定成组仍待实现
mermaid 完整查看器(缩放/平移/明暗主题切换/下载 SVG·PNG) 先做「能渲染 + 失败回退代码」;查看器后置
队列上限/超时/升级提示(queue.banner.*) 商业化限流逻辑

建议的推进顺序

按「投入产出比」排(✅ = 已完成):

  1. ✅ 工具折叠与时间线保序 —— 普通工具折叠,widget 作为独立段保持原位
  2. ✅ mermaid + KaTeX —— 均按需动态加载
  3. ✅ 工具改动 diff(write/edit 卡)—— 使用工具帧 args
  4. ⚠️ 消息工具栏与 widget —— 编辑后分支重发已接;仍需真实窗口截图核对 widget
  5. ⚠️ 消息编辑 + 回退(接 branch/fork)—— 编辑重发已接;任意历史点回退与分支切换待做
  6. ⬜ 忙时排队(接 steer/follow_up)—— 内核已验证可用,但前端有前置依赖,见下
  7. ⬜ 对话内系统事件流(压缩 / 模型切换 / 会话边界)—— 需要新概念,建议单独设计

第 6 项的前置依赖(实测发现)

内核侧已经可用。探测结果:流式进行中再发一条

{ "id":"p2", "type":"prompt", "message":"再说一句:收到", "streamingBehavior":"followUp" }

→ success: true,随后收到 queue_update 帧,且第二条的 prompt_result.status = "completed"。

但前端不能只加一个参数就接。 OMP 把排队的 follow-up 视为同一次 run 的延续(在下一次 yield 时汇报), 而 Ygent 现在只有「一条用户消息 → 一个 agent 气泡」的模型,没有回合边界概念 —— 直接接会导致两条回答被合并进同一个气泡。

所以第 6 项的真实依赖是:先补回合边界处理(映射 OMP 的 agent_start / agent_end 事件来切分气泡), 再接 streamingBehavior,最后才是队列 UI(排队标记 / 编辑 / 立即发送)。 建议与第 7 项(系统事件流)一起做 —— 两者都需要「对话内事件」这条通道。

落地时的关键发现(实测)

工具帧里有大量此前被丢弃的信息。 探测 omp --mode rpc-ui 的原始帧:

// tool_execution_start —— 带完整参数与意图
{ "type":"tool_execution_start", "toolCallId":"call_…", "toolName":"write",
  "args": { "path":"note.txt", "content":"alpha\nbeta\ngamma\n" },
  "intent":"Creating requested note" }

// tool_execution_end —— 带显式失败标记(start 帧没有 args,end 帧没有 args)
{ "type":"tool_execution_end", "toolCallId":"call_…", "toolName":"write",
  "result": { "content":[…], "details": { "resolvedPath":"…" } }, "isError": false }

由此得到三条:

  1. args 可做代码 diff —— write 有 content(整份新增),edit 有 old_string/new_string
  2. isError 可准确区分成功/失败 —— 之前靠「result 是否为空」推断是错的(见 toolState 那次修复)
  3. intent 可作工具卡副标题 —— 模型自己说明这次调用要干什么

注意 args 只在 start 帧下发,end 帧没有 —— 前端必须记住并在落库时用回来(stores/chat.ts 的 toolCards map)。

mermaid 必须关掉 htmlLabels。 mermaid 默认用 <foreignObject> 承载节点文字,而消毒配置禁掉了 foreignObject(它能把 HTML 塞进 SVG 绕过 SVG profile),结果是「框画出来了但文字全丢」。设 htmlLabels: false(顶层 + flowchart + class)改用原生 SVG <text>,两全其美。

剩余纯渲染层的工作可继续推进;消息编辑已建立独立子会话与持久内核 entry 映射,任意历史回退仍需单独补充分支选择与恢复界面。


一句话

渲染层能 1:1;高级交互也能 1:1,因为 OMP 内核已经支持 branch/fork/steer/compact/get_messages_page,缺的是 Ygent 侧的接线;真正不能对标的是 WorkBuddy 的产品体系(IM、插件、MCP、积分、敏感保护、媒体生成)。