fix(web): settle subagent entries stuck at "running" after interruption or disconnect#1969
Open
youngting520 wants to merge 1 commit into
Open
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 46d65dc369
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…on or disconnect An interrupted subagent (e.g. a 429 rate limit aborting the run) never emitted a terminal subagent.* event: mirrorAgentRun swallowed the failure for any AbortError, so the web UI kept the entry "running" forever. The client also had no way to recover a missed terminal event — foreground subagents are served neither by REST /tasks nor by the snapshot roster once the next main turn starts. Close the gap at three layers: - Engine: mirrorAgentRun guarantees exactly one terminal event after subagent.started; aborts publish subagent.failed (matching v1). The swarm scheduler keeps its suppression, and session init opts out via the new suppressAbortFailureEvent option. - Web client: when the main turn ends (turnActiveChanged active:false — the single source of truth for the main-turn boundary), foreground subagent rows still running are settled as failed; background/detached subagents stay owned by REST /tasks. Prompt-level events are not used as the settle signal: aborting a queued prompt emits promptAborted while the active turn and its subagents legitimately keep running. - Web client: when the snapshot shows an idle main turn, the merge drops stale live foreground rows the roster no longer knows instead of guessing a terminal state — absence from the roster cannot distinguish completed from failed, so the persisted Agent tool result drives the final display. Resolve MoonshotAI#1963
youngting520
force-pushed
the
fix/1963-stale-running-subagents
branch
from
July 20, 2026 15:07
46d65dc to
47d0370
Compare
🦋 Changeset detectedLatest commit: 47d0370 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
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.
Related Issue
Resolve #1963
Problem
In
kimi websessions, subagent entries can stay "running" forever with an ever-growing timer even though the subagent already finished: an interrupted subagent (e.g. a 429 rate limit aborting the run) never emits a terminalsubagent.*event, and the web client has no way to recover from a missed terminal event — foreground subagents are served neither by REST/tasksnor by the snapshot roster once the next main turn starts, so a stale row survives every refresh. The same stale state also appears after an ordinary client disconnect with no error at all, while background tasks recover correctly via REST/tasks.What changed
Close the gap at three layers so a spawned subagent always reaches a terminal UI state:
mirrorAgentRunnow guarantees exactly one terminal event aftersubagent.started— aborts publishsubagent.failedlike any other failure instead of being silently swallowed (matching the v1 engine's behavior). The swarm scheduler keeps its existing suppression, and session init opts out explicitly via a newsuppressAbortFailureEventoption to stay quiet on user cancellation.prompt.completed/prompt.aborted), foreground subagent rows stillrunningare settled as failed — a foreground subagent cannot outlive its prompt, so such a row is stale by definition. Background and detached (Ctrl+B) subagents are left to REST/tasks.Tests: new engine-side cases for abort/suppressed-abort mirroring, reducer cases for the prompt-end settle, and snapshot-merge cases for the idle-session settle (kimi-web suite 652 tests, agent-core-v2 and kap-server suites green).
Checklist
gen-changesetsskill, or this PR needs no changeset.gen-docsskill, or this PR needs no doc update.