Skip to content

fix(agent-core-v2): keep user-cancellation identity when aborting swarm tool runs - #3729

Open
kimi-agent-bot wants to merge 2 commits into
MoonshotAI:mainfrom
kimi-agent-bot:fix/swarm-abort-exit1
Open

fix(agent-core-v2): keep user-cancellation identity when aborting swarm tool runs#3729
kimi-agent-bot wants to merge 2 commits into
MoonshotAI:mainfrom
kimi-agent-bot:fix/swarm-abort-exit1

Conversation

@kimi-agent-bot

Copy link
Copy Markdown
Collaborator

Problem

Interrupting an AgentSwarm (>=2 items running) with Esc in the TUI killed the whole process with exit 1 within ~1s, taking the main agent and all subagents down mid-turn with nothing in the log. Seen twice in production on 0.42.0.

Two faults chain together:

  1. human/agent/machine.ts aborted turn tools via entry.scope.abort() with no reason. The interruption therefore lost its UserCancellationError identity and surfaced as a generic DOMException("This operation was aborted"). In features/swarm/session/agentRunBatch.ts, the batchAbortListener's isUserCancellation check then failed, so the batch went down the fail() path and rejected instead of resolving per-subagent "aborted" results.
  2. features/swarm/session/sessionSwarmService.ts attached cleanup via promise.finally(cleanup) and dropped the derived promise. When the batch rejects, that floating promise rejects unobserved -> unhandledRejection -> run-shell.ts emergencyExit(1).

Fault 2 stands on its own: any genuine AgentRunBatch failure (not just user interruption) crashed the process the same way.

Fix

  • machine.ts: on the input.abort and abort-escalation paths, turn-tool scopes are now aborted with the user-cancellation reason (abortTurnToolsUserCancelled / stopTurnToolsUserCancelled / abortSpawnedTools), so an interrupted swarm batch resolves per-subagent "aborted" results as designed. The plain turn-exit path (abortTurnTools / stopTurnTools) still aborts without a reason, keeping the "turn over" semantics distinct from user cancellation. The first abort() latches the reason, so the later exit-path aborts cannot clobber it.
  • sessionSwarmService.ts: the cleanup chain now ends in .catch(() => {}), so a rejecting batch can no longer crash the process through the floating derived promise. The returned promise still rejects to the caller unchanged.
  • The human kernel cannot import _base (import-boundary rule: human is the pure kernel), so it gets its own UserCancellationError (userCancelled = true, name AbortError) in human/utils/abort.ts, and _base's isUserCancellation now also recognises cancellations structurally (userCancelled === true) across class copies.

Tests

  • machine.test.ts: aborting a turn now passes a UserCancellationError reason to running turn tools.
  • sessionSwarm.test.ts: a failing swarm batch no longer raises an unhandledRejection while run() still rejects to the caller.
  • abort.test.ts: isUserCancellation recognises a foreign class copy flagged with userCancelled.

All three fail before the fix and pass after. Full agent-core-v2 suite (6466 tests), typecheck, lint:imports, oxlint, build, and the no-comments check are green.

…rm tool runs

Interrupting an AgentSwarm with Esc aborted turn tools without an abort
reason, so the interruption lost its UserCancellationError identity and
the swarm batch rejected instead of resolving per-subagent "aborted"
results. The rejection then surfaced on a floating promise derived by
promise.finally(cleanup) in SessionSwarmService, raising an
unhandledRejection that killed the whole process with exit 1.

- abort turn tools with the user-cancellation reason on the input.abort
  and abort-escalation paths in the agent machine
- swallow the derived cleanup promise rejection in SessionSwarmService
  so a failing batch can no longer crash the process on its own
- recognise user cancellations structurally across class copies so the
  human kernel (which cannot import _base) can flag its own reason
@changeset-bot

changeset-bot Bot commented Sep 11, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 807f855

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

@pkg-pr-new

pkg-pr-new Bot commented Sep 11, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@807f855
npx https://pkg.pr.new/@moonshot-ai/kimi-code@807f855

commit: 807f855

@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: eeab7d6777

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread .changeset/swarm-abort-user-cancellation.md Outdated
The release changelog entry only needs the user-visible outcome;
implementation details live in the PR body.
@kimi-agent-bot

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

Reviewed commit: 807f85500d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

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.

1 participant