/* Copyright (C) 2023-2026 QuantumNous This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . For commercial licensing, please contact support@quantumnous.com */ import { BookOpenCheck, Braces, Code2, Database, FileCode, Globe, type LucideIcon, PanelTopOpen, ScanEye, Settings2, Sparkles, Workflow, Zap, } from 'lucide-react' import { useTranslation } from 'react-i18next' import { cn } from '@/lib/utils' import type { ModelCapability } from '../types' type CapabilityMeta = { icon: LucideIcon labelKey: string descriptionKey: string } const CAPABILITY_META: Record = { function_calling: { icon: Workflow, labelKey: 'Function calling', descriptionKey: 'Invoke developer-defined functions with structured arguments', }, streaming: { icon: Zap, labelKey: 'Streaming', descriptionKey: 'Stream tokens incrementally as they are generated', }, vision: { icon: ScanEye, labelKey: 'Vision', descriptionKey: 'Understand image inputs alongside text', }, json_mode: { icon: Braces, labelKey: 'JSON mode', descriptionKey: 'Force a syntactically valid JSON response', }, structured_output: { icon: FileCode, labelKey: 'Structured output', descriptionKey: 'Return data conforming to a JSON schema', }, reasoning: { icon: Sparkles, labelKey: 'Reasoning', descriptionKey: 'Multi-step thinking before final answer', }, tools: { icon: Settings2, labelKey: 'Tools', descriptionKey: 'Use external tools to extend capabilities', }, system_prompt: { icon: PanelTopOpen, labelKey: 'System prompt', descriptionKey: 'Steer behaviour with a system instruction', }, web_search: { icon: Globe, labelKey: 'Web search', descriptionKey: 'Search the public web at inference time', }, code_interpreter: { icon: Code2, labelKey: 'Code interpreter', descriptionKey: 'Execute code in a sandbox during the response', }, caching: { icon: Database, labelKey: 'Prompt caching', descriptionKey: 'Cache repeated prompt prefixes for cheaper, faster reuse', }, embeddings: { icon: BookOpenCheck, labelKey: 'Embeddings', descriptionKey: 'Return vector embeddings for inputs', }, } /** * Order capabilities for display. We put the most user-facing capabilities * first, then the rest. Anything not listed sinks to the bottom in a stable * order so the layout looks tidy across models. */ const CAPABILITY_ORDER: ModelCapability[] = [ 'streaming', 'function_calling', 'tools', 'json_mode', 'structured_output', 'vision', 'reasoning', 'caching', 'system_prompt', 'web_search', 'code_interpreter', 'embeddings', ] function orderCapabilities(capabilities: ModelCapability[]): ModelCapability[] { const set = new Set(capabilities) const ordered = CAPABILITY_ORDER.filter((c) => set.has(c)) for (const c of capabilities) { if (!ordered.includes(c)) ordered.push(c) } return ordered } export function ModelDetailsCapabilities(props: { capabilities: ModelCapability[] }) { const { t } = useTranslation() const ordered = orderCapabilities(props.capabilities) if (ordered.length === 0) { return (

{t('No capabilities reported for this model.')}

) } return (
{ordered.map((capability) => { const meta = CAPABILITY_META[capability] if (!meta) return null const Icon = meta.icon return (
{t(meta.labelKey)}

{t(meta.descriptionKey)}

) })}
) }