diff --git a/ui/src/e2e/session-ownership.e2e.test.ts b/ui/src/e2e/session-ownership.e2e.test.ts index a8bbd1064437..c7a1ce38142c 100644 --- a/ui/src/e2e/session-ownership.e2e.test.ts +++ b/ui/src/e2e/session-ownership.e2e.test.ts @@ -493,9 +493,9 @@ suite.define(() => { label: `Member ${index + 1}`, })), ]; - const channelIdentities = [ - { type: "human" as const, id: "channel:chn_design", label: "Design" }, - { type: "human" as const, id: "discord:channel:operations", label: "Operations" }, + const nonHumanIdentities = [ + { type: "agent" as const, id: "agent-design", label: "Design" }, + { type: "system" as const, id: "system-operations", label: "Operations" }, ]; const gateway = await installMockGateway(currentPage, { sessionKey: "agent:main:ada", @@ -544,7 +544,7 @@ suite.define(() => { "session.members.list": { sessionKey: "agent:main:ada", members: [{ identityId: longMemberId, addedBy: "profile-ada", addedAt: 1 }], - identities: [...humanIdentities, ...channelIdentities], + identities: [...humanIdentities, ...nonHumanIdentities], role: "owner", allowedVisibilities: ["shared", "read-only", "suggest", "draft"], }, @@ -677,7 +677,9 @@ suite.define(() => { await expectBrowser( dropdown.locator(".chat-pane__sharing-member openclaw-session-owner-chip"), ).toHaveCount(30); - await expectBrowser(dropdown.locator(".chat-pane__sharing-channel-icon")).toHaveCount(2); + // Agent and system identities render the non-human icon from identity.type, + // not from an ID-string heuristic; owner-chip presentation is human-only. + await expectBrowser(dropdown.locator(".chat-pane__sharing-member-icon > svg")).toHaveCount(2); expect( await longNameItem.locator(".chat-pane__sharing-member-label").getAttribute("title"), ).toBe(longMemberLabel); diff --git a/ui/src/pages/chat/components/chat-session-sharing.test.ts b/ui/src/pages/chat/components/chat-session-sharing.test.ts index eecc115a18ec..fbcf3154a4e7 100644 --- a/ui/src/pages/chat/components/chat-session-sharing.test.ts +++ b/ui/src/pages/chat/components/chat-session-sharing.test.ts @@ -71,7 +71,7 @@ describe("chat session sharing menu", () => { expect(onMemberChange).toHaveBeenCalledWith("alice", true); }); - it("distinguishes people from channel-backed members", () => { + it("renders member presentation from identity.type, not from ID spelling", () => { const root = mount( renderChatSessionSharing({ session: { @@ -88,8 +88,12 @@ describe("chat session sharing menu", () => { members: [], identities: [ { type: "human", id: "profile-vyctor", label: "Vyctor Brzezowski" }, + // Human identity IDs are opaque (e.g. an inbound SenderId) and + // can contain "channel:" as a substring; the recorded type, + // not the ID string, must drive presentation. { type: "human", id: "channel:chn_design", label: "Design" }, - { type: "human", id: "discord:channel:operations", label: "Operations" }, + { type: "agent", id: "discord:channel:operations", label: "Operations" }, + { type: "system", id: "channel:audit", label: "Audit" }, ], role: "owner", allowedVisibilities: ["shared"], @@ -101,16 +105,21 @@ describe("chat session sharing menu", () => { }), ); - const human = root.querySelector('wa-dropdown-item[value="member:profile-vyctor"]'); - const channels = [ + const humans = [ + root.querySelector('wa-dropdown-item[value="member:profile-vyctor"]'), root.querySelector('wa-dropdown-item[value="member:channel:chn_design"]'), + ]; + const nonHumans = [ root.querySelector('wa-dropdown-item[value="member:discord:channel:operations"]'), + root.querySelector('wa-dropdown-item[value="member:channel:audit"]'), ]; - expect(human?.querySelector("openclaw-session-owner-chip")).not.toBeNull(); - for (const channel of channels) { - expect(channel?.querySelector("openclaw-session-owner-chip")).toBeNull(); - expect(channel?.querySelector(".chat-pane__sharing-channel-icon svg")).not.toBeNull(); + for (const human of humans) { + expect(human?.querySelector("openclaw-session-owner-chip")).not.toBeNull(); + } + for (const nonHuman of nonHumans) { + expect(nonHuman?.querySelector("openclaw-session-owner-chip")).toBeNull(); + expect(nonHuman?.querySelector(".chat-pane__sharing-member-icon svg")).not.toBeNull(); } }); diff --git a/ui/src/pages/chat/components/chat-session-sharing.ts b/ui/src/pages/chat/components/chat-session-sharing.ts index ccada5f651d8..e5893891a727 100644 --- a/ui/src/pages/chat/components/chat-session-sharing.ts +++ b/ui/src/pages/chat/components/chat-session-sharing.ts @@ -43,10 +43,6 @@ function sharingIcon(visibility: SessionVisibility): TemplateResult { return visibility === "shared" ? icons.users : icons.lock; } -function isChannelIdentity(identityId: string): boolean { - return identityId.startsWith("channel:") || identityId.includes(":channel:"); -} - export function canManageChatSessionSharing( session: Pick, ): boolean { @@ -162,7 +158,6 @@ export function renderChatSessionSharing(props: ChatSessionSharingProps) { const disabledReason = members.has(identity.id) ? props.memberRemoveDisabledReason : props.memberAddDisabledReason; - const channelIdentity = isChannelIdentity(identity.id); return html` -