diff --git a/docs/agent-evaluation.md b/docs/agent-evaluation.md index a2fd83855..3b341b5f3 100644 --- a/docs/agent-evaluation.md +++ b/docs/agent-evaluation.md @@ -104,6 +104,8 @@ uv run --locked --no-sync python -m scripts.evaluation --live \ WebAgent 的排队消息已补齐稳定留存和真实时序展示:后端展示快照和 `AgentChatMessage` 记录 `steering_message_id`,前端把 queued 消息写入本地会话、把 snake_case 字段同步到服务端,并在断流、刷新或服务端快照替换时合并保留;迟到的 applied 事件会按稳定 ID 更新同一条用户气泡。应用点会收口前一段助手、把用户消息插入其后并创建 continuation 助手,后续文本和工具事件按真实事件流进入 continuation。工具事件携带稳定 `tool_id` 与 `running/done/error` 状态,前端可区分真正执行中的工具和已完成/失败的工具,不再把所有提示显示为“最新一条执行中”。追加验证发现 continuation 助手插入后若把原始对象直接存入 steering 映射,后续工具状态会写入但不会触发 Vue 重渲染;前端提交 `44e19778b70fd17bc0a7ddf63021866ef45bdaa5` 改为从响应式消息数组取回 continuation,并增加“工具 1 完成 → 插入用户消息 → 工具 2 running”的时序回归。本轮后端相关测试 162 项、前端 `AgentAssistantPanel.spec.ts` 42 项、`vue-tsc --noEmit`、格式和 ESLint 通过,远端 `Frontend Tests` run [34596734349](https://github.com/jxxghp/MoviePilot-Frontend/actions/runs/34596734349) 成功。 +前端后续修复把未收到稳定 `steering_message_id` 的本地草稿改为有序集合,并在 queued ACK 阶段直接插入当前助手段之后的真实边界;应用事件只负责收口旧助手、创建 continuation 和绑定稳定 ID。这样主流事件、短 ACK、断流恢复或多个补充消息交错时,用户消息从首次显示开始就保持工具调用之间的顺序,不会先落在列表末尾再跳到顶部,也不会因单一草稿引用被覆盖。新增回归覆盖两个 ACK 断流后按提交顺序应用的补充消息;前端 `AgentAssistantPanel.spec.ts` 现为 43 项,类型检查、格式和 ESLint 均通过。 + 因此当前真实 Gemini 结果证明了工具合同读取和未知结果诚实边界已经能被实测,但不能宣称达到 Codex 的整体智能水平。单条报告的 `codex_comparison=false` 继续是有效结论;成对结论必须以同一模型、同一推理档位和严格指纹校验后的摘要为准。 ### `thought_signature` 与真实 MoviePilot Agent diff --git a/docs/refactor/agent-codex-parity-plan.md b/docs/refactor/agent-codex-parity-plan.md index c3ccf0efd..636256304 100644 --- a/docs/refactor/agent-codex-parity-plan.md +++ b/docs/refactor/agent-codex-parity-plan.md @@ -18,7 +18,7 @@ Google 的 OpenAI-compatible 层会丢失 Gemini 3 工具回复中的 `thought_s | 目标 | 状态 | 验收重点 | | --- | --- | --- | -| C1.4 终端工具完整闭环 | 生产与原生 pipe/PTY 配对已验证 | `run/pipe/PTY` 共用 shell、cwd、login 和 UTF-8 策略;stdin 写入、EOF、分页、interrupt/kill、超时和进程组收尾有真实进程测试。原生终端场景经由 app-server 采集 `outputDelta`/`terminalInteraction`,并按评测预算保留足够的流式空闲时间;pipe/PTY 配对均已观察输入、输出和退出码 | +| C1.4 终端工具完整闭环 | PTY 已配对;原生 pipe stdin 仍受边界阻塞 | `run/pipe/PTY` 共用 shell、cwd、login 和 UTF-8 策略;stdin 写入、EOF、分页、interrupt/kill、超时和进程组收尾有真实进程测试。原生终端场景经由 app-server 采集 `outputDelta`/`terminalInteraction`,并按评测预算保留足够的流式空闲时间;PTY 配对已观察输入、输出和退出码,pipe 配对仍保留原生 CLI 关闭 stdin、未产生 `terminalInteraction` 的失败证据 | | C1.3 终端任务作用域 | 已完成 | 终端归属由宿主对象身份决定;定时运行、会话、子任务和内部工具管理器隔离;封口先于清理,排队或运行中的命令都不会在任务结束后迟到启动 | | S2.3 运行中消息排队与 WebAgent 输入 | 已完成本轮实现并修复丢消息、时序错位和 continuation 状态不刷新的遗漏 | 运行中仍可提交新消息;消息按会话原子入队,在下一次模型调用边界注入真实 `HumanMessage`;SSE 报告 queued/applied,稳定 `steering_message_id` 贯穿展示快照、前端本地状态和恢复合并;应用点收口当前助手并创建 continuation 助手,用户气泡落在真实事件边界;工具按 `tool_id` 报告 running/done/error;停止后不再派发后续工具 | | C1.5 长上下文压缩与任务约束保留 | 同条件配对已通过 | 真实压缩前后预算约 69.5K → 26.1K;保留首条用户任务、工具尾部和 provider 序列化安全余量;MoviePilot 与原生 Codex 均完成 6 页读取并通过独立 oracle | @@ -50,7 +50,7 @@ uv run --locked --no-sync python -m scripts.evaluation \ ## 工具与 Harness 对齐清单 -- **命令行**:普通一次性命令与后台终端分别支持 pipe/PTY、共享 cwd/shell/login/环境和 UTF-8;输入写入、空写入、EOF、分页、短写、interrupt、kill、超时、取消和进程组收尾都有结构化终态。`command_execution` 与终端场景只在原生 CLI 真实广告 `functions.exec_command`/`functions.write_stdin` 时按场景开启,并把 MoviePilot 生产 `ExecuteCommandTool` 绑定到临时目录;终端场景的原生评测使用 app-server,记录命令输出增量和终端输入事件。生产与原生 pipe/PTY 都已通过同条件真实配对;适配器将单请求、代理和 app-server 流式空闲时间统一跟随评测墙钟预算,避免较长推理被 Harness 的硬编码超时误判。 +- **命令行**:普通一次性命令与后台终端分别支持 pipe/PTY、共享 cwd/shell/login/环境和 UTF-8;输入写入、空写入、EOF、分页、短写、interrupt、kill、超时、取消和进程组收尾都有结构化终态。`command_execution` 与终端场景只在原生 CLI 真实广告 `functions.exec_command`/`functions.write_stdin` 时按场景开启,并把 MoviePilot 生产 `ExecuteCommandTool` 绑定到临时目录;终端场景的原生评测使用 app-server,记录命令输出增量和终端输入事件。生产与原生 PTY 已通过同条件真实配对;原生 pipe 仍因 CLI 在一次性命令后关闭 stdin 而没有输入事件,保持 blocked,不把适配器能力误算成原生 Harness 对齐。适配器将单请求、代理和 app-server 流式空闲时间统一跟随评测墙钟预算,避免较长推理被 Harness 的硬编码超时误判。 - **浏览器**:工具目录必须明确导航、读取、交互、等待和截图的动作与权限;浏览器会话、页面状态和失败重试由宿主持有,不能由模型字符串冒领。新增 `browser_navigation` 场景使用回环动态页面验证生产工具;原生 CLI 探针没有广告浏览器工具,原生配对保持 blocked,等待可用的 Codex browser harness。 - **子代理**:主 Agent 自动选择通用子代理;专用画像只有在 held-out 任务上证明提高成功率、减少调用或降低副作用风险时才保留。子代理不能自行发送消息、执行高影响写操作或继承兄弟任务句柄。 - **API Skill 与合同读取**:`skills/moviepilot-api/SKILL.md` 只负责路由索引和工作流;`api/*.md` 各自包含完整操作合同及该类别需要的 Body Models,不再依赖单独的 `api/models.md`。真实 Agent 先用 `read_skill` 得到 supporting-file 清单,再用同一个工具的 `file=api/.md` 参数按需读取类别文档;评测目录必须提供同一条链路,不能只返回文件名而不给模型读取能力。operation 输入错误还要返回该 operation 的允许字段、必填字段和类型约束,帮助模型纠正后重试。 @@ -81,5 +81,6 @@ uv run --locked --no-sync python -m scripts.evaluation \ - WebAgent 中途输入补充了真实 HTTP 流时序回归 `test_web_agent_stream_queues_mid_run_input_into_the_same_assistant_stream`:首条流保持运行时,第二条请求收到 queued ACK,消息在同一会话的下一模型回合以 steering applied 进入原流;应用点会收口前一段助手、插入用户消息并创建 continuation 助手,后续文本和工具事件进入 continuation。该回归验证了宿主排队和展示边界;真实模型长任务配对仍待补跑。 - 本轮 WebAgent 留存与工具状态修复了两类真实时序:后端展示快照和 `AgentChatMessage` 记录 `steering_message_id`,前端持久化 queued 消息并在服务端恢复快照、刷新和 ACK 断流时合并保留,迟到 applied 事件更新同一条用户气泡;工具事件携带稳定 `tool_id` 与 `running/done/error` 状态,前端不再用最后一条提示覆盖之前的完成态。后端相关测试 162 项和前端 `AgentAssistantPanel.spec.ts` 41 项通过,`vue-tsc --noEmit` 通过。 - 追加验证发现 continuation 助手插入后若把原始对象直接存入 steering 映射,后续工具状态会写入但不会触发 Vue 重渲染;前端提交 `44e19778b70fd17bc0a7ddf63021866ef45bdaa5` 改为从响应式消息数组取回 continuation,并增加“工具 1 完成 → 插入用户消息 → 工具 2 running”的时序回归。前端 `AgentAssistantPanel.spec.ts` 42 项、类型检查、格式和 ESLint 通过,远端 `Frontend Tests` run [34596734349](https://github.com/jxxghp/MoviePilot-Frontend/actions/runs/34596734349) 成功。 +- 前端继续修复追加消息的显示锚点:未收到稳定 `steering_message_id` 的草稿改为有序集合,queued ACK 阶段直接插入当前助手段之后,并在 applied 阶段只切分助手段和绑定 ID;多个 ACK 断流后再按顺序应用时,消息仍保持工具调用之间的真实顺序。新增回归覆盖两个断流草稿的顺序与重复收口,前端 `AgentAssistantPanel.spec.ts` 43 项、类型检查、格式和 ESLint 通过。 - 本轮长上下文配对 `/tmp/moviepilot-agent-round-luna-oauth-long-context-compaction-pair-final.json` 使用同一 `gpt-5.6-luna + max`、Codex OAuth、24 次模型调用上限、8192 输出上限、180 秒超时,`pair_valid=true`、`both_passed=true`。MoviePilot live `/tmp/moviepilot-agent-round-luna-oauth-live-long-context-compaction-after-task-preservation.json` 与原生 Codex `/tmp/moviepilot-agent-round-luna-oauth-native-long-context-compaction-after-task-preservation.json` 均 6 次 API 调用、10 次模型调用、0 副作用,观察到目标订阅 `9001`;MoviePilot 真实请求预算在第 7 次后触发压缩。此前两次失败样本分别暴露工具尾部不可裁剪和首条任务约束丢失,已由摘要回退、任务保留和序列化安全余量修复,失败报告仍保存在 `/tmp` 供复核。 - 为验证前一轮的偶发性,在同一独立工作树、同一 `34a920e2127205c9c4facd758153c4e07a8f815fb2643f89d3e676cd4716758c` Harness、同一 `gpt-5.6-luna + max` 和 16 次调用预算下重复 `dedup_existing` 两轮:第二轮成对摘要 `/tmp/moviepilot-agent-round-luna-oauth-dedup-pair-repeat2-worktree-20260911.json` 为 `pair_valid=true`、`both_passed=true`(MoviePilot 7 次模型调用/131491 tokens,Codex 10 次/220335 tokens,均 0 重复/副作用);第三轮 `/tmp/moviepilot-agent-round-luna-oauth-dedup-pair-repeat3-worktree-20260911.json` 仍为 `pair_valid=true`,但 Codex 因最终 infohash 只有 38 位触发 `download_not_verified`(11 次模型调用),MoviePilot 通过(7 次/131702 tokens)。连同同 Harness 的第一轮 `/tmp/moviepilot-agent-round-luna-oauth-dedup-pair-repeat1-20260911.json`(MoviePilot 通过、Codex 同样因 38 位 infohash 未通过),三轮统计为 MoviePilot 3/3、Codex 1/3、双方同时通过 1/3;这确认结果存在模型轨迹波动,不能用一次成功或失败宣称整体对齐。一次误在其他 checkout 生成的原生报告因 Harness SHA 为 `eee4b6ad...` 被 `--compare` 拒绝,证明配对指纹控制有效。