scira-chat / components /model-picker.tsx
victor's picture
victor HF Staff
feat: Add Hugging Face model support
8cfdcec
raw
history blame
3.54 kB
"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>
);
};