--- title: "List of Supported Models" description: "Comprehensive catalog of supported AI models with detailed specifications, capabilities, and costs" icon: "list" mode: "wide" --- export const ModelDialog = React.memo(({ model, onClose }) => { const modelString = `model: "${model.model || 'unknown'}"` const jsonString = JSON.stringify(model, null, 2) const copyModelString = useCallback(() => { navigator.clipboard.writeText(modelString) }, [modelString]) const copyJson = useCallback(() => { navigator.clipboard.writeText(jsonString) }, [jsonString]) return (
e.stopPropagation()} >

Model Details: {model.model || 'Unknown'}

Use on Bifrost
{modelString}
Full Configuration (JSON)
              {jsonString}
            
) }) export const ModelsCatalog = () => { const [models, setModels] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [searchTerm, setSearchTerm] = useState('') const [selectedProvider, setSelectedProvider] = useState('all') const [selectedModel, setSelectedModel] = useState(null) const [showDialog, setShowDialog] = useState(false) useEffect(() => { async function fetchModels () { try { const response = await fetch('https://getbifrost.ai/datasheet') if (!response.ok) { throw new Error(`Failed to fetch models: ${response.status}`) } const data = await response.json() // Convert object format {modelName: {config}} to array format if (data && typeof data === 'object' && !Array.isArray(data)) { const modelsArray = Object.entries(data).map(([modelName, config]) => ({ model: modelName, ...config })) if (modelsArray.length === 0) { throw new Error('No models data received') } setModels(modelsArray) } else if (Array.isArray(data)) { setModels(data) } else { throw new Error('Invalid data format') } } catch (err) { console.error('Fetch error:', err) setError(err.message) } finally { setLoading(false) } } fetchModels() }, []) useEffect(() => { const styleId = 'custom-scrollbar-styles' if (document.getElementById(styleId)) return const style = document.createElement('style') style.id = styleId style.textContent = ` /* Firefox overlay scrollbar - always visible */ .custom-scrollbar { overflow: auto !important; scrollbar-gutter: auto !important; scrollbar-width: thin !important; scrollbar-color: rgba(228, 228, 231, 0.6) rgba(241, 245, 249, 0.5) !important; } .custom-scrollbar:hover { scrollbar-color: rgba(228, 228, 231, 1) rgba(241, 245, 249, 0.7) !important; } .dark .custom-scrollbar { scrollbar-color: rgba(113, 113, 122, 0.6) rgba(39, 39, 42, 0.5) !important; } .dark .custom-scrollbar:hover { scrollbar-color: rgba(113, 113, 122, 1) rgba(39, 39, 42, 0.7) !important; } /* WebKit overlay scrollbar - always visible */ .custom-scrollbar::-webkit-scrollbar { width: 8px !important; height: 8px !important; background: transparent !important; } .custom-scrollbar::-webkit-scrollbar-track { background-color: rgba(241, 245, 249, 0.5) !important; margin: 0 !important; border: none !important; border-radius: 8px !important; } .dark .custom-scrollbar::-webkit-scrollbar-track { background-color: rgba(39, 39, 42, 0.5) !important; } .custom-scrollbar::-webkit-scrollbar-thumb { background-color: rgba(228, 228, 231, 0.6) !important; border-radius: 8px !important; border: 2px solid transparent !important; background-clip: padding-box !important; transition: background-color 0.2s !important; } .custom-scrollbar:hover::-webkit-scrollbar-thumb { background-color: rgba(228, 228, 231, 1) !important; } .custom-scrollbar::-webkit-scrollbar-thumb:hover { background-color: rgba(82, 82, 91, 1) !important; } .dark .custom-scrollbar::-webkit-scrollbar-thumb { background-color: rgba(113, 113, 122, 0.6) !important; } .dark .custom-scrollbar:hover::-webkit-scrollbar-thumb { background-color: rgba(113, 113, 122, 1) !important; } .dark .custom-scrollbar::-webkit-scrollbar-thumb:hover { background-color: rgba(161, 161, 170, 1) !important; } /* Make scrollbar overlay by extending table into scrollbar area */ .custom-scrollbar { overflow-x: hidden !important; } .custom-scrollbar > table { width: calc(100% + 8px) !important; margin-right: -8px !important; } ` document.head.appendChild(style) return () => { const existingStyle = document.getElementById(styleId) if (existingStyle) { existingStyle.remove() } } }, []) const providers = useMemo(() => { const uniqueProviders = new Set() models.forEach(model => { if (model.provider) { uniqueProviders.add(model.provider) } }) return Array.from(uniqueProviders).sort() }, [models]) const filteredModels = useMemo(() => { let filtered = models // Filter by provider if (selectedProvider !== 'all') { filtered = filtered.filter(model => model.provider === selectedProvider) } // Filter by search term if (searchTerm) { const term = searchTerm.toLowerCase() filtered = filtered.filter(model => Object.values(model).some(value => String(value).toLowerCase().includes(term) ) ) } return filtered }, [models, searchTerm, selectedProvider]) const formatColumnName = useCallback((name) => { // Handle snake_case: replace underscores with spaces let formatted = name.replace(/_/g, ' ') // Handle camelCase: add space before capital letters formatted = formatted.replace(/([A-Z])/g, ' $1') // Capitalize first letter of each word and trim return formatted .split(' ') .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) .join(' ') .trim() }, []) const handleRowClick = useCallback((model) => { setSelectedModel(model) setShowDialog(true) }, []) if (loading) { return (
Loading models...
) } if (error) { return (
Error: {error}
Check console for details
) } if (!models || models.length === 0) { return (
No models available
) } return (
setSearchTerm(e.target.value)} className="flex-1 px-3 py-2 text-base border-2 border-zinc-950/20 dark:border-white/20 rounded-lg focus:outline-none focus:border-[#0C3B43] dark:focus:border-[#07C983] transition-colors bg-white dark:bg-zinc-950 text-zinc-950 dark:text-white" />
Showing {filteredModels.length} of {models.length} models
{filteredModels.length === 0 && searchTerm ? ( ) : ( filteredModels.map((model, idx) => ( )) )}
Provider Model Details
No models found matching "{searchTerm}"
{model.provider || '—'} {model.model || '—'}
{showDialog && selectedModel && setShowDialog(false)} />}
) }