show owner badges for duplicate-named agents#1469
Draft
tellaho wants to merge 2 commits into
Draft
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
agentOwnermetadata 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
ownerPubkeyfields.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
2xsavatar 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
Username's {agentname}..Screenshots/Demos
Timeline — Scout A shows alice's teal avatar image inline, Scout B shows bob's
Binitials, and Ranger shows no badge. Row heights match.Balloon — duplicate-agent popover reads
alice's Scout..Validation
pnpm --dir desktop checkpnpm --dir desktop typecheckpnpm --dir desktop testpnpm --dir desktop buildpnpm --dir desktop exec playwright test duplicate-agent-avatars --project=smokeorigin/mainbefore opening this draft PR and reran the focused validation above.