Spaces:
Running
Running
File size: 3,543 Bytes
5012205 8cfdcec 5012205 dff2be9 8cfdcec 5012205 dff2be9 5012205 8cfdcec 5012205 8cfdcec 5012205 8cfdcec dff2be9 5012205 264f96c dff2be9 5012205 dff2be9 8cfdcec 5012205 dff2be9 d8c725b 5012205 264f96c dff2be9 5012205 dff2be9 5012205 dff2be9 8cfdcec dff2be9 264f96c dff2be9 5012205 |
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 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
"use client";
import { getModels, getDefaultModel, ModelID } from "@/lib/models";
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from "./ui/select";
import { cn } from "@/lib/utils";
import { Bot } from "lucide-react";
import { useEffect, useState } from "react";
interface ModelPickerProps {
selectedModel: ModelID;
setSelectedModel: (model: ModelID) => void;
}
export const ModelPicker = ({ selectedModel, setSelectedModel }: ModelPickerProps) => {
const [models, setModels] = useState<ModelID[]>([]);
const [validModelId, setValidModelId] = useState<ModelID>("");
useEffect(() => {
const fetchModels = async () => {
const availableModels = await getModels();
setModels(availableModels);
const defaultModel = await getDefaultModel();
const currentModel = selectedModel || defaultModel;
const isValid = availableModels.includes(currentModel);
const newValidModelId = isValid ? currentModel : defaultModel;
setValidModelId(newValidModelId);
if (selectedModel !== newValidModelId) {
setSelectedModel(newValidModelId);
}
};
fetchModels();
}, [selectedModel, setSelectedModel]);
// Handle model change
const handleModelChange = (modelId: string) => {
if (models.includes(modelId as ModelID)) {
setSelectedModel(modelId as ModelID);
}
};
return (
<div className="absolute bottom-2 left-2 z-10">
<Select
value={validModelId}
onValueChange={handleModelChange}
defaultValue={validModelId}
>
<SelectTrigger
className="max-w-[200px] sm:max-w-fit sm:w-80 px-2 sm:px-3 h-8 sm:h-9 rounded-full group border-primary/20 bg-primary/5 hover:bg-primary/10 dark:bg-primary/10 dark:hover:bg-primary/20 transition-all duration-200 ring-offset-background focus:ring-2 focus:ring-primary/30 focus:ring-offset-2"
>
<SelectValue
placeholder="Select model"
className="text-xs font-medium flex items-center gap-1 sm:gap-2 text-primary dark:text-primary-foreground"
>
<div className="flex items-center gap-1 sm:gap-2">
<Bot className="h-3 w-3" />
<span className="font-medium truncate">{validModelId}</span>
</div>
</SelectValue>
</SelectTrigger>
<SelectContent
align="start"
className="bg-background/95 dark:bg-muted/95 backdrop-blur-sm border-border/80 rounded-lg overflow-hidden p-0 w-[280px]"
>
<SelectGroup className="space-y-1 p-1">
{models.map((id) => (
<SelectItem
key={id}
value={id}
className={cn(
"!px-2 sm:!px-3 py-1.5 sm:py-2 cursor-pointer rounded-md text-xs transition-colors duration-150",
"hover:bg-primary/5 hover:text-primary-foreground",
"focus:bg-primary/10 focus:text-primary focus:outline-none",
"data-[highlighted]:bg-primary/10 data-[highlighted]:text-primary",
validModelId === id && "!bg-primary/15 !text-primary font-medium"
)}
>
<div className="flex items-center gap-1.5">
<Bot className="h-4 w-4" />
<span className="font-medium truncate">{id}</span>
</div>
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
</div>
);
};
|