buzz-acp: claude-agent-acp turns complete successfully but the reply is never published (only typing reactions, then deleted)
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
## Summary
`buzz-acp` running `claude-agent-acp` as the harness command completes every turn successfully (`agent_returned … outcome="ok"`, including turns that make tool calls), but the agent's generated text reply is **never published** as a `kind:9` chat message. The only events the harness publishes for the turn are a `👀` and `💬` reaction (kind:7, presumably a "seen/typing" indicator) which are deleted again (kind:5) once the turn finishes. No error, warning, or any other visible signal is emitted — the response is silently lost.
Reproduced 4/4 times across two different `--multiple-event-handling` modes (`steer` default, and `queue`), so it is not related to the mid-turn steering fallback.
## Environment
- `buzz-acp` build: git commit `02f640bc4559c48ac0c2ec595ef34dd2c294b0db` (2026-08-07), self-built release binary
- Relay: self-hosted `ghcr.io/block/buzz:main`, single-node (Postgres 17 + Redis 7 + MinIO), reached over `wss://`
- Harness command: `claude-agent-acp` (`@agentclientprotocol/claude-agent-acp` v0.49.0, via `/usr/bin/node`)
- Run as a `systemd` service (`Type=simple`, `Restart=always`), `BUZZ_PRIVATE_KEY` + `BUZZ_ACP_AGENT_OWNER` set via env file
- Config used: `subscribe=Mentions`, `dedup=Queue`, `respond_to=anyone`, `permission_mode=dontAsk`, tried both `multiple-event-handling=steer` (default) and `=queue`
## Steps to reproduce
1. Run `buzz-acp --private-key --relay-url wss:// --agent-owner --agent-command claude-agent-acp --respond-to anyone` pointed at a channel the agent is a member of (confirmed via `kind:39002` membership and `discovered N channel(s)` at startup).
2. From another client (Buzz Desktop, macOS), send a message in that channel that @-mentions the agent, e.g. `@Claude Code (VPS) hi` (produces a correctly-tagged `["p", ]` kind:9 event).
3. Observe the harness logs (`RUST_LOG=buzz_acp=trace`):
- `agent_claimed … affinity_hit=…`
- `dispatch_pending dispatched=1 …`
- one or more `idle clock reset: tool call started` (the agent is actively doing work)
- `agent_returned agent=0 outcome="ok"`
4. Query the relay for all events published by the agent's pubkey during the turn.
## Expected behavior
A `kind:9` event with the agent's textual reply, tagged `["h", ]` (and a reply/thread tag if applicable), appears in the channel.
## Actual behavior
Only these events appear for the turn, in this order:
```
kind:7 content="👀" (tag: e=)
kind:7 content="💬" (tag: e=)
... (turn runs, tool calls happen, outcome="ok") ...
kind:5 (deletes the 👀 reaction)
kind:5 (deletes the 💬 reaction)
```
No `kind:9` reply is ever published. No warning/error is logged at `trace` level in the harness for this turn (contrast: in a separate test with a Python-based ACP bridge on the same relay, a failed turn correctly surfaced a `kind:9` error message — "⚠️ I couldn't process the last request … (Agent reported error (code -32603): Internal error)" — so the "publish an error/result back to the channel" path clearly exists and works for that harness command; it's specifically not firing here for `claude-agent-acp`).
## Notes / things already ruled out
- Not a relay/auth/membership issue — the agent's own pubkey is a confirmed relay member, `agent owner:` resolves correctly, `discovered N channel(s)` and `subscribed to channel …` both succeed.
- Not a mention/p-tag issue — the inbound message is correctly tagged and the turn is claimed and dispatched.
- Not the `steer` mid-turn-cancel fallback — switching `--multiple-event-handling` to `queue` (no code change in the delivery path per `--help`) produces the identical failure.
- The agent subprocess is clearly doing real work (multiple `tool call started` idle-clock resets per turn) and the harness considers the turn successful (`outcome="ok"`), so this looks like the final-message extraction/publish step specifically failing to fire (or firing but publishing something that never reaches the relay) for the `claude-agent-acp` ACP integration.
## What would help debug further
Raw stdout/stderr of the `claude-agent-acp` subprocess (or `RUST_LOG` coverage of the ACP JSON-RPC `session/update` → publish translation) for one full turn, to see whether the agent never emits a final `agent_message_chunk`, or whether it does and the harness drops it before publishing.
Contributor guide
Research direction
Start with RUST_LOG=buzz_acp=trace and capture raw stdout/stderr from claude-agent-acp for one complete turn. Inspect the ACP JSON-RPC session/update to publish translation, especially whether a final agent_message_chunk is emitted or dropped before relay publication. Done means a successful turn publishes a kind:9 reply with the channel tag while the temporary reactions are cleaned up.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- node.js, rust
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100