diff --git a/client/src/components/Agents/tests/Accessibility.spec.tsx b/client/src/components/Agents/tests/Accessibility.spec.tsx
index 8d9a02a982..a06c559067 100644
--- a/client/src/components/Agents/tests/Accessibility.spec.tsx
+++ b/client/src/components/Agents/tests/Accessibility.spec.tsx
@@ -126,7 +126,7 @@ jest.mock('~/data-provider/Agents', () => ({
// Mock utility functions
jest.mock('~/utils/agents', () => ({
- renderAgentAvatar: jest.fn(() =>
),
+ AgentAvatar: jest.fn(() =>
),
getContactDisplayName: jest.fn((agent) => agent.authorName),
}));
diff --git a/client/src/components/Agents/tests/AgentDetail.spec.tsx b/client/src/components/Agents/tests/AgentDetail.spec.tsx
index 0a1afffea7..5ce1418438 100644
--- a/client/src/components/Agents/tests/AgentDetail.spec.tsx
+++ b/client/src/components/Agents/tests/AgentDetail.spec.tsx
@@ -46,9 +46,7 @@ jest.mock('@librechat/client', () => ({
}));
jest.mock('~/utils/agents', () => ({
- renderAgentAvatar: jest.fn((agent, options) => (
-
- )),
+ AgentAvatar: jest.fn(({ agent, size }) =>
),
}));
jest.mock('~/Providers', () => ({
diff --git a/client/src/components/Endpoints/EndpointIcon.tsx b/client/src/components/Endpoints/EndpointIcon.tsx
index 9e4f2bb6a7..ba2cbf6993 100644
--- a/client/src/components/Endpoints/EndpointIcon.tsx
+++ b/client/src/components/Endpoints/EndpointIcon.tsx
@@ -41,7 +41,9 @@ export default function EndpointIcon({
const assistantName = assistant && (assistant.name ?? '');
const agent =
- endpoint === EModelEndpoint.agents ? agentsMap?.[conversation?.agent_id ?? ''] : null;
+ endpoint === EModelEndpoint.agents && conversation?.agent_id
+ ? agentsMap?.[conversation.agent_id]
+ : null;
const agentAvatar = getAgentAvatarUrl(agent) ?? '';
const iconURL = assistantAvatar || agentAvatar || convoIconURL;
diff --git a/client/src/components/Nav/Favorites/FavoriteItem.tsx b/client/src/components/Nav/Favorites/FavoriteItem.tsx
index e758b8cd5d..3c9b67435b 100644
--- a/client/src/components/Nav/Favorites/FavoriteItem.tsx
+++ b/client/src/components/Nav/Favorites/FavoriteItem.tsx
@@ -7,7 +7,7 @@ import type { FavoriteModel } from '~/store/favorites';
import type t from 'librechat-data-provider';
import MinimalIcon from '~/components/Endpoints/MinimalIcon';
import { useFavorites, useLocalize } from '~/hooks';
-import { renderAgentAvatar, cn } from '~/utils';
+import { AgentAvatar, cn } from '~/utils';
type Kwargs = {
model?: string;
@@ -73,7 +73,7 @@ export default function FavoriteItem({
const renderIcon = () => {
if (type === 'agent') {
- return renderAgentAvatar(item as t.Agent, { size: 'icon', className: 'mr-2' });
+ return
;
}
const model = item as FavoriteModel;
return (
diff --git a/client/src/utils/__tests__/agents.spec.tsx b/client/src/utils/__tests__/agents.spec.tsx
index dee58cdf84..30590863fb 100644
--- a/client/src/utils/__tests__/agents.spec.tsx
+++ b/client/src/utils/__tests__/agents.spec.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
-import { getAgentAvatarUrl, renderAgentAvatar, getContactDisplayName } from '../agents';
+import { getAgentAvatarUrl, AgentAvatar, getContactDisplayName } from '../agents';
import type t from 'librechat-data-provider';
// Mock the Feather icon from lucide-react
@@ -61,7 +61,7 @@ describe('Agent Utilities', () => {
});
});
- describe('renderAgentAvatar', () => {
+ describe('AgentAvatar', () => {
it('should render image when avatar URL exists', () => {
const agent = {
id: '1',
@@ -69,7 +69,7 @@ describe('Agent Utilities', () => {
avatar: '/test-avatar.png',
} as unknown as t.Agent;
- render(
{renderAgentAvatar(agent)}
);
+ render(
);
const img = screen.getByAltText('Test Agent avatar');
expect(img).toBeInTheDocument();
@@ -83,7 +83,7 @@ describe('Agent Utilities', () => {
name: 'Test Agent',
} as t.Agent;
- render(
{renderAgentAvatar(agent)}
);
+ render(
);
const featherIcon = screen.getByTestId('feather-icon');
expect(featherIcon).toBeInTheDocument();
@@ -97,13 +97,13 @@ describe('Agent Utilities', () => {
avatar: '/test-avatar.png',
} as unknown as t.Agent;
- const { rerender } = render(
{renderAgentAvatar(agent, { size: 'sm' })}
);
+ const { rerender } = render(
);
expect(screen.getByAltText('Test Agent avatar')).toHaveClass('h-12', 'w-12');
- rerender(
{renderAgentAvatar(agent, { size: 'lg' })}
);
+ rerender(
);
expect(screen.getByAltText('Test Agent avatar')).toHaveClass('h-20', 'w-20');
- rerender(
{renderAgentAvatar(agent, { size: 'xl' })}
);
+ rerender(
);
expect(screen.getByAltText('Test Agent avatar')).toHaveClass('h-24', 'w-24');
});
@@ -114,7 +114,7 @@ describe('Agent Utilities', () => {
avatar: '/test-avatar.png',
} as unknown as t.Agent;
- render(
{renderAgentAvatar(agent, { className: 'custom-class' })}
);
+ render(
);
const container = screen.getByAltText('Test Agent avatar').parentElement;
expect(container).toHaveClass('custom-class');
@@ -127,10 +127,10 @@ describe('Agent Utilities', () => {
avatar: '/test-avatar.png',
} as unknown as t.Agent;
- const { rerender } = render(
{renderAgentAvatar(agent, { showBorder: true })}
);
+ const { rerender } = render(
);
expect(screen.getByAltText('Test Agent avatar')).toHaveClass('border-1');
- rerender(
{renderAgentAvatar(agent, { showBorder: false })}
);
+ rerender(
);
expect(screen.getByAltText('Test Agent avatar')).not.toHaveClass('border-1');
});
});
diff --git a/client/src/utils/agents.tsx b/client/src/utils/agents.tsx
index a65577d1f3..1951f7549c 100644
--- a/client/src/utils/agents.tsx
+++ b/client/src/utils/agents.tsx
@@ -85,16 +85,17 @@ const LazyAgentAvatar = ({
* Renders an agent avatar with fallback to Bot icon
* Consistent across all agent displays
*/
-export const renderAgentAvatar = (
- agent: t.Agent | null | undefined,
- options: {
- size?: 'icon' | 'sm' | 'md' | 'lg' | 'xl';
- className?: string;
- showBorder?: boolean;
- } = {},
-): React.ReactElement => {
- const { size = 'md', className = '', showBorder = true } = options;
-
+export const AgentAvatar = ({
+ agent,
+ size = 'md',
+ className = '',
+ showBorder = true,
+}: {
+ agent: t.Agent | null | undefined;
+ size?: 'icon' | 'sm' | 'md' | 'lg' | 'xl';
+ className?: string;
+ showBorder?: boolean;
+}) => {
const avatarUrl = getAgentAvatarUrl(agent);
// Size mappings for responsive design
From 40871fa670a0d6cb2507d419146e0dade46193d4 Mon Sep 17 00:00:00 2001
From: Marco Beretta <81851188+berry-13@users.noreply.github.com>
Date: Sat, 20 Dec 2025 03:23:55 +0100
Subject: [PATCH 5/6] feat: Replace renderAgentAvatar function with AgentAvatar
component for improved avatar rendering
---
client/src/components/Agents/AgentDetailContent.tsx | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/client/src/components/Agents/AgentDetailContent.tsx b/client/src/components/Agents/AgentDetailContent.tsx
index 1e06d8230f..d76524c4ae 100644
--- a/client/src/components/Agents/AgentDetailContent.tsx
+++ b/client/src/components/Agents/AgentDetailContent.tsx
@@ -12,7 +12,7 @@ import {
} from 'librechat-data-provider';
import type t from 'librechat-data-provider';
import { useLocalize, useDefaultConvo, useFavorites } from '~/hooks';
-import { renderAgentAvatar, clearMessagesCache } from '~/utils';
+import { AgentAvatar, clearMessagesCache } from '~/utils';
import { useChatContext } from '~/Providers';
interface SupportContact {
@@ -140,7 +140,9 @@ const AgentDetailContent: React.FC
= ({ agent }) => {
return (
{/* Agent avatar */}
- {renderAgentAvatar(agent, { size: 'xl' })}
+
{/* Agent name */}
From b40123f6071551ba3fe531f6d965fcc9dcc7bf8f Mon Sep 17 00:00:00 2001
From: Marco Beretta <81851188+berry-13@users.noreply.github.com>
Date: Sat, 20 Dec 2025 12:28:16 +0100
Subject: [PATCH 6/6] feat: Replace loading spinner with Spinner component for
improved consistency
---
client/src/components/Conversations/Convo.tsx | 25 +++----------------
1 file changed, 3 insertions(+), 22 deletions(-)
diff --git a/client/src/components/Conversations/Convo.tsx b/client/src/components/Conversations/Convo.tsx
index c0cfcd601c..412cbeb3a2 100644
--- a/client/src/components/Conversations/Convo.tsx
+++ b/client/src/components/Conversations/Convo.tsx
@@ -2,11 +2,11 @@ import React, { useState, useEffect, useRef, useMemo } from 'react';
import { useRecoilValue } from 'recoil';
import { useParams } from 'react-router-dom';
import { Constants } from 'librechat-data-provider';
-import { useToastContext, useMediaQuery } from '@librechat/client';
+import { useToastContext, useMediaQuery, Spinner } from '@librechat/client';
import type { TConversation } from 'librechat-data-provider';
+import { useAgentsMapContext } from '~/Providers/AgentsMapContext';
import { useUpdateConversationMutation } from '~/data-provider';
import EndpointIcon from '~/components/Endpoints/EndpointIcon';
-import { useAgentsMapContext } from '~/Providers/AgentsMapContext';
import { useNavigateToConvo, useLocalize } from '~/hooks';
import { useGetEndpointsQuery } from '~/data-provider';
import { NotificationSeverity } from '~/common';
@@ -191,26 +191,7 @@ export default function Conversation({
localize={localize}
>
{isGenerating ? (
-
+
) : (