Skip to content

fix(desktop): include relay agents in DM activity surfaces - #3

Open
carimura wants to merge 1 commit into
mainfrom
fix/dm-relay-agent-activity
Open

fix(desktop): include relay agents in DM activity surfaces#3
carimura wants to merge 1 commit into
mainfrom
fix/dm-relay-agent-activity

Conversation

@carimura

Copy link
Copy Markdown
Owner

Summary

BYO relay agents show a live tool-call activity feed in stream channels but only a bare "agent is typing..." row in DMs, even though their observer frames (kind:24200) arrive and decrypt fine — the DM session panel proves it by showing the full transcript.

Root cause: getChannelAgentSessionAgents excludes relay-discovered agents from every DM they participate in. A relay agent's declared channel scope is built from its bot-role channel memberships (kind:39002), and a DM roster can never carry the bot role — the relay hardcodes every DM participant to the plain member role at creation (create_dm in crates/buzz-db/src/dm.rs), and add_member's role-change guard requires an elevated actor, but all DM members are plain members. So the declared-channel check can never match a DM, and the membership fallback only applies to agents with no declared scope at all.

The one exclusion produces the broken UX twice:

  1. BotActivityBar renders nothing when the working agent is missing from its channel-scoped agents list, even though the unified working signal knows the agent is mid-turn.
  2. useChannelActivityTyping uses the same filtered list to split typing events into bot vs. human, so the agent's kind:20002 typing events are classified as human typing and rendered by the plain typing row — literally "agent is typing...".

Desktop-managed agents are unaffected (their branch already checks membership), which made BYO relay agents second-class in DMs only.

Fix

In DM channels, relay agents now fall back to DM membership, with the channel's participant roster covering the window before the members query resolves. Stream and forum scoping is unchanged. One change fixes both symptoms because both surfaces consume the same function.

Testing

  • New useChannelAgentSessions.test.mjs: 6 tests pinning room scoping (unchanged), DM inclusion via members and via the participant-roster fallback, non-participant exclusion, and loaded-members authority over stale participants. All pass.
  • Full desktop unit suite: 5076/5076 pass.
  • tsc --noEmit clean.

Related (upstream)

Same "relay agents are second-class on some desktop surfaces" family as block#5250 (forum threads have no typing/observer wiring at all) and block#4776 (mention picker drops relay-directory agents), but a distinct mechanism. Not yet filed upstream — this PR is fork-only for now.

🤖 Generated with Claude Code

https://claude.ai/code/session_01QBPvBmgHKc5QpHPKCHhkRN

A relay-discovered agent's declared channel scope is built from its
bot-role channel memberships (kind:39002), and a DM roster can never
carry the bot role: the relay hardcodes every DM participant to the
plain member role at creation, and no DM member is elevated enough to
change it. getChannelAgentSessionAgents therefore excluded relay agents
from every DM they participate in — the declared-channel check can
never match a DM and the membership fallback only applies to agents
with no declared scope.

The exclusion hid live agent activity twice over in DMs: the composer
activity bar renders nothing when the working agent is missing from its
channel-scoped agents list, and useChannelActivityTyping classifies the
agent's kind:20002 typing events as human typing, so a DM shows
"agent is typing..." while the same agent's turn renders the full live
activity feed in a stream channel. Managed agents were unaffected (their
branch already checks membership), which made BYO relay agents
second-class in DMs only.

In DM channels, relay agents now fall back to DM membership, with the
channel's participant roster covering the window before the members
query resolves. Stream and forum scoping is unchanged.

Testing: new useChannelAgentSessions.test.mjs covers room scoping
(unchanged), DM inclusion via members and via the participant fallback,
and non-participant exclusion. Full desktop suite passes (5076/5076)
and tsc --noEmit is clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QBPvBmgHKc5QpHPKCHhkRN
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant