| import { useState } from 'react' |
|
|
| const PROVIDER_ICONS = { |
| groq: 'β‘', google: 'π', mistral: 'π«', huggingface: 'π€', nvidia: 'β', openrouter: 'π', |
| } |
|
|
| const PROVIDER_SUBS = { |
| groq: 'LPU Inference', google: 'Gemini Flash', mistral: 'European AI', |
| huggingface: 'Open-weight', nvidia: 'NIM Endpoints', openrouter: 'Unified gateway', |
| } |
|
|
| export default function ModelPicker({ registry, currentProvider, currentModel, onSelect, onClose }) { |
| const [activeProv, setActiveProv] = useState(currentProvider) |
|
|
| const providers = Object.keys(registry) |
| const currentModels = registry[activeProv]?.models || [] |
|
|
| return ( |
| <div className="modal-overlay" onClick={e => e.target === e.currentTarget && onClose()}> |
| <div className="modal-card model-picker-card"> |
| <div className="modal-header"> |
| <span className="modal-title">Select Model</span> |
| <button className="modal-close" onClick={onClose}> |
| <svg viewBox="0 0 24 24"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg> |
| </button> |
| </div> |
| |
| <div className="picker-layout"> |
| <div className="picker-providers"> |
| {providers.map(p => ( |
| <button |
| key={p} |
| className={`picker-prov-btn ${p === activeProv ? 'active' : ''}`} |
| onClick={() => setActiveProv(p)} |
| > |
| <span className="picker-prov-icon">{PROVIDER_ICONS[p] || 'π€'}</span> |
| <div> |
| <div style={{ fontWeight: 600 }}>{registry[p].label}</div> |
| <div style={{ fontSize: 10, opacity: 0.6 }}>{PROVIDER_SUBS[p] || ''}</div> |
| </div> |
| </button> |
| ))} |
| </div> |
| |
| <div className="picker-models"> |
| {currentModels.map(m => ( |
| <div |
| key={m.id} |
| className={`picker-model-item ${(activeProv === currentProvider && m.id === currentModel) ? 'active' : ''}`} |
| onClick={() => onSelect(activeProv, m.id)} |
| > |
| <div className="picker-model-badge">{m.badge || 'π'}</div> |
| <div> |
| <div className="picker-model-name">{m.name}</div> |
| <div className="picker-traits"> |
| {(m.traits || []).map(t => ( |
| <span key={t} className={`trait-pill ${t}`}>{t}</span> |
| ))} |
| </div> |
| </div> |
| </div> |
| ))} |
| {currentModels.length === 0 && ( |
| <div style={{ color: 'var(--t4)', fontSize: 13, padding: 20, textAlign: 'center' }}> |
| No models available |
| </div> |
| )} |
| </div> |
| </div> |
| </div> |
| </div> |
| ) |
| } |
|
|