Repository navigation
Conversation
…bg_kill is aborted A terminal that settles while a bg_kill holds interest skips the automatic follow-up because that kill is expected to report it. If the kill is then interrupted (Esc while another id waits for SIGKILL), it reports nothing and the settled result was lost. Remember which settlements were suppressed for a kill report and, when an interrupted kill releases the last interest in them, hand them back to the normal delivery path. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
一次
bg_kill杀多个终端时,如果在等待过程中按了 Esc,已经结束的那些终端的结果会彻底丢失,模型永远不知道它们结束了。举个例子:
bg_kill(["fast", "slow"])。fast收到 SIGTERM 马上就退出了。slow忽略 SIGTERM,要等大约 2 秒后升级到 SIGKILL。bg_kill报Kill wait aborted; termination continues in the background.后退出。slow被 SIGKILL 杀掉,结果正常作为后续消息送达模型。fast的结果既不在bg_kill的返回里(工具已经抛错),也不会作为后续消息送达。模型以为
fast还在跑,比如以为 dev server 还开着,后面的判断就会跟着出错。原因在
extensions/background-terminals/src/manager.ts:kill()开始时,给要杀的终端加上 "kill interest"。终端在这期间结束时,settle()会把它标成consumed,意思是"这次 kill 会自己把结果返回给模型,不用再自动发一份"。index.ts的onSettled看到consumed就不再投递。ensuring只释放了 interest,没有把那些已经标成consumed的结果放回投递队列,它们就丢了。Value
后台终端是 OpenPI 的核心能力之一。AGENTS.md 要求 runtime 负责"唯一终态和结果投递",每个结束的终端都应该让模型确切知道一次。按 Esc 是最常见的操作,而多 id 的 kill 里只要有一个进程忽略 SIGTERM,就会打开这 2 秒的窗口。
Approach
Entry上加一个awaitingKillReport标记。settle()判定为consumed时设为 true,表示"自动投递被跳过,正在等某个 kill 返回它"。kill()成功拼好报告后,把自己负责的终端的标记清掉,表示结果已经交给调用方。kill()的ensuring里,如果这次 kill 没有成功返回(被中断或失败),在释放 interest 后,对每个仍然awaitingKillReport、并且已经没有别的 kill 持有 interest 的终端,按普通的非 consumed 方式再调一次onSettled,交回正常的自动投递流程。manager.ts,index.ts的投递逻辑没动,走的还是原来的 defer、合批、agent_settled那一套。Validation
基线是上游
f98d6a4。修复前后都跑了新加的回归测试:
index.test.ts:an aborted multi-id bg_kill still delivers the terminal that already settled,通过真实的bg_start、bg_kill、agent_settled走完整流程,检查发给模型的消息fast没有送达(10 秒超时)fast和slow各送达一次manager.test.ts:an aborted multi-id kill hands already-settled results back exactly oncefast只有一次consumed: true,没有交回slow正常结束manager.test.ts:an aborted kill does not redeliver results another kill returned(防止重复投递)写测试时注意到一点:
bg_status查到已结束的终端时,本来就会把这个结果算作"已经交给模型",所以测试里用bg_list轮询状态,不用bg_status。其他命令:
tests/extensions/background-terminals/全部:105/105 通过,连续跑了 3 次。bun run check:通过。bun run test,Node 部分:2461 个,2450 通过、9 跳过、2 失败。tests/extensions/plan-mode/result-rendering.test.ts里的a rich plan renders without throwing and keeps its content和expanded survives edge-content plans at extreme widths。bun run test,UI 部分:Node 部分失败后脚本没有继续,我用bun run test:ui单独补跑了。tests/web/下,是超时类用例,没改过的 main 上本地也会失败。这个 PR 没碰 web 代码。trap '' TERM和 POSIX 信号,在 Windows 上跳过。Impact
bg_kill被中止后,已经结束的终端会和其他后台结果一样,作为后续消息显示出来,不再悄悄消失。background-terminals/index.ts,但这个 PR 只改了src/manager.ts,没有重叠。🤖 Generated with Claude Code