amaniquery-frontend / src /components /ModelSelector.tsx
Benaah's picture
Upload folder using huggingface_hub
6a059d3 verified
Raw
History Blame Contribute Delete
6.15 kB
"use client"
/**
* Model Selector - WeKnora Integration
*
* Allows users to switch between AI models dynamically
*/
import { useState } from "react"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
import {
Sparkles,
Zap,
Brain,
Rocket,
Info
} from "lucide-react"
import { cn } from "@/lib/utils"
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip"
interface AIModel {
id: string
name: string
provider: string
description: string
speed: 'fast' | 'medium' | 'slow'
quality: 'standard' | 'high' | 'premium'
icon: React.ReactNode
available: boolean
}
// Prioritize Moonshot and Gemini (user has these APIs)
const AI_MODELS: AIModel[] = [
{
id: "moonshot-v1-8k",
name: "Moonshot V1",
provider: "Moonshot",
description: "Fast, efficient for most queries",
speed: "fast",
quality: "high",
icon: <Zap className="h-4 w-4" />,
available: true
},
{
id: "gemini-2.5-flash",
name: "Gemini 2.5 Flash",
provider: "Google",
description: "Latest Gemini, great balance",
speed: "fast",
quality: "high",
icon: <Sparkles className="h-4 w-4" />,
available: true
},
{
id: "gemini-1.5-pro",
name: "Gemini 1.5 Pro",
provider: "Google",
description: "Best for complex analysis",
speed: "medium",
quality: "premium",
icon: <Brain className="h-4 w-4" />,
available: true
},
{
id: "gpt-4o-mini",
name: "GPT-4o Mini",
provider: "OpenAI",
description: "Requires OpenAI API key",
speed: "fast",
quality: "high",
icon: <Sparkles className="h-4 w-4" />,
available: false
},
{
id: "claude-3.5-sonnet",
name: "Claude 3.5 Sonnet",
provider: "Anthropic",
description: "Requires Anthropic API key",
speed: "medium",
quality: "premium",
icon: <Rocket className="h-4 w-4" />,
available: false
}
]
interface ModelSelectorProps {
selected: string
onChange: (modelId: string) => void
className?: string
showDetails?: boolean
}
export function ModelSelector({
selected,
onChange,
className,
showDetails = true
}: ModelSelectorProps) {
const selectedModel = AI_MODELS.find(m => m.id === selected) || AI_MODELS[0]
const getSpeedBadge = (speed: string) => {
switch (speed) {
case 'fast': return <Badge variant="default" className="bg-green-500 text-xs">Fast</Badge>
case 'medium': return <Badge variant="secondary" className="text-xs">Medium</Badge>
case 'slow': return <Badge variant="outline" className="text-xs">Slow</Badge>
}
}
const getQualityBadge = (quality: string) => {
switch (quality) {
case 'premium': return <Badge variant="default" className="bg-purple-500 text-xs">Premium</Badge>
case 'high': return <Badge variant="secondary" className="text-xs">High</Badge>
case 'standard': return <Badge variant="outline" className="text-xs">Standard</Badge>
}
}
return (
<div className={cn("flex items-center gap-2", className)}>
<Select value={selected} onValueChange={onChange}>
<SelectTrigger className="w-[200px]">
<div className="flex items-center gap-2">
{selectedModel.icon}
<SelectValue placeholder="Select model" />
</div>
</SelectTrigger>
<SelectContent>
{AI_MODELS.map((model) => (
<SelectItem key={model.id} value={model.id}>
<div className="flex items-center gap-2">
{model.icon}
<div className="flex flex-col">
<span className="font-medium">{model.name}</span>
<span className="text-xs text-muted-foreground">{model.provider}</span>
</div>
</div>
</SelectItem>
))}
</SelectContent>
</Select>
{showDetails && (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button variant="ghost" size="icon" className="h-8 w-8">
<Info className="h-4 w-4 text-muted-foreground" />
</Button>
</TooltipTrigger>
<TooltipContent side="bottom" className="max-w-[250px]">
<div className="space-y-2">
<div className="flex items-center gap-2">
{selectedModel.icon}
<span className="font-medium">{selectedModel.name}</span>
</div>
<p className="text-xs text-muted-foreground">{selectedModel.description}</p>
<div className="flex gap-2">
{getSpeedBadge(selectedModel.speed)}
{getQualityBadge(selectedModel.quality)}
</div>
</div>
</TooltipContent>
</Tooltip>
</TooltipProvider>
)}
</div>
)
}
// Compact version for sidebar
export function ModelSelectorCompact({
selected,
onChange
}: {
selected: string
onChange: (modelId: string) => void
}) {
const selectedModel = AI_MODELS.find(m => m.id === selected) || AI_MODELS[0]
return (
<Select value={selected} onValueChange={onChange}>
<SelectTrigger className="w-full h-9">
<div className="flex items-center gap-2 text-sm">
{selectedModel.icon}
<span>{selectedModel.name}</span>
</div>
</SelectTrigger>
<SelectContent>
{AI_MODELS.map((model) => (
<SelectItem key={model.id} value={model.id}>
<div className="flex items-center gap-2">
{model.icon}
<span>{model.name}</span>
</div>
</SelectItem>
))}
</SelectContent>
</Select>
)
}
export default ModelSelector