anomalyco / anomalyco/opencode

[FEATURE] /undo during active generation: cancel the queued messages, keep the in-flight stream

Open
#44,202 0 comments 0 reactions 1 assignee View on GitHub

@kitlangton is already working on this.

Since Aug 22, 2026.

Dominant language
TypeScript
Stars
209k
Forks
27.5k
PR merge metrics
PR metrics pending

Description

Summary

Proposed semantics for /undo while a generation is active: cancel the queued messages and leave the in-flight stream alone, applying the revert once the active response completes.

Today the behavior is either a Session is busy failure (#38476) or — in the pre-beta behavior #38476 asks to restore — aborting the active generation. Both miss the common case.

The common case

A run is active and I realize the follow-up message I just queued is wrong (typo, wrong file, changed my mind). I reach for /undo. What I want reverted is the queued message — the part that has not been consumed yet. What I do not want is to kill the active generation:

  • On paid providers, aborting mid-stream throws away committed tokens.
  • On large local models (e.g. long-context local seats), prefill + decode can represent minutes of compute that must then be redone from scratch.

Esc/ctrl+c already exists as the explicit "kill the active generation" affordance. /undo does not need to be a second one.

Proposed behavior

Session state /undo behavior
Active stream + queued messages Drop the queued messages; keep the active stream; apply the revert after it completes
Active stream, empty queue Friendly no-op with a hint ("nothing queued — press Esc to abort") instead of a busy error
Idle Current behavior (revert last message)
Esc / interrupt Unchanged force-abort

This also gives a natural answer to the promotion race in #39736: a queued-but-not-yet-promoted message becomes an explicit "cancelled before promotion" outcome rather than an undo boundary the revert planner cannot find.

Why not simply restore abort+undo (the ask in #38476)

It works, but it conflates two operations and pays for both: the active generation is destroyed and the message is reverted. With queue-first semantics, #38476's reproduction (start response → /undo → error) resolves without any abort when the intent was fixing the queue, and Esc remains available when the intent really is killing the run.

Environment

  • opencode 1.18.15, macOS TUI (arm64), Homebrew
  • Abort path observed in local logs as message=cancel followed by message=process ... error=Aborted

Refs: #38476 (busy failure; asks for abort+undo), #39736 (admitted-message undo race after interrupt), #14014 (historical: session.undo aborted ongoing work)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.