feat(acp): add --multiple-event-handling flag with cancel+re-prompt#216
Open
tlongwell-block wants to merge 1 commit intomainfrom
Open
feat(acp): add --multiple-event-handling flag with cancel+re-prompt#216tlongwell-block wants to merge 1 commit intomainfrom
tlongwell-block wants to merge 1 commit intomainfrom
Conversation
Add a single flag `--multiple-event-handling queue|interrupt|owner-interrupt`
that controls how new @mentions are handled while a turn is already in-flight:
- `queue` (default): existing behavior, zero code change in this path
- `interrupt`: cancel in-flight turn via ACP `session/cancel`, then
re-dispatch a merged prompt combining original + new events
- `owner-interrupt`: same cancel behavior, but only for @mentions from
the agent owner (resolved via OwnerCache); everyone else queues normally
Also adds `!cancel` explicit command (owner-only, mode-independent) that
mirrors the `!shutdown` pattern — detected before queue.push(), consumed
on match, falls through to normal handling for non-owners.
Cancel mechanics:
- Signal: tokio::sync::oneshot per channel task (None for heartbeats)
- select! { biased } prefers natural completion over cancel
- has_in_flight_prompt() guard prevents Race 1 deadlock
- Session invalidated after cancel → fresh session on re-prompt
- requeue_as_cancelled() stores events separately from generic queue
- flush_next() merges cancelled_batches into FlushBatch.cancelled_events
- format_prompt() produces annotated sections when cancelled_events present
- Fallback path handles !cancel with no new events (re-dispatch unchanged)
Startup validation rejects interrupt/owner-interrupt with DedupMode::Drop.
Tests: 263 passed (258 existing + 5 new cancel queue operation tests).
wesbillman
approved these changes
Apr 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add
--multiple-event-handling queue|interrupt|owner-interrupt— a single flag controlling how new @mentions are handled while a turn is already in-flight.queue(default)interruptowner-interruptAlso adds
!cancelexplicit command (owner-only, mode-independent, mirrors!shutdownpattern).How it works
Cancel mechanics:
tokio::sync::oneshotper channel task (Nonefor heartbeats)select! { biased }prefers natural completion over cancelhas_in_flight_prompt()guard prevents Race 1 deadlockrequeue_as_cancelled()stores events separately from generic queueflush_next()mergescancelled_batchesintoFlushBatch.cancelled_eventsformat_prompt()produces annotated[Previous request — interrupted]/[New request — supersedes previous]sections!cancelwith no new events (re-dispatch unchanged)Startup validation: Rejects
interrupt/owner-interruptwithDedupMode::Drop(events would be lost during cancel drain).Files changed
acp.rshas_in_flight_prompt()accessorconfig.rsMultipleEventHandlingenum, CLI arg, Config field, validation, summarymain.rs!cancelcommand, mode gate,cancel_in_flight_task(), oneshot dispatch,requeue_as_cancelledfor Cancelledpool.rsTaskMeta.cancel_tx,PromptOutcome::Cancelled,select!cancel logicqueue.rsFlushBatch.cancelled_events,cancelled_batchesHashMap, merge logic, 5 new unit testsTesting
cargo clippycleanhas_flushable_work,drain_channelcleanup, double-cancel accumulationAccepted limitations
!cancel+DedupMode::Droploses the batch (Drop mode semantics — events are expendable)