Skip to content

fix(daemon): recycle unresponsive agent runtimes - #11275

Merged
yiliang114 merged 3 commits into
codex/issue-8586-runtime-generationsfrom
codex/issue-8586-unresponsive-agent
Sep 7, 2026
Merged

fix(daemon): recycle unresponsive agent runtimes#11275
yiliang114 merged 3 commits into
codex/issue-8586-runtime-generationsfrom
codex/issue-8586-unresponsive-agent

Conversation

@yiliang114

Copy link
Copy Markdown
Collaborator

What this PR does

This is the final stacked layer for #8586. After the existing background-Agent progress watchdog aborts a stalled run, it gives the Agent a fixed five-second cooperative exit window. If the run still does not settle, the registry records one failed terminal state while retaining its physical concurrency slot, persists and displays the terminal notification without starting another model turn, and asks the daemon to recycle the Session's exact owner runtime. Any late settlement may release the physical slot but cannot overwrite the failed terminal state.

The recycle request uses the existing runtime-generation lifecycle introduced by #11273. It is accepted only from the child that owns the Session and never falls back to the primary or currently active runtime.

Why it's needed

The logical watchdog in #11270 can abort an Agent, but an underlying provider or tool may ignore cancellation. In that case the Agent can continue occupying a concurrency slot indefinitely and keep the old runtime unhealthy. Starting the ordinary completion-notification turn on that same runtime would add more work to a process that is about to be retired.

This layer closes that gap: the user-visible task becomes terminal once, the terminal record remains durable, and the unhealthy owner generation drains while a replacement generation accepts new work.

Reviewer Test Plan

How to verify

Start a background Agent whose provider or tool does not settle after its watchdog abort. Confirm that the task changes to failed after the cooperative exit window, exactly one terminal notification is recorded and displayed, no automatic model turn is started for that notification, the Session's owner generation becomes draining, and a fresh generation accepts new Sessions. Then let the old Agent settle late and confirm that it releases its physical slot without changing the failed sidecar or emitting a second notification.

Also confirm that a forged recycle request for an unknown or non-owned Session is rejected, and that the daemon never creates more than two OS-live runtime generations while the old one drains.

Evidence (Before & After)

Before: an abort-ignoring Agent remains logically/physically stuck and its runtime is not recycled.

After: the Agent is finalized once, its notification is persisted without a new model turn, and only its owner runtime is drained and replaced.

Tested on

OS Status
🍏 macOS ⚠️
🪟 Windows N/A
🐧 Linux N/A

Environment (optional)

No local test, build, typecheck, or CI command was run. Static review and git diff --check only, following the requested local workflow constraint.

Risk & Scope

Linked Issues

Completes the implementation stack for #8586 after #11273 merges. This PR intentionally does not auto-close the umbrella issue while its dependency stack is still open.

中文说明

本 PR 做了什么

这是 #8586 的最后一个堆叠层。现有后台 Agent 进度看门狗中止停滞任务后,会给 Agent 固定五秒的协作退出窗口。如果任务仍未结束,注册表会记录一次 failed 终态,同时保留它实际占用的并发槽;终态通知只落盘并展示,不启动新的模型 turn;随后请求 daemon 回收该 Session 精确所属的 runtime。迟到的任务结束只能释放物理槽,不能覆盖已经写入的 failed 终态。

回收请求复用 #11273 引入的 runtime generation 生命周期。只有实际拥有该 Session 的子进程才能发起请求,并且绝不会回退到 primary runtime 或当前 active runtime。

为什么需要

#11270 的逻辑看门狗可以中止 Agent,但底层 provider 或工具可能忽略取消。在这种情况下,Agent 会无限占用并发槽,并让旧 runtime 一直处于不健康状态。若仍在同一个 runtime 上启动普通的完成通知 turn,只会给即将被回收的进程增加更多工作。

这一层补上了该缺口:用户看到的任务只终结一次,终态记录保持持久化,不健康的 owner generation 进入 draining,同时新的 generation 接受新工作。

Reviewer 验证计划

如何验证

启动一个在看门狗中止后仍不结束的后台 Agent。确认协作退出窗口结束后任务变为 failed,只记录并展示一条终态通知,不为该通知启动自动模型 turn;该 Session 所属的 owner generation 进入 draining,新 generation 可以接受新 Session。随后让旧 Agent 迟到结束,确认它只释放物理并发槽,不改变 failed sidecar,也不发送第二条通知。

同时确认伪造的未知 Session 或非本进程所有 Session 的回收请求会被拒绝,并且旧 generation draining 期间 daemon 的 OS-live runtime generation 始终不超过两个。

证据(Before & After)

Before:忽略 abort 的 Agent 在逻辑和物理上持续卡住,所属 runtime 不会被回收。

After:Agent 只终结一次,通知持久化但不启动新模型 turn,并且只 drain 和替换它实际所属的 runtime。

已验证平台

OS 状态
🍏 macOS ⚠️
🪟 Windows N/A
🐧 Linux N/A

环境(可选)

未运行本地测试、build、typecheck 或 CI 命令。仅进行了静态审查和 git diff --check,遵循所要求的本地工作流约束。

风险与范围

关联 Issue

本 PR 在 #11273 合入后完成 #8586 的实现堆栈。依赖栈仍开放期间,本 PR 不会自动关闭该 umbrella issue。

@qwen-code-ci-bot

qwen-code-ci-bot commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator

🚫 Qwen Triage was cancelledview run. The run was cancelled before finishing. Check for a newer run before re-running.

🚫 Qwen Triage 已取消 —— 查看运行。运行未完成即被取消。重跑前请先确认是否有更新的运行。

…ions' into codex/issue-8586-unresponsive-agent
…ions' into codex/issue-8586-unresponsive-agent
@yiliang114
yiliang114 merged commit 90244a6 into codex/issue-8586-runtime-generations Sep 7, 2026
9 of 12 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

Development

Successfully merging this pull request may close these issues.

3 participants