[FEATURE]: Graceful handling of queued messages after session interrupt #3450

Open
opened 2026-02-16 17:40:07 -05:00 by yindo · 6 comments
Owner

Originally created by @thoughtlesslabs on GitHub (Dec 10, 2025).

Originally assigned to: @rekram1-node on GitHub.

Feature hasn't been suggested before.

  • I have verified this feature I'm about to request hasn't been suggested before.

Describe the enhancement you want to request

Problem

When a user sends multiple messages while an operation is in progress, the messages are queued. However, if the current operation is interrupted (aborted), the queued messages are silently rejected and lost rather than being processed. This creates a poor user experience, especially when iterating quickly with the AI assistant.

Current behavior:

https://github.com/user-attachments/assets/d9140fe6-3504-48b7-9ca2-e5d2a6f2bdbe

  • User sends message A (starts processing)
  • User sends message B while A is processing (queued)
  • User interrupts message A
  • Message B is silently discarded

Expected behavior:

  • User sends message A (starts processing)
  • User sends message B while A is processing (queued)
  • User interrupts message A
  • Message B begins processing automatically

Proposed Solution

This feature adds graceful queue handling with full visibility and control:

https://github.com/user-attachments/assets/b68d6f89-1ffb-4f0b-bef1-6c1511cd4b5a

1. Queue Persistence After Interrupts

Queued messages remain in the queue and are processed in order after an interrupt, rather than being rejected.

2. Cancel Individual Queued Messages

Users can remove specific messages from the queue via the message action dialog (click on a queued message to see the "Cancel" option).

Image

3. Separated Queue Display

Queued messages are pinned in a dedicated section above the input prompt, visually separated from the scrolling conversation. A "Processing next task..." separator shows when tasks transition.

Image

Implementation

A working implementation is available in the fork branch:

🔗 https://github.com/thoughtlesslabs/opencode/tree/feat/queued-message-interrupt

Key Changes

File Description
packages/opencode/src/session/prompt.ts Queue handling logic with loopId tracking to prevent race conditions, cancelQueued() and getQueuedMessageIds() functions
packages/opencode/src/cli/cmd/tui/routes/session/index.tsx Visual queue separation with queuedMessages and activeMessages memos, pinned queue section
packages/opencode/src/cli/cmd/tui/routes/session/dialog-message.tsx Cancel action for queued messages in the message dialog

Technical Details

  • Added loopId tracking using ulid() to prevent race conditions when canceling/restarting loops
  • Queue callbacks now include userMessageID for proper tracking
  • processQueuedCallbacks() handles ordered queue processing after interrupts
  • UI uses SolidJS reactive memos for efficient queue state management

Why It Belongs in OpenCode

  1. Improves UX - User input is never silently discarded
  2. Provides transparency - Users can see exactly what's queued and processing
  3. Gives users control - Ability to cancel individual queued messages
  4. Common workflow - Users frequently iterate quickly, sending follow-up messages before the AI finishes
  5. No breaking changes - Backward compatible enhancement to existing behavior

This feature request follows the CONTRIBUTING.md guidelines for net-new functionality.

Originally created by @thoughtlesslabs on GitHub (Dec 10, 2025). Originally assigned to: @rekram1-node on GitHub. ### Feature hasn't been suggested before. - [x] I have verified this feature I'm about to request hasn't been suggested before. ### Describe the enhancement you want to request ## Problem When a user sends multiple messages while an operation is in progress, the messages are queued. However, if the current operation is interrupted (aborted), the queued messages are silently rejected and lost rather than being processed. This creates a poor user experience, especially when iterating quickly with the AI assistant. **Current behavior:** https://github.com/user-attachments/assets/d9140fe6-3504-48b7-9ca2-e5d2a6f2bdbe - User sends message A (starts processing) - User sends message B while A is processing (queued) - User interrupts message A - Message B is silently discarded ❌ **Expected behavior:** - User sends message A (starts processing) - User sends message B while A is processing (queued) - User interrupts message A - Message B begins processing automatically ✅ ## Proposed Solution This feature adds graceful queue handling with full visibility and control: https://github.com/user-attachments/assets/b68d6f89-1ffb-4f0b-bef1-6c1511cd4b5a ### 1. Queue Persistence After Interrupts Queued messages remain in the queue and are processed in order after an interrupt, rather than being rejected. ### 2. Cancel Individual Queued Messages Users can remove specific messages from the queue via the message action dialog (click on a queued message to see the "Cancel" option). <img width="1596" height="1292" alt="Image" src="https://github.com/user-attachments/assets/6d4d3c2a-d16d-4da5-878a-d5b19b08ad31" /> ### 3. Separated Queue Display Queued messages are pinned in a dedicated section above the input prompt, visually separated from the scrolling conversation. A "Processing next task..." separator shows when tasks transition. <img width="1597" height="1295" alt="Image" src="https://github.com/user-attachments/assets/5994e19d-a67a-4896-9563-19ab20e11019" /> ## Implementation A working implementation is available in the fork branch: 🔗 **<https://github.com/thoughtlesslabs/opencode/tree/feat/queued-message-interrupt>** ### Key Changes | File | Description | |------|-------------| | `packages/opencode/src/session/prompt.ts` | Queue handling logic with `loopId` tracking to prevent race conditions, `cancelQueued()` and `getQueuedMessageIds()` functions | | `packages/opencode/src/cli/cmd/tui/routes/session/index.tsx` | Visual queue separation with `queuedMessages` and `activeMessages` memos, pinned queue section | | `packages/opencode/src/cli/cmd/tui/routes/session/dialog-message.tsx` | Cancel action for queued messages in the message dialog | ### Technical Details - Added `loopId` tracking using `ulid()` to prevent race conditions when canceling/restarting loops - Queue callbacks now include `userMessageID` for proper tracking - `processQueuedCallbacks()` handles ordered queue processing after interrupts - UI uses SolidJS reactive memos for efficient queue state management ## Why It Belongs in OpenCode 1. **Improves UX** - User input is never silently discarded 2. **Provides transparency** - Users can see exactly what's queued and processing 3. **Gives users control** - Ability to cancel individual queued messages 4. **Common workflow** - Users frequently iterate quickly, sending follow-up messages before the AI finishes 5. **No breaking changes** - Backward compatible enhancement to existing behavior --- *This feature request follows the [CONTRIBUTING.md](https://github.com/sst/opencode/blob/dev/CONTRIBUTING.md) guidelines for net-new functionality.*
yindo added the discussion label 2026-02-16 17:40:07 -05:00
Author
Owner

@github-actions[bot] commented on GitHub (Dec 10, 2025):

This issue might be a duplicate of existing issues. Please check:

  • #4821: Add ability to unqueue messages
  • #5135: Queued message interrupts todolist execution
  • #2270: When aborting and sending a new message the agent ignores the new message and starts processing the previous user message
  • #2246: Queued message not running
  • #1476: Forgets queued messages

Feel free to ignore if none of these address your specific case.

@github-actions[bot] commented on GitHub (Dec 10, 2025): This issue might be a duplicate of existing issues. Please check: - #4821: Add ability to unqueue messages - #5135: Queued message interrupts todolist execution - #2270: When aborting and sending a new message the agent ignores the new message and starts processing the previous user message - #2246: Queued message not running - #1476: Forgets queued messages Feel free to ignore if none of these address your specific case.
Author
Owner

@thoughtlesslabs commented on GitHub (Dec 10, 2025):

I do understand that there are some other related issues raised, but i put this as a new one because it provides a comprehensive solution and I wanted to submit this is a feature request instead of a bug fix because it introduces updated ui/ux elements

@thoughtlesslabs commented on GitHub (Dec 10, 2025): I do understand that there are some other related issues raised, but i put this as a new one because it provides a comprehensive solution and I wanted to submit this is a feature request instead of a bug fix because it introduces updated ui/ux elements
Author
Owner

@rekram1-node commented on GitHub (Dec 10, 2025):

I see...

@rekram1-node commented on GitHub (Dec 10, 2025): I see...
Author
Owner

@thoughtlesslabs commented on GitHub (Dec 22, 2025):

Hey @rekram1-node what would next steps be on this? Push as a pr?

@thoughtlesslabs commented on GitHub (Dec 22, 2025): Hey @rekram1-node what would next steps be on this? Push as a pr?
Author
Owner

@rekram1-node commented on GitHub (Dec 23, 2025):

The proposal sounds a bit more complicated than what i'd expect but I havent looked into this particular issue enough.

It seems like there is prolly a simple fix so that a queued message would be persisted to disk

@rekram1-node commented on GitHub (Dec 23, 2025): The proposal sounds a bit more complicated than what i'd expect but I havent looked into this particular issue enough. It seems like there is prolly a simple fix so that a queued message would be persisted to disk
Author
Owner

@thoughtlesslabs commented on GitHub (Jan 13, 2026):

@rekram1-node the fix i originally put forward still did some weird things, but was definitely simpler. I can close these ones and figure out a better solution. It's funny how often i run into this, but I queue messages quite a bit. And also interrupt actions when i can see things going off the rails.

@thoughtlesslabs commented on GitHub (Jan 13, 2026): @rekram1-node the fix i originally put forward still did some weird things, but was definitely simpler. I can close these ones and figure out a better solution. It's funny how often i run into this, but I queue messages quite a bit. And also interrupt actions when i can see things going off the rails.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#3450