From 182ee28286c400f2407c2ecbf05d4bdfdafeda3c Mon Sep 17 00:00:00 2001 From: Timo Wacke Date: Mon, 16 Mar 2026 21:53:53 +0100 Subject: [PATCH] feat: add acceptedFileMimetypes to model config Allow models to declare which file MIME types they accept (e.g. "application/pdf", "image/*") via a new `acceptedFileMimetypes` field. The frontend merges these with existing multimodal MIME types to determine which upload options to show. This enables per-model file type support without coupling to a specific provider's file handling implementation. Refs: #482, #609, #1505, #1652 Co-Authored-By: Claude Opus 4.6 --- src/lib/components/chat/ChatWindow.svelte | 3 ++- src/lib/server/api/types.ts | 1 + src/lib/server/models.ts | 2 ++ src/lib/types/Model.ts | 1 + src/routes/api/v2/models/+server.ts | 1 + 5 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/lib/components/chat/ChatWindow.svelte b/src/lib/components/chat/ChatWindow.svelte index 0756db53aca..74ccbccf74f 100644 --- a/src/lib/components/chat/ChatWindow.svelte +++ b/src/lib/components/chat/ChatWindow.svelte @@ -309,7 +309,7 @@ providerOverride && providerOverride !== "auto" && !currentModel.isRouter ); - // Always allow common text-like files; add images only when model is multimodal + // Always allow common text-like files; add images when multimodal; add declared file types import { TEXT_MIME_ALLOWLIST, IMAGE_MIME_ALLOWLIST_DEFAULT } from "$lib/constants/mime"; let activeMimeTypes = $derived( @@ -319,6 +319,7 @@ ...(modelIsMultimodal ? (currentModel.multimodalAcceptedMimetypes ?? [...IMAGE_MIME_ALLOWLIST_DEFAULT]) : []), + ...(currentModel.acceptedFileMimetypes ?? []), ]) ) ); diff --git a/src/lib/server/api/types.ts b/src/lib/server/api/types.ts index 6ac8bd9a65e..a48422ca043 100644 --- a/src/lib/server/api/types.ts +++ b/src/lib/server/api/types.ts @@ -16,6 +16,7 @@ export type GETModelsResponse = Array<{ preprompt?: string; multimodal: boolean; multimodalAcceptedMimetypes?: string[]; + acceptedFileMimetypes?: string[]; supportsTools?: boolean; unlisted: boolean; hasInferenceAPI: boolean; diff --git a/src/lib/server/models.ts b/src/lib/server/models.ts index 5459f6202cc..dd6bd0dffbc 100644 --- a/src/lib/server/models.ts +++ b/src/lib/server/models.ts @@ -56,6 +56,8 @@ const modelConfig = z.object({ .optional(), multimodal: z.boolean().default(false), multimodalAcceptedMimetypes: z.array(z.string()).optional(), + /** MIME types the model accepts as file attachments (e.g. ["application/pdf", "image/*"]) */ + acceptedFileMimetypes: z.array(z.string()).optional(), // Aggregated tool-calling capability across providers (HF router) supportsTools: z.boolean().default(false), unlisted: z.boolean().default(false), diff --git a/src/lib/types/Model.ts b/src/lib/types/Model.ts index 2c6711d5c08..24eb7431823 100644 --- a/src/lib/types/Model.ts +++ b/src/lib/types/Model.ts @@ -17,6 +17,7 @@ export type Model = Pick< | "preprompt" | "multimodal" | "multimodalAcceptedMimetypes" + | "acceptedFileMimetypes" | "unlisted" | "hasInferenceAPI" | "providers" diff --git a/src/routes/api/v2/models/+server.ts b/src/routes/api/v2/models/+server.ts index d49dcde8313..cf5e94837eb 100644 --- a/src/routes/api/v2/models/+server.ts +++ b/src/routes/api/v2/models/+server.ts @@ -26,6 +26,7 @@ export const GET: RequestHandler = async () => { preprompt: model.preprompt, multimodal: model.multimodal, multimodalAcceptedMimetypes: model.multimodalAcceptedMimetypes, + acceptedFileMimetypes: model.acceptedFileMimetypes, supportsTools: (model as unknown as { supportsTools?: boolean }).supportsTools ?? false, unlisted: model.unlisted, hasInferenceAPI: model.hasInferenceAPI,