关联主问题:#251
依赖:#260
类型
会话状态机 / 同步 / 用户接管 / Tab 所有权
背景
当前 inputSequence 只能让动作退化为 stale_target,Browser Runtime 依赖 tab.agentDispatching 布尔值区分输入来源。布尔窗口会漏掉 Agent 动作期间的真实用户输入,也没有形成可恢复的 PAUSED_BY_USER 状态。
锁定方案
- BrowserSession 使用单写者队列,变更型动作严格串行
- 每个动作执行后进行有界事件等待,监听导航、SPA/DOM 变化、新 Tab、dialog、download、crash
- 不使用可能被 websocket/长轮询拖死的全局 networkidle
- 使用操作级“预期输入账本”替换 agentDispatching 布尔值
- 未匹配预期账本的鼠标、键盘、滚动或导航视为用户输入
- 用户输入立即取消当前动作、清空队列并进入 PAUSED_BY_USER
- 只允许用户明确恢复;恢复后旧 ref/screenshot 全部失效并自动获取新快照
- 新 Tab 创建后不自动切换 agentActiveTabId;Agent 必须显式 switch_tab
- JavaScript dialog 进入 BLOCKED_BY_DIALOG,只允许显式 accept/dismiss
- 用户接管 Agent Tab 后转移所有权,不再自动关闭
动作结果
统一区分 action dispatched 与页面 effect,例如 navigation、dom_changed、new_tab_opened、dialog_opened、download_started、no_detectable_change。
验收标准
- 并行生成的工具调用不会并发落到页面
- 前一动作导航后,队列内旧页面动作不会继续执行
- 用户在 Agent 点击期间操作页面也能可靠触发接管
- Agent 自己的 CDP 输入不会误触发用户接管
- 新 Tab、对话框和下载不会造成后续工具超时或目标漂移
- 恢复后 Agent 必须基于新快照继续,不重放已取消动作
关联主问题:#251
依赖:#260
类型
会话状态机 / 同步 / 用户接管 / Tab 所有权
背景
当前 inputSequence 只能让动作退化为 stale_target,Browser Runtime 依赖 tab.agentDispatching 布尔值区分输入来源。布尔窗口会漏掉 Agent 动作期间的真实用户输入,也没有形成可恢复的 PAUSED_BY_USER 状态。
锁定方案
动作结果
统一区分 action dispatched 与页面 effect,例如 navigation、dom_changed、new_tab_opened、dialog_opened、download_started、no_detectable_change。
验收标准