fix: abort Agent Manager prompts during startup - #11152
Merged
Merged
Conversation
Contributor
Code Review SummaryStatus: No Issues Found | Recommendation: Merge The new commit ( All logic from the previous review remains correct and unchanged. The new abstraction is clean:
Files Reviewed (4 files, incremental from b23d3df)
Reviewed by claude-4.6-sonnet-20260217 · 423,899 tokens Review guidance: REVIEW.md from base branch |
catrielmuller
approved these changes
Jun 12, 2026
t7tran
pushed a commit
to t7tran/kilocode
that referenced
this pull request
Aug 14, 2026
fix: abort Agent Manager prompts during startup
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
Agent Manager shows the first Local prompt and its working indicator immediately while the backend is still creating the real session. During that startup window, the UI can display active feedback such as "Considering next steps," but Escape previously used only the backend session status to decide whether a prompt was stoppable. The status was still idle and a new Local tab still had only a draft ID, so Escape did nothing even though the interface looked active.
The problem also had a narrower backend ordering component. Prompt work was forked before the runner state transition to
Runningwas committed. The child fiber could publishsession.status = busyfirst, allowing the UI to send an abort whileSessionRunState.cancel()still observed an idle runner and returned without interrupting anything.This explains why the problem also reproduces in ordinary Agent Manager sessions that were never moved to a worktree. Directory reassignment is not required. The repeated
Agent Manager Session Stoppedtelemetry showed that some Escape requests reached the extension, but that telemetry records stop intent before the backend confirms that a cancellable runner exists.Cause and history
PR #11103 made initial Local prompt feedback optimistic so cold session creation no longer looked unresponsive. That behavior is desirable, but it exposed the pre-session interval as visible work without extending Escape semantics to the same interval.
Cold session creation became more noticeable after the OpenCode v1.14.48 integration, which also brought the current Effect-based asynchronous prompt and runner lifecycle. Together these changes created two related gaps:
The earlier hypothesis that continuing a running session in another worktree was the primary cause did not explain the ordinary Local reproduction. The durable fix therefore addresses startup cancellation and runner ordering directly rather than routing aborts across worktree directories.
Durable behavior
Submitting is now a stoppable prompt state. Both the focused composer Escape handler and the document-level fallback treat optimistic submission like backend busy work.
When Escape is pressed before a real session is ready, the webview records cancellation intent against the specific optimistic message instead of sending an invalid abort with a draft ID. That intent:
sessionCreatedarrives;Normal busy sessions still abort immediately, and repeated Escape remains available while the same turn remains active.
The runner now gates work behind a latch. It commits the
Runningstate before opening the latch, so work cannot publish busy beforecancel()can find it. Latch opening is uninterruptible after the state commit, which prevents an interrupted first caller from leaving a permanently blocked runner. The same ordering applies when queued work begins after a shell command.Constraints
The optimistic Local prompt remains visible immediately; this does not restore the old blank waiting period. The change also preserves the existing HTTP and SSE contracts, so no SDK regeneration or protocol migration is required.
Cancellation state stays in the webview because it bridges a UI-only draft ID to a backend session ID. The runner ordering guarantee lives in the CLI because
busymust represent cancellable work for every client, not only VS Code.