Skip to content

feat(Chat): interrupt agent execution#39

Merged
remarkablemark merged 7 commits intomasterfrom
feat/interrupt
May 9, 2026
Merged

feat(Chat): interrupt agent execution#39
remarkablemark merged 7 commits intomasterfrom
feat/interrupt

Conversation

@remarkablemark
Copy link
Copy Markdown
Member

@remarkablemark remarkablemark commented May 9, 2026

What is the motivation for this pull request?

Implement interrupt functionality during agent/tool execution, similar to other TUIs.

What is the current behavior?

There is no way to cancel a running stream or reject a tool call and return to idle.

What is the new behavior?

  • Pressing Esc or Ctrl+C during streaming aborts the current request via AbortSignal and shows ❗ Execution interrupted.
  • Rejecting a tool call returns to idle and shows ❗ Tool call rejected. instead of re-streaming
  • A <turn_aborted> user-role message is injected into history on both interrupt and rejection so the model has context, but it is filtered from the UI
  • Messages moved to its own src/components/Messages/ directory with a constants.ts for TURN_ABORTED_MESSAGE
  • SSR build external list removed — Vite SSR mode auto-externalises all dependencies

Checklist:

Pressing Esc or Ctrl+C while the agent is streaming or executing a tool
cancels the in-flight operation, commits any partial assistant content
already accumulated, shows a UI-only interrupt notice, injects a
user-role `turn_aborted` message into history, and returns to the idle
input state.

Two things happen on interrupt:

1. **UI notice** (display-only, not in history):

   > `❗ Execution interrupted.`
   > Rendered via a transient `wasInterrupted` boolean state; disappears on next submit.

2. **History injection** (model sees it, as a `user` role message):
   ```
   <turn_aborted>
   The user interrupted the previous turn on purpose. Any running commands may still be running in the background. If any tools were aborted, they may have partially executed.
   </turn_aborted>
   ```
   Appended to `messages` state so the model knows not to assume success.

In `handleToolApproval` `DECISION.REJECT` case: replace the current
`system`-role `"User declined to execute tool {name}"` message with a
`user`-role `<turn_aborted>` message (same text as the interrupt).
Rejecting a tool call now displays a rejection message and returns
directly to idle — no re-stream, no repeated approval prompt.
@codecov
Copy link
Copy Markdown

codecov Bot commented May 9, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

Files with missing lines Coverage Δ
src/components/Chat/Chat.tsx 100.00% <100.00%> (ø)
src/components/Chat/Input.tsx 100.00% <100.00%> (ø)
src/components/Chat/constants.ts 100.00% <100.00%> (ø)
src/components/Messages/Messages.tsx 100.00% <100.00%> (ø)
src/components/Messages/constants.ts 100.00% <100.00%> (ø)
src/constants/ui.ts 100.00% <100.00%> (ø)
src/utils/ollama.ts 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@remarkablemark remarkablemark self-assigned this May 9, 2026
@remarkablemark remarkablemark added bug Something isn't working enhancement New feature or request labels May 9, 2026
@remarkablemark remarkablemark merged commit b2b87fb into master May 9, 2026
15 checks passed
@remarkablemark remarkablemark deleted the feat/interrupt branch May 9, 2026 00:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant