Files
buzz/crates
Salman Mohammed 46dcc01873 fix(acp): keep agent-to-agent thread replies in the thread (#8124)
## Summary
When an agent @mentions another agent inside a thread,
`resolve_reply_anchor` returned `None`, so the receiving agent's
`<context>` had no `--reply-to` instruction. A harness that follows the
base prompt literally then posted its reply at the channel top level.

Agent↔agent turns in a thread now anchor to the triggering event. The
reply stays in the thread and can still nest (the reason #1281 left
these turns unanchored). Top-level agent↔agent turns and all
human-facing turns are unchanged.

Native steering keeps the running turn's `<context>`, so a message
steered into a turn anchored to its trigger would be answered under that
trigger too. The prompt task now records whether its anchor is the
trigger, next to its DM classification (`PromptDmClassification` →
`PromptRouting`). The steer guard refuses native steering into a channel
thread turn whose anchor is the trigger, or not yet recorded. That
message takes the cancel+merge path, whose re-prompt carries its own
`<context>`.

Behavior change: a same-thread follow-up that arrives before the running
turn's prompt is formatted (for example during `session/new`) now
cancels and merges instead of steering natively, because the anchor is
not known yet. Once the prompt is formatted, follow-ups to human-facing
thread turns steer natively as before.

### Related issue
Fixes #8122

### Testing
- `cargo test -p buzz-acp -- --test-threads=1` (BUZZ_* env cleared):
1046 passed. `cargo clippy -p buzz-acp --all-targets -D warnings` clean.
Pre-push workspace `rust-tests` hook passed.
- New regressions, each confirmed to fail when its guard is removed:
- `human_follow_up_to_agent_thread_turn_cancels_and_merges`: a real
dispatched turn with agent profiles served by the relay fixture. A human
message in the same thread is not steered natively.
- `test_human_merged_into_agent_thread_turn_anchors_to_root`: the merged
re-prompt anchors to the thread root.
- `channel_same_thread_follow_up_during_prompt_steers_natively` /
`..._during_setup_cancels_and_merges`.
- Live local (`buzz-relay` + `buzz-acp` at this head + `buzz-pi-acp`;
agent B is a CLI identity with a NIP-OA auth tag):
- B @mentions A in a human-rooted thread → A's `<context>` says
`--reply-to <B's event>`, and the reply nests under B. On `main` the
`<context>` had no reply instruction.
- B asks A to `sleep 30` then reply; while A works, the human @mentions
A in the same thread → `control signal sent to in-flight task`
(cancel+merge), the re-prompt says `--reply-to <root>`, and both replies
land at the thread root.

---------

Signed-off-by: Leo <a3812943bac59c128e311ca05f83bf91113f179bb6fa9ca96c3d8efe15c330e6@buzz.block.builderlab.xyz>
Co-authored-by: Leo <a3812943bac59c128e311ca05f83bf91113f179bb6fa9ca96c3d8efe15c330e6@buzz.block.builderlab.xyz>
2026-10-06 18:31:37 +00:00
..