Skip to content

Easy Message Unqueue with /unqueue - #6415

Closed
will-marella wants to merge 4 commits into
anomalyco:devfrom
will-marella:feature/unqueue-clean
Closed

will-marella wants to merge 4 commits into
anomalyco:devfrom
will-marella:feature/unqueue-clean

Conversation

@will-marella

@will-marella will-marella commented Dec 30, 2025 •

Copy link
Copy Markdown
Contributor

Summary

Adds /unqueue slash command to remove queued messages without affecting the current assistant response. It also adds a keybind, "session_unqueue" (default: none), so it can be easily configured by users.

Problem

Oftentimes after queueing a message, I decide I want to rewrite it or ask something else altogether. In these cases, I’d like to remove all queued messages from the queue.

Solution

The /unqueue command:

  • Removes queued user messages
  • Deletes them from persistent storage (clean conversation history)
  • Rejects in-memory callbacks (messages never execute)
  • Silent operation (no UI clutter)

Demo

opencode-easyunqueue.mp4

I experimented with introducing an interactable button in the TUI. (Imagine hovering over the QUEUED button and it prompts you to UNQUEUE) But this approach keeps the implementation simple and focused

@ariane-emory

Copy link
Copy Markdown
Contributor

Neat. There's no way I'm typing a long command name like that by hand, though, I would want the ability to bind it to a key (although the default bindings should be "none", allowing users to bind it to a key it they so choose). Likely only requires adding a couple of lines.

Will@Cambridge added 4 commits December 29, 2025 21:14
- Replace full message array accumulation with streaming iteration
- Stop at first assistant message (boundary optimization)
- Only store message IDs instead of full objects
- Use parallel deletion with Promise.all
- Memory: ~200KB → ~150 bytes (1000x reduction)
- I/O: Load 1-10 messages instead of 100+ (early break)
- Code: Only +6 lines for massive performance gain
…leUnqueue

- Rename queuedIDs -> queued (single-word preference per style guide)
- Remove let foundPending by moving deletion into conditional
- Add comment documenting MessageV2.stream order assumption
- Follows style guide: avoid let statements where possible
@will-marella

Copy link
Copy Markdown
Contributor Author

Neat. There's no way I'm typing a long command name like that by hand, though, I would want the ability to bind it to a key (although the default bindings should be "none", allowing users to bind it to a key it they so choose). Likely only requires adding a couple of lines.

You're right, that should be supported. I've updated the PR.

@Mishkun

Mishkun commented Dec 30, 2025

Copy link
Copy Markdown
Contributor

this will fix #4821

@github-actions

github-actions Bot commented Mar 1, 2026

Copy link
Copy Markdown
Contributor

Closing this pull request because it has had no updates for more than 60 days. If you plan to continue working on it, feel free to reopen or open a new PR.

@github-actions github-actions Bot closed this Mar 1, 2026
hunterchristian added a commit to chipp-ai/opencode that referenced this pull request Sep 23, 2026
New SessionV2.pending/withdraw/revise methods let a caller remove or
edit a message that's been durably admitted but not yet promoted into
a visible turn -- plus three new HTTP routes and a TUI /queue dialog.

Ported from upstream anomalyco#4821 (126 reactions): PR anomalyco#6415
"Easy Message Unqueue with /unqueue" (closed by a 60-day-stale bot,
never reviewed) and PR anomalyco#6271 "add edit and discard actions for queued
messages" (more thorough, self-closed after apparent lack of
maintainer response). Both PRs remove a queued message from an
in-memory callback list and delete the V1 message -- a backend model
with no equivalent in this repo's V2 session core, where a queued
message is a durable row that stays pending until a safe promotion
point. So the backend here is a fresh, V2-native design, not a port:
a durable event (session.next.prompt.withdrawn / .revised) is
published and projected the same way SessionInput.Prompted already
works, guarded to only affect rows that are neither promoted nor
withdrawn, with a withdraw winning any race against an in-flight
promotion. What was reused: the remove/edit concepts themselves,
/unqueue kept as a command alias (anomalyco#6415), and the general shape of a
queued-message picker UI (anomalyco#6271) -- reworked as a /queue list dialog
rather than anomalyco#6271's inline "EDITING" mode in the main prompt box.

New requireInput flag threads through the turn loop in
packages/core/src/session/runner/llm.ts so a turn whose only
justification was a withdrawn input is skipped rather than run with
nothing to answer -- merged by hand against this fork's own
model-fallback feature, which had already added a different
parameter (tried) to the exact same functions.

KNOWN, SIGNIFICANT GAP: the TUI still sends every prompt through the
legacy V1 SessionPrompt path, which never creates the V2 session_input
rows this feature acts on. /queue will show an empty list for
anything typed in the actual running TUI today. Switching the TUI to
send V2 prompts is a materially bigger decision than this feature's
own scope and was deliberately left for a separate follow-up rather
than silently expanded into. The backend is fully real, tested, and
reachable via the HTTP API directly today.

New tests: packages/core/test/session-prompt.test.ts (+10 cases),
session-runner.test.ts (+4), packages/tui/test/cli/tui/data.test.tsx
(+2), three new httpapi-exercise scenarios, event-manifest count
updated (88 -> 90 for the two new durable events). Client and legacy
JS SDKs regenerated. Verified against this fork's current dev,
including the manual merge against model-fallback: bun typecheck
clean across all 30 packages; packages/core 1178 pass (only the
pre-existing pty flake); packages/opencode 3613 pass, only the 4
pre-existing cf-ai-gateway failures; packages/tui 230 pass;
httpapi-exercise coverage mode 214 pass.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
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.

3 participants