Skip to content

Conversation

@temujin9
Copy link
Contributor

@temujin9 temujin9 commented Jan 19, 2026

Summary

Fixes several issues with stream cancellation when pressing Ctrl-C or ESC:

  1. Ctrl-C during agent execution: The isExecuting check in useInput returned early before the Ctrl-C handler could run. Fixed by moving Ctrl-C check before the isExecuting return.

  2. Missing backend cancel during tool execution: When pressing ESC while tools were executing, the code aborted client-side but never sent a cancel to the backend, leaving runs in "running" state. This caused 409 ConversationBusyError on subsequent messages.

  3. Cancel API compatibility: The conversations.cancel() endpoint returns 404 on local Letta servers. Simplified to always use agents.messages.cancel() which works universally.

Changes

  • Modified ApprovalDialogRich.tsx to check for Ctrl-C before the isExecuting early return
  • Added backend cancel call to the tool execution interrupt path in handleInterrupt
  • Simplified cancelCurrentRun helper to always use agents API

Test plan

  • Build passes successfully
  • Manual test: ESC during streaming cancels properly
  • Manual test: ESC during tool execution cancels properly
  • Manual test: No 409 errors on subsequent messages after cancellation
  • Verified fix works on both Letta Cloud and local Letta servers

🤖 Generated with Claude Code

Previously, Ctrl-C was blocked when the agent was executing (isExecuting
flag was true), requiring users to wait for completion before cancelling.

This fix moves the Ctrl-C handler before the isExecuting check, ensuring
users can always cancel regardless of execution state. This is especially
important for long-running operations or when the agent is stuck.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@cpacker
Copy link
Collaborator

cpacker commented Jan 19, 2026

@temujin9 to clarify what's the desired behavior here? (sorry having a hard time parsing)

Right now, the intended design is (if streaming):

  1. Pressing esc cancels the stream
  2. Presssing ctrl-c clears the input (but doesn't cancel the stream)

temujin9 and others added 3 commits January 18, 2026 22:13
When conversationId is "default" (agent's primary message history),
cancel requests should use the agents API endpoint instead of the
conversations API. This fixes the 409 ConversationBusyError when
pressing ESC during streaming with the default conversation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The handleInterrupt function had two code paths:
1. Tool execution path (isExecutingTool=true) - aborted client-side only
2. EAGER_CANCEL path - called backend cancel

The first path was missing the backend cancel call, leaving runs
in "running" state when ESC was pressed during tool execution.
This caused 409 ConversationBusyError on subsequent messages.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Simplify cancelCurrentRun to always use client.agents.messages.cancel()
instead of branching between agents and conversations APIs.

The conversations.cancel() endpoint returns 404 on local Letta servers,
while agents.messages.cancel() works universally for all conversation types.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@temujin9 temujin9 changed the title fix: allow Ctrl-C to cancel even during agent execution fix: improve Ctrl-C/ESC cancellation handling Jan 19, 2026
@temujin9
Copy link
Contributor Author

temujin9 commented Jan 19, 2026

Presssing ctrl-c clears the input (but doesn't cancel the stream)

That is surprising, for people used to existing terminals and other TUI coding agents. In those contexts ctrl-C is generally a cancel command, as with esc in yours and other coding agents. (The equivalent of clear screen for terminals is ctrl-L: I'm not sure why, that's just what I know to use.)

This PR is mostly about under-the-hood behaviors when a cancel is detected. I don't believe I actually touch what defines a cancellation here. (ETA: no, you're right, I do because I change the behavior of the ctrl-C flow.)

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.

2 participants