Skip to content

fix(web): settle subagent entries stuck at "running" after interruption or disconnect#1969

Open
youngting520 wants to merge 1 commit into
MoonshotAI:mainfrom
youngting520:fix/1963-stale-running-subagents
Open

fix(web): settle subagent entries stuck at "running" after interruption or disconnect#1969
youngting520 wants to merge 1 commit into
MoonshotAI:mainfrom
youngting520:fix/1963-stale-running-subagents

Conversation

@youngting520

@youngting520 youngting520 commented Jul 20, 2026

Copy link
Copy Markdown

Related Issue

Resolve #1963

Problem

Kimi Web builds its live subagent rows from WebSocket lifecycle events. If the client misses a terminal event — for example, when a computer sleeps or the display-off period disconnects the socket and the client later resumes — the local row can remain running indefinitely even though the subagent has already finished. A 429 interruption and retry is another way to expose the same lifecycle gap, but it is not the only cause.

The underlying reconciliation problem crossed several layers:

  • After a disconnect, the snapshot could not always prove that a locally cached row was stale. The roster did not model whether work could outlive the main turn or whether a row was owned by the roster versus REST /tasks.
  • Direct mirrored runs did not publish subagent.failed for aborts or start-hook failures, while a retryable 429 attempt must remain non-terminal until the swarm scheduler decides the logical subagent is finished.
  • Foreground descendants of background agents look foreground locally, but they share their background owner's lifetime and must not be cleared by a broad main-turn cleanup.

This left completed work visible with a growing timer and made it difficult for users to tell whether an agent was still consuming resources.

What changed

Close the lifecycle and reconciliation gaps at the engine, server, and Web client boundaries:

  • Agent engine: direct mirrored runs now publish subagent.failed for aborts, hook failures, and other errors. A retryable provider 429 emits subagent.suspended without a premature terminal; retry success emits subagent.completed, while the scheduler emits one final subagent.failed if the last unfinished member cannot be requeued.
  • Server snapshots: the subagent roster derives and propagates main_turn_independent through background-agent descendants. Main-owned background tasks remain REST-owned, while nested or detached background work stays roster-owned so it survives reconnects and main-turn boundaries until its own lifecycle settles.
  • Web reconciliation: task rows track main-turn independence and roster/REST ownership. At a main-turn boundary, stale main-bound rows are removed after normal completion or marked failed after interruption. When a roster is present in a snapshot it is authoritative for roster-owned rows; older servers that omit the roster retain the compatibility fallback.

The result is that stale timers converge after sleep/wake cycles, other disconnects, and live interruptions without terminating or hiding legitimate background subagent trees.

Validation

  • pnpm --filter @moonshot-ai/agent-core-v2 test
  • pnpm --filter @moonshot-ai/kap-server test
  • pnpm --filter @moonshot-ai/kimi-web test
  • Type checks for all three affected packages
  • pnpm --filter @moonshot-ai/agent-core-v2 lint:domain
  • pnpm --filter @moonshot-ai/kimi-web check:style (baseline mode)
  • pnpm lint (0 errors; existing repository warnings remain)
  • pnpm changeset status --since=upstream/main

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread apps/kimi-web/src/api/daemon/eventReducer.ts Outdated
Comment thread packages/agent-core-v2/src/session/subagent/mirrorAgentRun.ts Outdated
@youngting520
youngting520 force-pushed the fix/1963-stale-running-subagents branch from 46d65dc to 47d0370 Compare July 20, 2026 15:07
@changeset-bot

changeset-bot Bot commented Jul 20, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 680e9f3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kimi-code Patch

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

@youngting520
youngting520 force-pushed the fix/1963-stale-running-subagents branch from 47d0370 to e0aef68 Compare July 22, 2026 17:32
…on or disconnect

Subagent rows could remain running after aborts, rate-limit retries, or
disconnects because lifecycle terminals were not consistently emitted and
the web client could not reconcile rows missed while offline.

Make direct mirrored runs publish failures for aborts and hook errors. Keep
retryable 429 attempts non-terminal while the swarm owns the logical
subagent, then publish one final failure if it cannot be requeued.

Propagate main-turn-independent lifetime through background-agent
descendants and make the server roster authoritative for nested live work.
The web client now distinguishes roster-owned and REST-owned rows, settles
main-turn-bound rows at turn boundaries, and reconciles missed terminals
from snapshots without killing legitimate background descendants.

Resolve MoonshotAI#1963
@youngting520
youngting520 force-pushed the fix/1963-stale-running-subagents branch from e0aef68 to 680e9f3 Compare July 22, 2026 17:36
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.

Web UI keeps showing finished subagents as running after reconnect or interruption

1 participant