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:
@@ -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;
|
||||
|
||||
@@ -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({
|
||||
|
||||
Reference in New Issue
Block a user