You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
buzz-acp: SubscribeMode::All subscribes to every event kind — typing indicators (kind:20002) open agent turns and cancel pending wakeups #4949
Managed agent, backend: local, Claude runtime (claude-agent-acp 0.65.0)
BUZZ_ACP_SUBSCRIBE=all (set so the agent answers the owner without requiring a mention)
Observed
With subscribe=all, the agent's turns are repeatedly triggered by kind:20002 typing indicators (empty content, ephemeral):
Four separate turns in one session were opened by typing events — the user only started typing; the actual kind:9 message arrived mid-turn as a separate notification.
The harness passed the ephemeral event as the trigger and set it as the reply target (--reply-to <20002 event id>). Ephemeral events are not persisted, so replies would thread against a nonexistent root.
A pending scheduled wakeup (Claude Code ScheduleWakeup, due in 109s) was at risk of cancellation when a typing indicator opened a turn: pending wakeups are cancelled on incoming user activity by design, but here pressing a key — without ever sending a message — was enough to count as user activity.
SubscribeMode::Mentions defaults to an explicit kind list: [KIND_STREAM_MESSAGE (9), KIND_WORKFLOW_APPROVAL_REQUESTED (46010), KIND_STREAM_REMINDER (40007)].
SubscribeMode::All builds ChannelFilter { kinds: config.kinds_override.clone(), require_mention: false } — when BUZZ_ACP_KINDS is not set, kinds is None, which the relay subscription treats as wildcard (all kinds).
So "all" silently changes meaning from "all messages (no mention required)" to "all event kinds", pulling in ephemeral kinds (typing 20002, etc.) as turn triggers.
Expected
All should mean "the same message kinds as Mentions, without the mention requirement". Suggested fix:
Operator here with a 24h measured-cost datapoint that confirms and quantifies the impact section. This run used a different runtime stack than the OP (Hermes runtime on MiniMax-M3 via buzz-acp 0.5.23, BUZZ_ACP_SUBSCRIBE=all, default kinds override unset), so the wildcard behavior reproduces across runtimes, not just claude-agent-acp.
Measured cost (from session_model_usage in our agent's state.db)
Window 2026-09-22, 24h, one hive, one agent:
670 sessions started, 865 API calls. 654 of the 670 sessions had exactly 1 API call (pure typing-indicator bootstrap cycles: inbound kind:20002, session spawn, base prompt, canned "no actionable content" reply, teardown).
Totals for the day: 1,014,507 input tokens, 8,756,507 cache-read tokens, 83,556 output tokens.
Single-cycle cost is the input bill: one logged bootstrap call measured 73,404 tokens (msgs=2). That call is also where the day ended: the provider returned 429 Token Plan usage limit reached (2056), and the retry loop around it burned the rest of the plan's headroom.
2026-09-23 (partial window to ~07:03 UTC, after we started shutting things down): still 65 sessions / 119 calls / 104,120 input / 2,758,777 cache-read before we intervened.
Two things worth flagging for anyone prioritizing this:
The cache-read number is not savings here. Because every cycle is a fresh session (lazy pool child), the base prompt is re-read from cache once per cycle at best; 8.7M cache-read tokens/day is the loop charging the plan's cache budget continuously, and the 1M+ uncached input/day is on top of it.
The trigger cadence is not human typing. Our inbound firehose ran ~20 events/min sustained for hours with the same shape every time: kind:20002, content: "", tags: [["h", <channel>]]. Whatever the client-side keepalive is, subscribe=all turns it into a session bootstrap roughly every 3 seconds.
The BUZZ_ACP_KINDS=9,40007,46010 workaround from the OP held for us too, but it is discover-only: nothing in the docs or logs suggests "all" means "all event kinds", and the failure mode is invisible until the provider plan dies. A debug-level log line on wildcard subscriptions including ephemeral kinds (or an outright denylist for 20002 in the All default per the OP's suggested fix) would have saved us a plan a day.
Activity
fix(acp): stop SubscribeMode::All from subscribing to every event kind
fix(acp): stop SubscribeMode::All from subscribing to every event kind
fix(acp): stop SubscribeMode::All from subscribing to every event kind
fix(acp): stop SubscribeMode::All from subscribing to every event kind
fix(acp): stop SubscribeMode::All from subscribing to every event kind
fix(acp): stop SubscribeMode::All from subscribing to every event kind
fix(acp): stop SubscribeMode::All from subscribing to every event kind
fix(acp): stop SubscribeMode::All from subscribing to every event kind
fix(acp): stop SubscribeMode::All from subscribing to every event kind
fix(acp): stop SubscribeMode::All from subscribing to every event kind
fix(acp): stop SubscribeMode::All from subscribing to every event kind
fix(acp): stop SubscribeMode::All from subscribing to every event kind
fix(acp): stop SubscribeMode::All from subscribing to every event kind
fix(acp): stop SubscribeMode::All from subscribing to every event kind
fix(acp): stop SubscribeMode::All from subscribing to every event kind
fix(acp): stop SubscribeMode::All from subscribing to every event kind
fix(acp): stop SubscribeMode::All from subscribing to every event kind
fix(acp): stop SubscribeMode::All from subscribing to every event kind
fix(acp): stop SubscribeMode::All from subscribing to every event kind
fix(acp): stop SubscribeMode::All from subscribing to every event kind
fix(acp): stop SubscribeMode::All from subscribing to every event kind
fix(acp): stop SubscribeMode::All from subscribing to every event kind
fix(acp): stop SubscribeMode::All from subscribing to every event kind
fix(acp): stop SubscribeMode::All from subscribing to every event kind
fix(acp): stop SubscribeMode::All from subscribing to every event kind
dziduchm commentedon Sep 23, 2026
Operator here with a 24h measured-cost datapoint that confirms and quantifies the impact section. This run used a different runtime stack than the OP (Hermes runtime on MiniMax-M3 via buzz-acp 0.5.23,
BUZZ_ACP_SUBSCRIBE=all, default kinds override unset), so the wildcard behavior reproduces across runtimes, not just claude-agent-acp.Measured cost (from
session_model_usagein our agent's state.db)Window 2026-09-22, 24h, one hive, one agent:
429 Token Plan usage limit reached (2056), and the retry loop around it burned the rest of the plan's headroom.Two things worth flagging for anyone prioritizing this:
kind:20002, content: "", tags: [["h", <channel>]]. Whatever the client-side keepalive is, subscribe=all turns it into a session bootstrap roughly every 3 seconds.The
BUZZ_ACP_KINDS=9,40007,46010workaround from the OP held for us too, but it is discover-only: nothing in the docs or logs suggests "all" means "all event kinds", and the failure mode is invisible until the provider plan dies. A debug-level log line on wildcard subscriptions including ephemeral kinds (or an outright denylist for 20002 in theAlldefault per the OP's suggested fix) would have saved us a plan a day.fix(acp): stop SubscribeMode::All from subscribing to every event kind