File size: 2,827 Bytes
212c959 48b8720 212c959 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | 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>
)
}
|