Skip to content

fix(agent-runtime): bound trusted extension lifecycle waits - #788

Merged
vastsa merged 5 commits into
vastsa:mainfrom
hui455:fix/hooks-lifecycle-p0
Sep 22, 2026
Merged

vastsa merged 5 commits into
vastsa:mainfrom
hui455:fix/hooks-lifecycle-p0

Conversation

@hui455

@hui455 hui455 commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

问题与改动

可信扩展原先可能在 Stop 或销毁后继续运行:旧命令仍可弹窗、发送消息、发布工具进度,pi.exec 子进程也可能遗留到下一次操作。

本 PR 完成 #787 的有界生命周期等待,并补齐 #816 的副作用归属和取消清理。

改动

  • 模块加载、工厂初始化和每个事件 handler 各有 30 秒等待预算;销毁拒绝新派发、取消既有等待,并发调用只执行一次关闭。
  • 每个 handler、命令和扩展工具拥有独立操作范围;完成、超时、Stop 或销毁后,旧 SDK 调用和迟到工具进度不再生效。
  • pi.exec 管理其创建的进程组/进程树并在操作退役时清理;销毁等待已登记进程结束并保留清理错误诊断。
  • 结果型 hook 使用独立载荷,headers 只在处理器及时成功后提交;工具参数、已采纳进度及结果也与扩展持有对象分离,结束后的原地修改不能回写。
  • UI 请求按 session、extension 和 request ID 精确退役;显示中及排队弹窗都会清理。Main 先收到 Stop 时会立即退役当前命令,避免 sidecar abort 到达前继续弹出下一窗口。
  • waitForIdle、newSession、fork、sendUserMessage、模型及会话名操作传播取消;等待请求前 hook 时停止,不再请求模型,并保留用户消息供后续回合使用。
  • 新增内部事件能力清单,并同步 trusted extensions 规范、ADR、决策日志、中英文 E2E 场景及 unreleased。

兼容性与边界

通知、启动和关闭 handler 从无界等待改为每个 handler 30 秒预算。 模块加载与工厂初始化各有独立的 30 秒预算,handler 内等待 UI 回答也计入事件预算。

命令和工具不增加固定 30 秒期限,合法长任务可运行至完成、显式取消、Stop 或销毁。同步 JavaScript、直接 Node API、主动逃逸进程组不能被强制终止;已经进入 Host 的事务不能回滚,但取消后不会继续本地状态提交或队列优先级续接。

无数据库迁移、不新增权限,Native Pi 生命周期不在本 PR 范围。

验证

  • 最终 Runner 定向回归 24/24:覆盖长命令、长工具、工具取消和迟到进度、工具结果副本、上下文等待、headers 迟到修改、销毁及恢复。
  • Runtime lifecycle 5/5、真实父子进程清理 2/2、UI 请求身份与退役 1/1;最终 Agent Runtime typecheck 通过。
  • Main UI broker 与真实 Runner → UI request → Main 取消接线 18/18:覆盖 Main 先取消、旧弹窗响应失效、无后续弹窗/消息,以及新命令恢复。
  • Windows 上既有 build:js、Desktop typecheck、lint、docs:check、agent-policy、架构检查及 host-core build 通过;最后的小范围 Runtime 补充后只重跑受影响的定向测试与 typecheck。
  • 本地完整 Electron E2E 按一次运行约束实际为 37/39,不是通过。其中 [Follow-up] 可信扩展超时后的副作用清理及未覆盖执行路径 #816 暴露的 Stop 后下一弹窗竞态已由真实接线回归修复;另一项是驱动读取上一回合回复,已改为等待当前用户消息后的 assistant 持久化。最终完整套件未在本地重复运行,远端检查仍是合入门禁。
  • 未做 macOS/Linux 实机验证;最终候选没有可发布的前后截图。

Closes #787
Closes #816

Retire pending hook dispatches on cancellation and disposal so stale
results cannot continue a stopped turn. Bound startup and shutdown waits
and make concurrent shutdown idempotent.

Report deferred event registrations without disabling supported hooks,
and preserve existing result folding and fail-open behavior.

fixes vastsa#787
@vastsa

vastsa commented Sep 21, 2026

Copy link
Copy Markdown
Owner

pr 最近有点多,慢慢合,感谢时间!

@vastsa

vastsa commented Sep 21, 2026

Copy link
Copy Markdown
Owner

核查过了:问题真实,修法也是点对点的,但当前 head 不满足落地门禁。

根因确认(main):packages/agent-runtime/src/extensions/runner.ts:416(模块加载)/:430(工厂初始化)/:448(session_start)以及除 result 事件外的所有 handler 都没有等待预算(withTimeout 只在 :558 对 RESULT_EVENTS 生效);dispose() 在 :455 才置 disposed,关闭可被挂住且并发会跑两次;emit 只在 :556 入口判 disposed,在飞派发仍会返回结果并被 runtime.ts:7647 无条件采纳;runtime.ts:7601-7606 在 stop 后没有 runCancelled 检查,preflight hook 一解挂就发模型请求。本 PR 的 handler-lifecycle.ts 每代 AbortController + 30s 预算、dispose 记忆化、runtime 侧的 runCancelled/disposed 守卫都正好命中这些点。

落地阻塞:与最新 main 冲突(GitHub CONFLICTING)
git merge-tree 结果是 4 个纯文档冲突:docs/spec/06-delivery/04-e2e-test-plan.md、docs/spec/08-meta/decisions-log.md 及两份 zh-CN 对应文件(两侧都在同一处插表行、或在文件尾追加)。packages/agent-runtime 代码侧没有冲突标记(含双方都改的 runtime.ts)。请 rebase 到 origin/main 或合并 origin/main,保留两侧新增内容。

另请确认/跟进两点

  1. 通知类 handler 由无界变为 30s 是契约变更(spec 与决策日志已记录,这点我认可)。请在 PR 描述里显式标出来,避免下游扩展以为通知 handler 仍可长时间运行。
  2. 超时只是让等待失效,不能强杀进程内 handler:已挂起的子进程、原地改写的 payload、等待 UI 回答的请求都会残留;另外 runCommand handler、扩展工具 execute、命令上下文的 waitForIdle/newSession/fork/sendUserMessage 仍未纳入预算。若不在本 PR 范围,建议另开 issue 跟踪。

rebase 之后我做集成验证(typecheck + desktop 测试 + pnpm test:e2e:trusted-extensions)再合入。

Preserve the trusted-extension lifecycle fix and both sides of the E2E
and decision-log additions when integrating current main. This removes
the documentation conflicts blocking review without changing runtime
behavior.
hui455 and others added 3 commits September 22, 2026 14:19
Preserve the existing lifecycle fix while integrating current main. Own
cancellation of SDK subprocesses, prompts, tool payloads, and late
continuations without imposing an event deadline on legitimate long tasks.

Refs vastsa#816
Refresh the existing PR candidate with current main while preserving both
delivery-document additions.

Refs vastsa#816
@vastsa
vastsa merged commit 05752ca into vastsa:main Sep 22, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants