From 738ed005b691ce804893ad28753eb9aeb1dce2ff Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Thu, 14 May 2026 09:39:55 -0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=8F=B7=EF=B8=8F=20feat:=20Hide=20Model=20?= =?UTF-8?q?Spec=20Badge=20Rows=20(#13124)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: hide model spec badge row * chore: import order * feat: hide model spec badge row --- client/src/components/Chat/Input/ChatForm.tsx | 16 +++++++++++++--- librechat.example.yaml | 1 + .../data-provider/specs/config-schemas.spec.ts | 4 ++++ packages/data-provider/src/models.ts | 3 +++ 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/client/src/components/Chat/Input/ChatForm.tsx b/client/src/components/Chat/Input/ChatForm.tsx index a4f4f062f5..884a9251c4 100644 --- a/client/src/components/Chat/Input/ChatForm.tsx +++ b/client/src/components/Chat/Input/ChatForm.tsx @@ -21,12 +21,13 @@ import { useSubmitMessage, useFocusChatEffect, } from '~/hooks'; +import PendingManualSkillsChips from './PendingManualSkillsChips'; +import { cn, getModelSpec, removeFocusRings } from '~/utils'; +import { useGetStartupConfig } from '~/data-provider'; import { mainTextareaId, BadgeItem } from '~/common'; import AttachFileChat from './Files/AttachFileChat'; import FileFormChat from './Files/FileFormChat'; -import { cn, removeFocusRings } from '~/utils'; import TextareaHeader from './TextareaHeader'; -import PendingManualSkillsChips from './PendingManualSkillsChips'; import SkillsCommand from './SkillsCommand'; import PromptsCommand from './PromptsCommand'; import AudioRecorder from './AudioRecorder'; @@ -96,11 +97,17 @@ const ChatForm = memo(function ChatForm({ setConversation: setAddedConvo, } = useAddedChatContext(); const assistantMap = useAssistantsMapContext(); + const { data: startupConfig } = useGetStartupConfig(); const endpoint = useMemo( () => conversation?.endpointType ?? conversation?.endpoint, [conversation?.endpointType, conversation?.endpoint], ); + const modelSpec = useMemo( + () => getModelSpec({ specName: conversation?.spec, startupConfig }), + [conversation?.spec, startupConfig], + ); + const hideBadgeRow = modelSpec?.hideBadgeRow === true; const conversationId = useMemo( () => conversation?.conversationId ?? Constants.NEW_CONVO, [conversation?.conversationId], @@ -355,7 +362,10 @@ const ChatForm = memo(function ChatForm({ { { name: 'spec-1', label: 'Spec 1', + hideBadgeRow: true, preset: { endpoint: EModelEndpoint.openAI }, }, ], }); expect(result.success).toBe(true); + if (result.success) { + expect(result.data.list[0].hideBadgeRow).toBe(true); + } }); it('still rejects null list', () => { diff --git a/packages/data-provider/src/models.ts b/packages/data-provider/src/models.ts index 6be55effde..85f455fe17 100644 --- a/packages/data-provider/src/models.ts +++ b/packages/data-provider/src/models.ts @@ -32,6 +32,8 @@ export type TModelSpec = { showIconInHeader?: boolean; iconURL?: string | EModelEndpoint; // Allow using project-included icons authType?: AuthType; + /** Hide the chat input tool badge row while this model spec is active. */ + hideBadgeRow?: boolean; webSearch?: boolean; fileSearch?: boolean; executeCode?: boolean; @@ -52,6 +54,7 @@ export const tModelSpecSchema = z.object({ showIconInHeader: z.boolean().optional(), iconURL: z.union([z.string(), eModelEndpointSchema]).optional(), authType: authTypeSchema.optional(), + hideBadgeRow: z.boolean().optional(), webSearch: z.boolean().optional(), fileSearch: z.boolean().optional(), executeCode: z.boolean().optional(),