diff --git a/frontend/src/components/ModelSelector.tsx b/frontend/src/components/ModelSelector.tsx index 8628ef5c..cc86ac6a 100644 --- a/frontend/src/components/ModelSelector.tsx +++ b/frontend/src/components/ModelSelector.tsx @@ -15,7 +15,7 @@ import type { Model } from "openai/resources/models.js"; // Model configuration for display names, badges, and token limits type ModelCfg = { displayName: string; - badge?: string; + badges?: string[]; disabled?: boolean; requiresPro?: boolean; requiresStarter?: boolean; @@ -34,33 +34,39 @@ export const MODEL_CONFIG: Record = { }, "google/gemma-3-27b-it": { displayName: "Gemma 3 27B", - badge: "Starter", + badges: ["Starter"], requiresStarter: true, tokenLimit: 70000 }, "leon-se/gemma-3-27b-it-fp8-dynamic": { displayName: "Gemma 3 27B", - badge: "Starter", + badges: ["Starter"], requiresStarter: true, supportsVision: true, tokenLimit: 70000 }, "deepseek-r1-70b": { displayName: "DeepSeek R1 70B", - badge: "Pro", + badges: ["Pro"], requiresPro: true, tokenLimit: 64000 }, + "deepseek-r1-0528": { + displayName: "DeepSeek R1 0528 671B", + badges: ["Pro", "Beta"], + requiresPro: true, + tokenLimit: 130000 + }, "mistral-small-3-1-24b": { displayName: "Mistral Small 3.1 24B", - badge: "Pro", + badges: ["Pro"], requiresPro: true, supportsVision: true, tokenLimit: 128000 }, "qwen2-5-72b": { displayName: "Qwen 2.5 72B", - badge: "Pro", + badges: ["Pro"], requiresPro: true, tokenLimit: 128000 } @@ -197,24 +203,28 @@ export function ModelSelector({ if (config) { elements.push(config.displayName); - if (config.badge) { - let badgeClass = "text-[10px] px-1.5 py-0.5 rounded-sm font-medium"; - - if (config.badge === "Coming Soon") { - badgeClass += " bg-gray-500/10 text-gray-600"; - } else if (config.badge === "Pro") { - badgeClass += " bg-gradient-to-r from-purple-500/10 to-blue-500/10 text-purple-600"; - } else if (config.badge === "Starter") { - badgeClass += " bg-gradient-to-r from-green-500/10 to-emerald-500/10 text-green-600"; - } else { - badgeClass += " bg-purple-500/10 text-purple-600"; - } - - elements.push( - - {config.badge} - - ); + if (config.badges && config.badges.length > 0) { + config.badges.forEach((badge, index) => { + let badgeClass = "text-[10px] px-1.5 py-0.5 rounded-sm font-medium"; + + if (badge === "Coming Soon") { + badgeClass += " bg-gray-500/10 text-gray-600"; + } else if (badge === "Pro") { + badgeClass += " bg-gradient-to-r from-purple-500/10 to-blue-500/10 text-purple-600"; + } else if (badge === "Starter") { + badgeClass += " bg-gradient-to-r from-green-500/10 to-emerald-500/10 text-green-600"; + } else if (badge === "Beta") { + badgeClass += " bg-gradient-to-r from-yellow-500/10 to-orange-500/10 text-yellow-600"; + } else { + badgeClass += " bg-purple-500/10 text-purple-600"; + } + + elements.push( + + {badge} + + ); + }); } if ( @@ -263,7 +273,7 @@ export function ModelSelector({ - + {availableModels && Array.isArray(availableModels) && // Sort models: vision-capable first (if images present), then available, then restricted, then disabled diff --git a/frontend/src/config/pricingConfig.tsx b/frontend/src/config/pricingConfig.tsx index c33254bf..3ed2397b 100644 --- a/frontend/src/config/pricingConfig.tsx +++ b/frontend/src/config/pricingConfig.tsx @@ -44,6 +44,11 @@ export const PRICING_PLANS: PricingPlan[] = [ { text: "Rename Chats", included: true, icon: }, { text: "Image Upload", included: false, icon: }, { text: "DeepSeek R1 70B", included: false, icon: }, + { + text: "DeepSeek R1 0528 671B", + included: false, + icon: + }, { text: "Gemma 3 27B", included: false, icon: }, { text: "Mistral Small 3.1 24B", @@ -76,6 +81,11 @@ export const PRICING_PLANS: PricingPlan[] = [ }, { text: "Gemma 3 27B", included: true, icon: }, { text: "DeepSeek R1 70B", included: false, icon: }, + { + text: "DeepSeek R1 0528 671B", + included: false, + icon: + }, { text: "Mistral Small 3.1 24B", included: false, @@ -107,6 +117,11 @@ export const PRICING_PLANS: PricingPlan[] = [ included: true, icon: }, + { + text: "DeepSeek R1 0528 671B", + included: true, + icon: + }, { text: "Gemma 3 27B", included: true, icon: }, { text: "Mistral Small 3.1 24B", @@ -153,6 +168,11 @@ export const PRICING_PLANS: PricingPlan[] = [ included: true, icon: }, + { + text: "DeepSeek R1 0528 671B", + included: true, + icon: + }, { text: "Gemma 3 27B", included: true, icon: }, { text: "Mistral Small 3.1 24B", @@ -208,6 +228,11 @@ export const PRICING_PLANS: PricingPlan[] = [ included: true, icon: }, + { + text: "DeepSeek R1 0528 671B", + included: true, + icon: + }, { text: "Gemma 3 27B", included: true, icon: }, { text: "Mistral Small 3.1 24B", diff --git a/frontend/src/routes/_auth.chat.$chatId.tsx b/frontend/src/routes/_auth.chat.$chatId.tsx index 7edd3a4d..3ca03827 100644 --- a/frontend/src/routes/_auth.chat.$chatId.tsx +++ b/frontend/src/routes/_auth.chat.$chatId.tsx @@ -233,16 +233,18 @@ function ChatComponent() { setUserImages([]); // Send message with system prompt as separate parameter - appendUserMessage(prompt, images, undefined, undefined, sysPrompt || undefined).catch((error) => { - // Only reset if it wasn't an abort - if (!(error instanceof Error) || error.message !== "Stream aborted") { - console.error("[ChatComponent] Failed to append message:", error); - setUserPrompt(prompt); - setSystemPrompt(sysPrompt); - setUserImages(images); - initialPromptProcessedRef.current = false; + appendUserMessage(prompt, images, undefined, undefined, sysPrompt || undefined).catch( + (error) => { + // Only reset if it wasn't an abort + if (!(error instanceof Error) || error.message !== "Stream aborted") { + console.error("[ChatComponent] Failed to append message:", error); + setUserPrompt(prompt); + setSystemPrompt(sysPrompt); + setUserImages(images); + initialPromptProcessedRef.current = false; + } } - }); + ); } }, [ userPrompt,