fix(FN-1992): show resolved agent names in chat avatars

- Resolve assistant avatar labels from the active session agent map with fallback handling
- Keep the built-in KB agent label as Fusion and fall back to a truncated agent ID when needed
- Apply resolved labels to both stored assistant messages and streaming assistant avatars
- Add ChatView tests for resolved labels, KB-agent fallback, and streaming avatar rendering
- Document the @fusion/engine prebuild prerequisite in .fusion/memory.md
This commit is contained in:
Fusion
2026-04-17 03:08:46 -07:00
committed by gsxdsm
parent 9c02bc3d33
commit c91ff5fbf6
4 changed files with 71 additions and 8 deletions

View File

@@ -412,6 +412,12 @@ export function ChatView({ projectId, addToast }: ChatViewProps) {
);
};
const agentName =
agentsMap.get(activeSession?.agentId ?? "")?.name ||
(activeSession?.agentId === KB_AGENT_ID
? "Fusion"
: (activeSession?.agentId?.slice(0, 30) ?? "Fusion"));
return (
<div className="chat-view">
{/* Sidebar */}
@@ -566,7 +572,7 @@ export function ChatView({ projectId, addToast }: ChatViewProps) {
{message.role === "assistant" && (
<div className="chat-message-avatar">
<Bot size={14} />
<span>Fusion</span>
<span>{agentName}</span>
{activeSession && (() => {
const modelTag = formatModelTag(activeSession.modelProvider, activeSession.modelId);
return modelTag ? <span className="chat-model-tag">{modelTag}</span> : null;
@@ -587,7 +593,7 @@ export function ChatView({ projectId, addToast }: ChatViewProps) {
<div className="chat-message chat-message--assistant chat-message--streaming">
<div className="chat-message-avatar">
<Bot size={14} />
<span>Fusion</span>
<span>{agentName}</span>
{activeSession && (() => {
const modelTag = formatModelTag(activeSession.modelProvider, activeSession.modelId);
return modelTag ? <span className="chat-model-tag">{modelTag}</span> : null;

View File

@@ -181,8 +181,8 @@ describe("ChatView", () => {
// Dialog should be open - check for dialog content
const dialog = document.querySelector(".chat-new-dialog");
expect(dialog).toBeInTheDocument();
// Should show Agent label
expect(within(dialog!).getByText("Agent")).toBeInTheDocument();
// Should show Agent label (current copy: "Agent (optional)")
expect(within(dialog!).getByText(/Agent(?:\s*\(optional\))?/i)).toBeInTheDocument();
});
it("creates session without model selection (uses default)", async () => {
@@ -305,6 +305,60 @@ describe("ChatView", () => {
expect(screen.getByText("Hi there!")).toBeInTheDocument();
});
it("shows resolved agent name in assistant message avatar", async () => {
setupMockChat({
activeSession: { id: "session-001", agentId: "agent-001", status: "active", title: "Agent Chat", updatedAt: "2026-04-08T00:00:00.000Z" },
messages: [
{ id: "msg-001", sessionId: "session-001", role: "assistant", content: "Hello from Alpha", createdAt: "2026-04-08T00:00:00.000Z" },
],
});
render(<ChatView projectId="proj-123" addToast={vi.fn()} />);
const avatar = document.querySelector(".chat-message-avatar");
expect(avatar).toBeInTheDocument();
await waitFor(() => {
expect(within(avatar!).getByText("Alpha")).toBeInTheDocument();
});
expect(within(avatar!).queryByText("Fusion")).not.toBeInTheDocument();
});
it("shows Fusion in assistant message avatar for kb agent sessions", () => {
setupMockChat({
activeSession: { id: "session-001", agentId: "__kb_agent__", status: "active", title: "Fusion Chat", updatedAt: "2026-04-08T00:00:00.000Z" },
messages: [
{ id: "msg-001", sessionId: "session-001", role: "assistant", content: "Built-in assistant response", createdAt: "2026-04-08T00:00:00.000Z" },
],
});
render(<ChatView projectId="proj-123" addToast={vi.fn()} />);
const avatar = document.querySelector(".chat-message-avatar");
expect(avatar).toBeInTheDocument();
expect(within(avatar!).getByText("Fusion")).toBeInTheDocument();
});
it("shows resolved agent name in streaming assistant avatar", async () => {
setupMockChat({
activeSession: { id: "session-001", agentId: "agent-001", status: "active", title: "Agent Chat", updatedAt: "2026-04-08T00:00:00.000Z" },
messages: [
{ id: "msg-001", sessionId: "session-001", role: "user", content: "Think", createdAt: "2026-04-08T00:00:00.000Z" },
],
isStreaming: true,
streamingText: "Thinking...",
});
render(<ChatView projectId="proj-123" addToast={vi.fn()} />);
const avatar = document.querySelector(".chat-message--streaming .chat-message-avatar");
expect(avatar).toBeInTheDocument();
await waitFor(() => {
expect(within(avatar!).getByText("Alpha")).toBeInTheDocument();
});
});
it("sends message on Enter key", async () => {
const sendMessage = vi.fn();
setupMockChat({