Files

166 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SOP:Ygent 真实桌面 WebView2 调试与渲染采集
## 隔离动态链路验收
调试构建支持 `scripts/ygent-debug.ps1 -ReuseFrontend -Port 9336 -DataDirectory <绝对路径>`。
独立SQLite和托管项目目录位于该目录;进程变量为YGENT_DEBUG_DATA_DIR,脚本退出恢复原环境,发布构建忽略该变量。安装实例正在执行任务时,可用 `-ReuseFrontend`、独立数据目录与空闲端口并行启动调试实例,不能停止安装实例或共享其数据目录。脚本拒绝重复调试实例与正常数据目录;完成后只关闭本次测试 PID 和测试服务,不用测试库覆盖正常库。
可用本机受控SSE验证真实Rust/Tauri IPC/WebView2并记录DOM时间线。该响应属于测试数据,结果仅表示YG端到端通过,不能称为WB或真实模型对照通过。序列见[动态清单](ygent-chat-interaction-parity.md)。
开发句柄window.__yg包含真实chat/session/settings/channel store和flushChatWrites。隔离测试使用同一运行时句柄;Vite HMR带时间戳模块与不带时间戳的动态import可能产生第二套store,不能误当当前UI。普通采集仍只读,不调用send/abort或修改设置。
辅助回归:`pnpm check:chat`;后端:`cargo test --lib --manifest-path src-tauri/Cargo.toml`。不代替原生验收。
### 原生普通回合的刷新恢复
1. 用真实 `agent_live` 读取普通与协作运行,包括启动预留、冻结模型和原用户消息;`collaboration_live`只覆盖协作,空数组不代表所有工作停止。
2. 只读采集运行requestId、会话、最后持久消息ID与DOM。页面刷新后核对同一requestId、原正文前缀、工具详情及pending授权身份,等待真实新增量;刷新不是重新发送。
3. `agent_replay`返回有序快照及水位,思考活动不进入持久历史。宿主在页面不在场时继续保存正文/工具,页面以hostRunId和稳定块键对齐持久行,不重复写入。
4. 完成/取消后核对真实终态、消息不重复、工具消息ID及展开作用域保持;停止准确绑定requestId。程序退出再启动仅标中断,不能把刷新重接理解为自动重放副作用。
5. 实际员工“继续”同时核对team_user_continuations、原team_dispatches/messageId与当前runId、当前合同版本及经理结果路由;不要用普通手动回合绕过派发。测试不得给正在执行的正常库注入事件或直接SQL改状态。
适用环境:Windows、Tauri 2、WebView2、Node 22+。默认 CDP 端口 9335,前端端口 1420。
本流程连接真实桌面窗口,使用真实 Rust IPC 和数据库,不依赖 computer-use、模拟 IPC 或 fixture。
已于 2026-10-08 在本机验证:WebView2 154.0.4258.62、CDP 9335 回环监听、视口 1335×916、DPR 1;恢复真实会话 5 的 829 条消息,并成功生成 DOM/样式 JSON 与原生截图。Rust `cargo build --no-default-features` 通过。
## 1. 启动前检查
在项目根目录执行。常规同数据调试需保存输入框草稿并退出旧 Ygent;安装实例正在工作时,改用上方独立数据目录方式,禁止为验收停止它。
旧实例启动后不能补开调试端口;如果由 `pnpm tauri dev` 启动,也结束旧开发终端中的命令。
```powershell
Get-Process ygent -ErrorAction SilentlyContinue
Get-NetTCPConnection -LocalPort 9335 -State Listen -ErrorAction SilentlyContinue
```
启动脚本遇到旧实例或占用端口会报错,不会自动结束其他进程。
## 2. 调试模式运行
常规开发(编译 Rust、启动 Vite、打开桌面窗口,终端保持运行):
```powershell
pnpm debug:desktop
# 或指定其他空闲端口
powershell -NoProfile -ExecutionPolicy Bypass -File scripts/ygent-debug.ps1 -Port 9336
```
如果 localhost:1420 的 Vite 已经运行且已有最新调试版可执行文件:
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File scripts/ygent-debug.ps1 -ReuseFrontend
```
复用模式不会重新编译 Rust;修改 Rust 后先 `cargo build --manifest-path src-tauri/Cargo.toml`,再启动隔离实例,或在无运行任务时使用常规开发模式。
脚本仅对启动子进程设置 `YGENT_DEBUG_PORT=9335`,随后恢复当前终端原值,不使用 setx 或注册表。
Windows debug 构建读取此变量,通过 Tauri 的 `additional_browser_args` 传入 `--remote-debugging-port`,保留默认浏览器参数;release 构建不启用此入口。
本机实测仅设置 `WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS` 未开放端口,不能把环境变量设置成功视为已连通。
机制参考:[Tauri 参数接口](https://docs.rs/tauri/latest/tauri/webview/struct.WebviewWindowBuilder.html#method.additional_browser_args)、[Microsoft WebView2 调试说明](https://learn.microsoft.com/en-us/microsoft-edge/webview2/how-to/debug-visual-studio-code)。
## 3. 确认连接的是原生窗口
```powershell
Invoke-RestMethod http://127.0.0.1:9335/json/version | Select-Object Browser, 'Protocol-Version'
Invoke-RestMethod http://127.0.0.1:9335/json/list | Select-Object id, title, type
Get-NetTCPConnection -LocalPort 9335 -State Listen | Select-Object LocalAddress, OwningProcess
```
验收条件:端口仅回环监听,目标为 localhost:1420 的 page,页面同时具有 `window.__TAURI_INTERNALS__` 和开发调试句柄 `window.__yg`。
仅有 localhost URL 不足以证明是原生窗口;采集脚本会检查两项句柄,不符合时拒绝采集。
9334 的独立 Edge 参照页面与此原生端口不同,不能混用验收结果。
## 4. 采集真实渲染
打开待验收会话,设置对应字号,定位到目标消息,展开待比对的过程行,等内容稳定后执行:
```powershell
$ygSopCapture = Join-Path $env:USERPROFILE ('.ygent\imports\ygent-debug-' + (Get-Date -Format 'yyyyMMdd-HHmmss-fff'))
node scripts/ygent-cdp.mjs "$ygSopCapture" 9335
$ygSopSnapshot = Get-Content (Join-Path $ygSopCapture 'dom-styles.json') -Raw -Encoding utf8 | ConvertFrom-Json
$ygSopSnapshot.viewport
$ygSopSnapshot.state
$ygSopSnapshot.samples | Where-Object selector -eq '.thread-content' | ConvertTo-Json -Depth 8
```
输出 `connected: true`、`runtime: native-tauri-webview2`,保存:
| 文件 | 内容 |
| --- | --- |
| dom-styles.json | DOM/HTML、最终计算样式、元素矩形、滚动尺寸、视口/DPR、活动会话与消息数量摘要 |
| ygent.png | 真实 WebView 当前视口截图 |
采集不读取 cookies、存储、密钥或完整 store,不改动页面状态。正文和截图仍包含真实会话,应保存在上述私有目录。
DOM 与截图先后采集,不是原子快照;流式生成期间需注明时间差。
## 5. 深入调试与对标
可在 Edge 的 `edge://inspect` 配置 `localhost:9335`,选择 Ygent page 的 inspect,使用 Elements、Computed、Console、Sources、Network。
Console 中只读查询示例:
```javascript
getComputedStyle(document.querySelector('.thread-content')).maxWidth
document.querySelector('.thread-content').getBoundingClientRect().toJSON()
window.__yg.useSessionStore.getState().activeId
window.__yg.useChatStore.getState().messages.length
```
读取不存在的元素前先检查选择器命中情况;新建任务页面可能没有对话节点。
对标 WorkBuddy 参照 [WorkBuddy CDP SOP](workbuddy-cdp.md)。记录同一会话、字号档位、窗口/视口、DPR、滚动位置及展开状态,先比较结构和计算样式,再检查截图。
不使用 Emulation 修改原生视口来代替真实窗口尺寸,不把模拟 IPC 的页面当作原生验收。
## 6. 退出调试与排错
- 退出 Ygent,再用 `pnpm tauri dev` 普通启动即可关闭本次 CDP。若终端外部本来设置了 `YGENT_DEBUG_PORT`,先移除该变量。
- 端口不响应:检查是否启动了旧实例、WebView2 是否继承启动参数、可执行文件是否存在;不要仅重启 Vite。
- 无目标:确认 Vite 1420 和原生窗口均已加载;本采集脚本针对开发页面,不针对安装版 tauri.localhost。
- 缺少 `__yg`:确认是 Vite 开发版;缺少 Tauri 句柄:确认没有连到独立浏览器。
- 采集无对话节点:先在真实窗口打开目标任务,再采集,不注入数据掩盖问题。
## 7. 对话路径 → 右侧工作台(2026-10-10)
- 对话正文中已识别的目录/文件路径默认在右侧工作台打开,支持点击、Enter 和空格;目录直接定位,文件复用已有标签(统一 Windows 路径分隔符)。收起后再次点击会重新展开。
- 目录浏览、文本与 Markdown 预览沿用当前对话实际工作目录边界,不因项目导航切换扩大范围。目录外路径显示读取拒绝;二进制文件显示不支持文本预览;均不自动调用系统应用。工作台“系统打开”是显式外部入口,目录标签打开当前浏览目录。
- 会话切换清除待打开路径,工作台标签仍按会话挂载隔离,不向新会话重放上个会话的请求。未新增图片/PDF/Office 预览;文本仍限制前 1 MB。
- 本机真实 Tauri WebView2、CDP 9336、视口 1335×916、DPR 1 验证通过:目录定位、两级返回到根目录、JSON 实际内容、重复点击及目录条目/正文路径共用文件标签、Markdown 渲染/源码、Enter/空格、收起重开、外部目录/文件拒绝、二进制预览错误、错误后恢复和跨会话隔离。采集了实际 DOM、计算样式及矩形:工作台 x=809.015625、y=46、宽=525.984375、高=870,display=flex。
- 验收使用独立测试数据库,通过真实宿主 IPC 持久化受控路径消息,再操作真实 DOM;没有模拟/替换 IPC,没有验证真实模型流式输出。截图保存在用户私有目录 `~/.ygent/path-workbench-smoke.png`。未改动已安装客户端,未进行 Mac/Linux 验收,未触发系统打开按钮。
- 类型检查 `node node_modules/typescript/bin/tsc --noEmit` 和 `node node_modules/vite/bin/vite.js build` 通过;构建仍提示大 chunk。本机 pnpm 入口遇到 esbuild 构建脚本审批错误,因此直接执行已安装的本地工具,未调整依赖审批设置。
- 同时运行已安装客户端时,独立调试窗口首次启动出现 WebView2 HRESULT 0x8007139F;为调试子进程临时指定独立 `WEBVIEW2_USER_DATA_FOLDER` 后成功,不修改系统环境变量或发布配置。
## 并行隔离验收的 WebView2 配置(2026-10-10)
调试构建同时设置 `YGENT_DEBUG_PORT` 与绝对路径 `YGENT_DEBUG_DATA_DIR` 时,主界面 WebView2 使用该数据目录下的 `debug-main-webview`。子浏览器仍按项目/对话使用原有独立 profile;发布构建不启用这个分支。
不要用 `WEBVIEW2_USER_DATA_FOLDER` 隔离含内置浏览器的整进程:它会覆盖子 WebView 的目录,主界面与浏览器使用不同启动参数时,WebView2 可能报 `0x8007139F`。本轮已在真实子视图创建时复现。仅修改当前启动命令的环境,不永久设置系统变量。
需要与用户运行窗口并行验收时,使用独立数据目录和未占用端口;回归脚本先校验 `activity_test_mode=native-isolated`。窗口尺寸以实际 DOM 为准;Win32 缩放/恢复前校验窗口 PID、标题和句柄,只操作验收进程。测试结束关闭自身标签、回环服务和进程,保留用户窗口。
## 编译缓存与磁盘占用
开发与测试共用 `Cargo.toml` 的 dev 配置:`debug = 1`、`incremental = false`,第三方依赖 `debug = 0`。保留 Ygent 自身回溯的文件/行号,不保留完整变量调试信息;需要调试第三方 Rust 依赖时临时启用其符号。WebView2 的 CDP、DOM 与流式调试不受影响。release 配置独立。
关闭增量缓存以减少长期磁盘占用,代价是 Rust 代码重编译更慢;依赖编译产物仍由 Cargo 复用。切换 profile 设置后的首次编译会重建受影响的依赖,不代表每次都全量编译。
旧缓存不会随配置变更自动删除。无 cargo/rustc 构建进程时,可清理 `src-tauri/target/debug/` 下的 `incremental`、`deps`、`build`、`.fingerprint`;这些是可重建的中间文件。保留顶部可执行文件、运行资源、sidecar 和 release 分发产物。清理后首次开发编译和测试须重建依赖。若运行中或正在构建,先停止对应任务再清理,不能一边编译一边删除。
## 长历史对话打开卡顿(2026-10-13)
用户反馈从团队打开成员执行对话时整个页面短暂无响应。真实正常库的Rust成员对话约2,000条消息、正文/工具/参数合计约600万字符。通过9335的真实WebView2连接,在执行同一 `openSession` → `showView('chat')` 路径前开启CDP `Profiler.enable/start`,打开后等待首轮渲染,再 `Profiler.stop` 保存CPU profile;同时使用 `PerformanceObserver` 记录 `longtask`。这些探针仅导航、读取和测量,不发送模型消息、替换IPC或注入消息数据。
诊断必须分别记录会话/消息IPC等待、历史合并、Markdown解析、首次布局及滚动恢复,不能把Promise等待当成JavaScript计算。此次既捕捉到首次Markdown/布局的长任务,也出现过打开等待22秒而渲染线程主要空闲的情况。相关同步IPC在原生窗口线程取数据库锁和读取,不适合继续放在UI线程;具体22秒内的持锁方未捕获,不能宣称已经定位到某个后台工具。
实现:
- `HistoryTurn` 仅在历史接近滚动视口时首次挂载正式 `TurnBlock`,挂载后持续保留,滚动离开不重置手动展开。当前生成、未处理问题/授权、搜索、分享和明确定位的历史立即挂载。原始消息仍完整保留,历史不截断、不按会话特殊处理。
- 共用Markdown高亮转换器的语言登记,避免每个段落重复注册全部语言;正文、代码、公式及工具仍使用原组件。已显现历史通过content-visibility跳过离屏布局和绘制。
- 真实消息行按ID/运行建立索引,合并活跃协作和历史不逐消息扫描整个历史。恢复滚动保存消息锚点及相对偏移,历史挂载改变高度时按真实跟随状态处理,用户上滚不会被强行拉回底部。
- 会话/消息读取、团队成员/工作台、协作列表及任务实际运行查询改用 `spawn_blocking`;保持原数据库、项目/运行身份和返回内容,读库等待不占原生窗口线程。运行标记包含真实恢复派发,不能由持久in_progress推断。
验证:TypeScript、Vite构建、聊天增量/渲染/工具摘要回归通过;新增长历史索引、历史可见性切换及工具展开保留、共享高亮跨块不串内容检查通过。运行标记Rust3项、团队恢复9项通过,调试版 `cargo rustc --bin ygent -- -C extra-filename=-chat-read` 编译通过;没有重复旧全量LSP测试来替代员工当前整改验收。
真实1335×916、DPR1下,前一阶段首次打开长任务524ms;按需挂载后同路径长任务60ms、DOM节点约4,848→1,016。滚动历史后重入的锚点偏差0.125px,回到底部间距0;原生复测中没有异常。该原生脚本选中的历史段未包含可展开工具,工具手动展开保留由组件回归证明,不能据空结果宣称原生工具验收通过。最初1.5–1.7秒采样发生在144×19的最小化视口,与正常窗口数据分别保留,不直接作同尺寸提速比例。
前端更新已在现有开发窗口生效。Rust修复已编译,当前PID1964仍为旧调试内核,未重启/替换、未部署安装目录;异步IPC和运行标记需切换新构建后原生复验。用户当前工作及主动取消不因性能修复重新派发。CPU profile、原生DOM/时间和检查日志只保存于私有 `~/.ygent/imports/employee-chat-*`,不提交会话内容。