Files
buzz/crates
Logan Johnson 133fb98692 fix(acp): steer running turns with edited mentions (#6132)
🤖
## Summary
Some agents can take a new message into a turn that is already running.
This is called "native steering." Before this PR, an edit that arrived
during a turn always cancelled the turn and started it again. Now the
edit is steered into the running turn, like any other new message. The
steered edit still points at the original message and its thread, so the
agent replies in the right place.

- The steer text carries the edit's route: `Edit of: …`, plus the
original's thread root.
- **Steer only within the same reply thread.** A native steer keeps the
running turn's `<context>`, so the reply goes where that `<context>`
points. The queue now records each running turn's reply thread. A
message is steered natively only when it replies in that same thread.
Under channel sessions one session spans threads, so an edit for another
thread (or another top-level message) takes the cancel-and-restart path.
Its re-prompt carries the message's own full `<context>`, with channel,
project, and profile data. The same rule applies to ordinary steered
messages, which had the same gap before this PR.
- **Per-thread sessions:** the edit steers only a turn running in the
same session as its original message. An edit in thread A is never added
to a turn running in thread B. If no turn is running in that session,
the edit waits in the queue as its own item.
- **Channel sessions** (the default): the channel has one session. A
running turn receives the edit natively only when the edit replies in
that turn's thread.
- If native steering is not available, or the transport fails or the
agent rejects the steer, the existing cancel-and-restart fallback runs.
If the agent returns another error, or the turn has already finished,
the edit goes back to the queue for normal delivery. In every case the
queued edit keeps its route.

## Details
- #4741 looks up the original message once, before the edit is queued.
This PR passes that stored route to the existing steer path, and uses
the same session the edit was queued under. No new lookup or preparation
step is needed.
- Removal, re-add, and fallback all use the existing lifecycle for
withheld steers.

### Stack
**3 of 3**. #6131 is merged; this PR is now based on `main`.

### Related issue
Part of #2540 (fixed by #6131). This PR adds the running-turn behavior.

### Testing
- `cargo test -p buzz-acp --all-targets` passes. The one test that fails
when the git setting `nostr.keyfile` is set is described in #4741.
- Tests check that the steer text carries the original's route, and that
the listener gives the steer path the same route and session it queues.
- End-to-end tests send a routed edit through the listener's steer
decision under channel sessions. An edit in the running turn's thread,
and an edit of the running top-level message, steer natively with no
cancel. An edit for thread B during a thread-A turn, and an edit of
another top-level message, send no native steer and take cancel+merge.
Removing the same-thread check makes both cross-thread tests fail.

---------

Signed-off-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
2026-10-02 13:24:22 -04:00
..