diff --git a/ui/src/ui/views/chat.test.ts b/ui/src/ui/views/chat.test.ts index 2e04413d39a..341409a9bac 100644 --- a/ui/src/ui/views/chat.test.ts +++ b/ui/src/ui/views/chat.test.ts @@ -1,3 +1,5 @@ +/* @vitest-environment jsdom */ + import { render } from "lit"; import { describe, expect, it, vi } from "vitest"; import type { SessionsListResult } from "../types.ts"; @@ -54,6 +56,46 @@ function createProps(overrides: Partial = {}): ChatProps { } describe("chat view", () => { + it("uses the assistant avatar URL for the welcome state when the identity avatar is only initials", () => { + const container = document.createElement("div"); + render( + renderChat( + createProps({ + assistantName: "Assistant", + assistantAvatar: "A", + assistantAvatarUrl: "/avatar/main", + }), + ), + container, + ); + + const welcomeImage = container.querySelector(".agent-chat__welcome > img"); + expect(welcomeImage).not.toBeNull(); + expect(welcomeImage?.getAttribute("src")).toBe("/avatar/main"); + }); + + it("falls back to the bundled logo in the welcome state when the assistant avatar is not a URL", () => { + const container = document.createElement("div"); + render( + renderChat( + createProps({ + assistantName: "Assistant", + assistantAvatar: "A", + assistantAvatarUrl: null, + }), + ), + container, + ); + + const welcomeImage = container.querySelector(".agent-chat__welcome > img"); + const logoImage = container.querySelector( + ".agent-chat__welcome .agent-chat__avatar--logo img", + ); + expect(welcomeImage).toBeNull(); + expect(logoImage).not.toBeNull(); + expect(logoImage?.getAttribute("src")).toBe("favicon.svg"); + }); + it("renders compacting indicator as a badge", () => { const container = document.createElement("div"); render( diff --git a/ui/src/ui/views/chat.ts b/ui/src/ui/views/chat.ts index db0b924322d..36412b965a6 100644 --- a/ui/src/ui/views/chat.ts +++ b/ui/src/ui/views/chat.ts @@ -31,7 +31,7 @@ import { detectTextDirection } from "../text-direction.ts"; import type { GatewaySessionRow, SessionsListResult } from "../types.ts"; import type { ChatItem, MessageGroup } from "../types/chat-types.ts"; import type { ChatAttachment, ChatQueueItem } from "../ui-types.ts"; -import { agentLogoUrl } from "./agents-utils.ts"; +import { agentLogoUrl, resolveAgentAvatarUrl } from "./agents-utils.ts"; import { renderMarkdownSidebar } from "./markdown-sidebar.ts"; import "../components/resizable-divider.ts"; @@ -566,7 +566,12 @@ const WELCOME_SUGGESTIONS = [ function renderWelcomeState(props: ChatProps): TemplateResult { const name = props.assistantName || "Assistant"; - const avatar = props.assistantAvatar ?? props.assistantAvatarUrl; + const avatar = resolveAgentAvatarUrl({ + identity: { + avatar: props.assistantAvatar ?? undefined, + avatarUrl: props.assistantAvatarUrl ?? undefined, + }, + }); const logoUrl = agentLogoUrl(props.basePath ?? ""); return html` @@ -802,7 +807,13 @@ export function renderChat(props: ChatProps) { const showReasoning = props.showThinking && reasoningLevel !== "off"; const assistantIdentity = { name: props.assistantName, - avatar: props.assistantAvatar ?? props.assistantAvatarUrl ?? null, + avatar: + resolveAgentAvatarUrl({ + identity: { + avatar: props.assistantAvatar ?? undefined, + avatarUrl: props.assistantAvatarUrl ?? undefined, + }, + }) ?? null, }; const pinned = getPinnedMessages(props.sessionKey); const deleted = getDeletedMessages(props.sessionKey); diff --git a/vitest.config.ts b/vitest.config.ts index 658437187f5..f164a8e2af9 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -83,6 +83,7 @@ export default defineConfig({ "extensions/**/*.test.ts", "test/**/*.test.ts", "ui/src/ui/views/agents-utils.test.ts", + "ui/src/ui/views/chat.test.ts", "ui/src/ui/views/usage-render-details.test.ts", "ui/src/ui/controllers/agents.test.ts", "ui/src/ui/controllers/chat.test.ts",