MCPcopy Create free account
hub / github.com/Openpanel-dev/openpanel / ModelPicker

Function ModelPicker

apps/start/src/components/chat/model-picker.tsx:19–70  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

17 * different agent name on the next render.
18 */
19export function ModelPicker() {
20 const { agentName, setAgent, models } = useChatState();
21
22 const grouped = models.reduce<Record<string, ChatModelOption[]>>(
23 (acc, m) => {
24 (acc[m.group] ??= []).push(m);
25 return acc;
26 },
27 {},
28 );
29
30 return (
31 <DropdownMenu>
32 <DropdownMenuTrigger asChild>
33 <Button
34 variant="ghost"
35 size="sm"
36 className="h-7 px-2 text-xs gap-1 text-muted-foreground"
37 aria-label="Select model"
38 title="Select model"
39 >
40 <span className="truncate max-w-[140px]">
41 {getModelLabel(agentName)}
42 </span>
43 <ChevronDownIcon className="size-3" />
44 </Button>
45 </DropdownMenuTrigger>
46 <DropdownMenuContent align="end" className="w-56">
47 {Object.entries(grouped).map(([group, items], idx) => (
48 <div key={group}>
49 {idx > 0 && <DropdownMenuSeparator />}
50 <DropdownMenuLabel className="text-[11px] uppercase tracking-wide text-muted-foreground">
51 {group}
52 </DropdownMenuLabel>
53 {items.map((m) => (
54 <DropdownMenuItem
55 key={m.id}
56 onSelect={() => setAgent(m.id)}
57 className="flex items-center justify-between gap-2"
58 >
59 <span className="truncate">{m.label}</span>
60 {agentName === m.id && (
61 <CheckIcon className="size-3 shrink-0 text-foreground" />
62 )}
63 </DropdownMenuItem>
64 ))}
65 </div>
66 ))}
67 </DropdownMenuContent>
68 </DropdownMenu>
69 );
70}

Callers

nothing calls this directly

Calls 4

useChatStateFunction · 0.90
getModelLabelFunction · 0.85
pushMethod · 0.45
mapMethod · 0.45

Tested by

no test coverage detected