Skip to content

show owner badges for duplicate-named agents#1469

Draft
tellaho wants to merge 2 commits into
mainfrom
tho/duplicate-agent-name-avatars
Draft

show owner badges for duplicate-named agents#1469
tellaho wants to merge 2 commits into
mainfrom
tho/duplicate-agent-name-avatars

Conversation

@tellaho

@tellaho tellaho commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

Category: new-feature
User Impact: When multiple agents in a room share the same name, users can tell them apart by the owning user's avatar shown inline next to the agent name.
Problem: Duplicate-named agents currently appear identical in the message timeline, which makes it hard to know which human owns or configured each agent. The first implementation reserved the inline badge space but could render a blank fallback during cold loads.
Solution: Detect duplicate agent names within the room, attach the agent owner's profile to those timeline messages, and render a 16px owner badge between the agent name and timestamp without increasing row height. The owner popover label now reads Username's {agentname}., and avatar-less owners paint initials immediately instead of showing an empty fallback window.

File changes

desktop/playwright.config.ts
Adds the duplicate-agent avatar smoke spec to the smoke project so the user-facing timeline behavior runs in CI.

desktop/src/features/channels/ui/ChannelScreen.tsx
Fetches second-level agent owner profiles and merges them into the timeline profile lookup so owner badges have display names and avatars even when owners did not author messages in the room.

desktop/src/features/messages/lib/formatTimelineMessages.ts
Detects duplicate agent display names among room members and annotates only those agent messages with owner profile data for rendering.

desktop/src/features/messages/lib/formatTimelineMessages.test.mjs
Adds unit coverage for duplicate-name detection, unique-agent omission, human-author omission, missing owner handling, unknown owner fallback, and case-insensitive matching.

desktop/src/features/messages/types.ts
Adds agentOwner metadata to timeline messages for duplicate-agent disambiguation.

desktop/src/features/messages/ui/MessageRow.tsx
Renders the inline owner avatar between the agent name and timestamp, keeps it within the row line box, and passes the disambiguated popover label.

desktop/src/features/profile/hooks.ts
Adds a helper query for fetching profiles referenced by agent ownerPubkey fields.

desktop/src/features/profile/ui/UserProfilePopover.tsx
Allows the popover header display name to be overridden for the Username's {agentname}. label.

desktop/src/shared/ui/UserAvatar.tsx
Adds the 16px 2xs avatar size and renders initials immediately when there is no image source, avoiding an empty fallback window.

desktop/tests/e2e/duplicate-agent-avatars.spec.ts
Adds smoke coverage for two same-named agents and one unique control: loaded owner image, initials fallback, no badge for the unique agent, unchanged row height, and the requested popover copy.

Reproduction Steps

  1. Open a room with two agents that share the same displayed name and a third uniquely named agent.
  2. Confirm the duplicate-named agents show a small owner badge between the agent name and timestamp.
  3. Confirm one owner badge can render an avatar image and another can render initials when no avatar URL exists.
  4. Confirm the uniquely named agent has no inline owner badge.
  5. Hover a duplicate-named agent and confirm the balloon reads Username's {agentname}..
  6. Compare duplicate and unique rows and confirm the inline badge does not increase row height.

Screenshots/Demos

Timeline — Scout A shows alice's teal avatar image inline, Scout B shows bob's B initials, and Ranger shows no badge. Row heights match.

image

Balloon — duplicate-agent popover reads alice's Scout..

image

Validation

  • pnpm --dir desktop check
  • pnpm --dir desktop typecheck
  • pnpm --dir desktop test
  • pnpm --dir desktop build
  • pnpm --dir desktop exec playwright test duplicate-agent-avatars --project=smoke
  • Marge live-build gate on the feature branch before rebase: biome check, typecheck, 1481 unit tests, build, and duplicate-agent e2e cold 3/3 all green. I rebased onto latest origin/main before opening this draft PR and reran the focused validation above.

npub1223z34hd7vtwc6qj4s7flsxkj644nlre2nthu7lrrmkumhu3xddsrx9r6w and others added 2 commits July 2, 2026 10:28
When a room has more than one agent with the same displayed name,
render the agent owner's 16px avatar between the username and the
timestamp (zero row-height change), and label the profile balloon
"Username's {agentname}." so humans can tell which clone is which.

- formatTimelineMessages: duplicate-name detection from channel
  members (agents only, case-insensitive); attaches agentOwner only
  when disambiguation is needed
- profile/hooks: useAgentOwnerProfilesQuery batch-fetches NIP-OA
  owner pubkeys; ChannelScreen merges them into the profile lookup
- MessageRow: inline owner avatar with tooltip; popover gets
  displayNameOverride; memo comparator extended for agentOwner
- UserAvatar: new 2xs (16px) size
- tests: 6 formatter unit tests + e2e spec seeding two same-named
  agents (asserts avatar presence/absence, balloon text, row height)

Co-authored-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
Radix AvatarFallback's delayMs exists to avoid an initials flash while
an avatar image loads. With no image src there is nothing to wait for,
yet the 200ms delay still applied — so avatar-less owners painted a
blank 16px box on cold renders (caught in live-build review). Only
apply the delay when an image src is present.

Tighten the e2e so it can no longer pass on an empty wrapper: seed one
owner with a hermetic data-URL avatar and one without, assert a fully
loaded <img> (naturalWidth > 0) for the former and visible initials
text for the latter, and give the second-level owner-profile fetch
generous timeouts to kill the cold-run race. 18 consecutive runs green
including cold server starts.

Co-authored-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
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