Stop running threads with Escape - #4298
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 4fce377. Configure here.
| if (shouldInterruptRunningThreadFromComposerKey({ key, isRunning: phase === "running" })) { | ||
| onInterrupt(); | ||
| return true; | ||
| } |
There was a problem hiding this comment.
Escape stops during pending input
Medium Severity
When structured plan or user-input questions are open, the footer shows submit/next controls and hides stop generation, but Escape in the composer still calls onInterrupt() whenever phase === "running". That can abort the turn while someone is typing a custom answer, diverging from the primary-action UI the thread can already be running during pending input.
Reviewed by Cursor Bugbot for commit 4fce377. Configure here.
ApprovabilityVerdict: Needs human review This PR adds new user-facing keyboard behavior (Escape stops running threads). An unresolved review comment identifies a potential issue where Escape could unintentionally abort threads during pending input scenarios, warranting human review. You can customize Macroscope's approvability policy. Learn more. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4fce377276
ℹ️ 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".
| if (shouldInterruptRunningThreadFromComposerKey({ key, isRunning: phase === "running" })) { | ||
| onInterrupt(); | ||
| return true; |
There was a problem hiding this comment.
Preserve IME Escape while composing
When a turn is running and the user is editing with an IME, Escape is commonly used to cancel the current composition/conversion. This new branch runs before any composition check and then consumes the key after onInterrupt(), so an IME user trying to cancel conversion in the composer will instead stop the thread. Please skip the interrupt while event.isComposing so IME editing still works.
Useful? React with 👍 / 👎.


Summary
Why
The chat composer did not forward Lexical's Escape command to the thread controls, so keyboard users had to move focus to the stop button to interrupt a running turn.
User impact
Users can now stop a running thread by pressing Escape without leaving the chat input.
Validation
vp check apps/web/src/composer-logic.ts apps/web/src/composer-logic.test.ts apps/web/src/components/ComposerPromptEditor.tsx apps/web/src/components/chat/ChatComposer.tsxvp test run apps/web/src/composer-logic.test.ts(44 tests passed)pnpm --filter @t3tools/web typecheckNote
Stop running threads by pressing Escape in the chat composer
Escapeto theComposerCommandKeyunion type and registers a LexicalKEY_ESCAPE_COMMANDhandler inComposerPromptEditorto forward the key toonCommandKeyDown.shouldInterruptRunningThreadFromComposerKeyin composer-logic.ts, a predicate that returns true only when the key isEscapeand the thread phase isrunning.ChatComposerchecks this predicate on each composer key event and callsonInterrupt()when it returns true, consuming the key before other handlers run.Macroscope summarized 4fce377.
Note
Low Risk
Small UX change that reuses the existing interrupt callback and only runs when
phase === "running".Overview
Escape in the chat composer now stops an in-progress turn without moving focus to the stop control.
Lexical’s
KEY_ESCAPE_COMMANDis wired through the same command-key path as arrows, Enter, and Tab.ChatComposerchecksshouldInterruptRunningThreadFromComposerKeyfirst and callsonInterrupt()when the session phase isrunning; when idle, Escape is not consumed so existing behavior can stay available elsewhere.Shared typing moves to
ComposerCommandKey(includingEscape), with unit tests on the interrupt predicate.Reviewed by Cursor Bugbot for commit 4fce377. Bugbot is set up for automated code reviews on this repo. Configure here.