diff --git a/surfsense_backend/alembic/versions/35_update_litellmprovider_enum_comprehensive.py b/surfsense_backend/alembic/versions/35_update_litellmprovider_enum_comprehensive.py new file mode 100644 index 000000000..69d3206b7 --- /dev/null +++ b/surfsense_backend/alembic/versions/35_update_litellmprovider_enum_comprehensive.py @@ -0,0 +1,199 @@ +"""Update LiteLLMProvider enum with comprehensive provider support + +This migration adds support for all major LiteLLM providers including: +- Fast inference platforms (XAI, Cerebras, SambaNova, Fireworks AI) +- Cloud platforms (Cloudflare, Databricks) +- Renames AWS_BEDROCK to BEDROCK for consistency +- Adds CUSTOM for custom OpenAI-compatible endpoints + +Revision ID: 35 +Revises: 34 +""" + +from collections.abc import Sequence + +from alembic import op + +# revision identifiers, used by Alembic. +revision: str = "35" +down_revision: str | None = "34" +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + """ + Add new LLM providers to LiteLLMProvider enum and migrate existing data. + + New providers added: + - XAI: xAI's Grok models + - FIREWORKS_AI: Fireworks AI platform + - CEREBRAS: Cerebras inference platform (fastest) + - SAMBANOVA: SambaNova inference platform + - CLOUDFLARE: Cloudflare Workers AI + - DATABRICKS: Databricks Model Serving + - BEDROCK: AWS Bedrock (replaces AWS_BEDROCK) + - CUSTOM: Custom OpenAI-compatible endpoints + """ + + # Add XAI (xAI Grok models) + op.execute( + """ + DO $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 FROM pg_enum + WHERE enumtypid = 'litellmprovider'::regtype + AND enumlabel = 'XAI' + ) THEN + ALTER TYPE litellmprovider ADD VALUE 'XAI'; + END IF; + END$$; + """ + ) + + # Add FIREWORKS_AI + op.execute( + """ + DO $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 FROM pg_enum + WHERE enumtypid = 'litellmprovider'::regtype + AND enumlabel = 'FIREWORKS_AI' + ) THEN + ALTER TYPE litellmprovider ADD VALUE 'FIREWORKS_AI'; + END IF; + END$$; + """ + ) + + # Add CEREBRAS (fastest inference platform) + op.execute( + """ + DO $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 FROM pg_enum + WHERE enumtypid = 'litellmprovider'::regtype + AND enumlabel = 'CEREBRAS' + ) THEN + ALTER TYPE litellmprovider ADD VALUE 'CEREBRAS'; + END IF; + END$$; + """ + ) + + # Add SAMBANOVA + op.execute( + """ + DO $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 FROM pg_enum + WHERE enumtypid = 'litellmprovider'::regtype + AND enumlabel = 'SAMBANOVA' + ) THEN + ALTER TYPE litellmprovider ADD VALUE 'SAMBANOVA'; + END IF; + END$$; + """ + ) + + # Add CLOUDFLARE (Cloudflare Workers AI) + op.execute( + """ + DO $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 FROM pg_enum + WHERE enumtypid = 'litellmprovider'::regtype + AND enumlabel = 'CLOUDFLARE' + ) THEN + ALTER TYPE litellmprovider ADD VALUE 'CLOUDFLARE'; + END IF; + END$$; + """ + ) + + # Add DATABRICKS + op.execute( + """ + DO $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 FROM pg_enum + WHERE enumtypid = 'litellmprovider'::regtype + AND enumlabel = 'DATABRICKS' + ) THEN + ALTER TYPE litellmprovider ADD VALUE 'DATABRICKS'; + END IF; + END$$; + """ + ) + + # Add BEDROCK (new standardized name) + op.execute( + """ + DO $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 FROM pg_enum + WHERE enumtypid = 'litellmprovider'::regtype + AND enumlabel = 'BEDROCK' + ) THEN + ALTER TYPE litellmprovider ADD VALUE 'BEDROCK'; + END IF; + END$$; + """ + ) + + # Add CUSTOM for custom OpenAI-compatible endpoints + op.execute( + """ + DO $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 FROM pg_enum + WHERE enumtypid = 'litellmprovider'::regtype + AND enumlabel = 'CUSTOM' + ) THEN + ALTER TYPE litellmprovider ADD VALUE 'CUSTOM'; + END IF; + END$$; + """ + ) + + # Note: Both AWS_BEDROCK and BEDROCK will coexist in the enum for backward compatibility. + # - New configurations will use BEDROCK (via the frontend) + # - Existing AWS_BEDROCK configurations will continue to work + # - The backend service handles both values correctly + # + # Legacy enum values (PALM, NLPCLOUD, ALEPH_ALPHA, PETALS, etc.) also remain in the enum. + # PostgreSQL doesn't support removing enum values without recreating the entire type. + # + # Data migration from AWS_BEDROCK -> BEDROCK is NOT performed because: + # 1. PostgreSQL doesn't allow using new enum values in the same transaction + # 2. Both values work correctly with the backend service + # 3. Users can manually update old configs if desired (not required) + + +def downgrade() -> None: + """ + Downgrade migration. + + Note: PostgreSQL doesn't support removing enum values directly. + This would require recreating the entire enum type and updating all dependent objects. + For safety and data preservation, this downgrade is a no-op. + + If you need to downgrade, you should: + 1. Ensure no llm_configs are using the new providers + 2. Manually remove enum values (requires enum recreation - complex operation) + + This is not automated to prevent accidental data loss. + New enum values (XAI, FIREWORKS_AI, CEREBRAS, BEDROCK, etc.) will remain + in the database but won't be selectable in the application after downgrade. + """ + # PostgreSQL doesn't support removing enum values directly + # This is a no-op for safety + pass diff --git a/surfsense_backend/app/db.py b/surfsense_backend/app/db.py index 48154a417..78512c671 100644 --- a/surfsense_backend/app/db.py +++ b/surfsense_backend/app/db.py @@ -86,32 +86,33 @@ class LiteLLMProvider(str, Enum): OPENAI = "OPENAI" ANTHROPIC = "ANTHROPIC" + GOOGLE = "GOOGLE" + AZURE_OPENAI = "AZURE_OPENAI" + BEDROCK = "BEDROCK" + VERTEX_AI = "VERTEX_AI" GROQ = "GROQ" COHERE = "COHERE" - HUGGINGFACE = "HUGGINGFACE" - AZURE_OPENAI = "AZURE_OPENAI" - GOOGLE = "GOOGLE" - AWS_BEDROCK = "AWS_BEDROCK" - OLLAMA = "OLLAMA" MISTRAL = "MISTRAL" - TOGETHER_AI = "TOGETHER_AI" - OPENROUTER = "OPENROUTER" - REPLICATE = "REPLICATE" - PALM = "PALM" - VERTEX_AI = "VERTEX_AI" - ANYSCALE = "ANYSCALE" - PERPLEXITY = "PERPLEXITY" - DEEPINFRA = "DEEPINFRA" - AI21 = "AI21" - NLPCLOUD = "NLPCLOUD" - ALEPH_ALPHA = "ALEPH_ALPHA" - PETALS = "PETALS" - COMETAPI = "COMETAPI" - # Chinese LLM Providers (OpenAI-compatible) DEEPSEEK = "DEEPSEEK" + XAI = "XAI" + OPENROUTER = "OPENROUTER" + TOGETHER_AI = "TOGETHER_AI" + FIREWORKS_AI = "FIREWORKS_AI" + REPLICATE = "REPLICATE" + PERPLEXITY = "PERPLEXITY" + OLLAMA = "OLLAMA" ALIBABA_QWEN = "ALIBABA_QWEN" MOONSHOT = "MOONSHOT" ZHIPU = "ZHIPU" + ANYSCALE = "ANYSCALE" + DEEPINFRA = "DEEPINFRA" + CEREBRAS = "CEREBRAS" + SAMBANOVA = "SAMBANOVA" + AI21 = "AI21" + CLOUDFLARE = "CLOUDFLARE" + DATABRICKS = "DATABRICKS" + COMETAPI = "COMETAPI" + HUGGINGFACE = "HUGGINGFACE" CUSTOM = "CUSTOM" diff --git a/surfsense_backend/app/services/llm_service.py b/surfsense_backend/app/services/llm_service.py index 95ff9e4a4..f63228ba6 100644 --- a/surfsense_backend/app/services/llm_service.py +++ b/surfsense_backend/app/services/llm_service.py @@ -61,11 +61,26 @@ async def validate_llm_config( "AZURE_OPENAI": "azure", "OPENROUTER": "openrouter", "COMETAPI": "cometapi", - # Chinese LLM providers (OpenAI-compatible) + "XAI": "xai", + "BEDROCK": "bedrock", + "AWS_BEDROCK": "bedrock", # Legacy support (backward compatibility) + "VERTEX_AI": "vertex_ai", + "TOGETHER_AI": "together_ai", + "FIREWORKS_AI": "fireworks_ai", + "REPLICATE": "replicate", + "PERPLEXITY": "perplexity", + "ANYSCALE": "anyscale", + "DEEPINFRA": "deepinfra", + "CEREBRAS": "cerebras", + "SAMBANOVA": "sambanova", + "AI21": "ai21", + "CLOUDFLARE": "cloudflare", + "DATABRICKS": "databricks", + # Chinese LLM providers "DEEPSEEK": "openai", "ALIBABA_QWEN": "openai", "MOONSHOT": "openai", - "ZHIPU": "openai", + "ZHIPU": "openai", # GLM needs special handling } provider_prefix = provider_map.get(provider, provider.lower()) model_string = f"{provider_prefix}/{model_name}" @@ -187,12 +202,26 @@ async def get_user_llm_instance( "AZURE_OPENAI": "azure", "OPENROUTER": "openrouter", "COMETAPI": "cometapi", - # Chinese LLM providers (OpenAI-compatible) - "DEEPSEEK": "openai", # DeepSeek uses OpenAI-compatible API - "ALIBABA_QWEN": "openai", # Qwen uses OpenAI-compatible API - "MOONSHOT": "openai", # Moonshot (Kimi) uses OpenAI-compatible API - "ZHIPU": "openai", # Zhipu (GLM) uses OpenAI-compatible API - # Add more mappings as needed + "XAI": "xai", + "BEDROCK": "bedrock", + "AWS_BEDROCK": "bedrock", # Legacy support (backward compatibility) + "VERTEX_AI": "vertex_ai", + "TOGETHER_AI": "together_ai", + "FIREWORKS_AI": "fireworks_ai", + "REPLICATE": "replicate", + "PERPLEXITY": "perplexity", + "ANYSCALE": "anyscale", + "DEEPINFRA": "deepinfra", + "CEREBRAS": "cerebras", + "SAMBANOVA": "sambanova", + "AI21": "ai21", + "CLOUDFLARE": "cloudflare", + "DATABRICKS": "databricks", + # Chinese LLM providers + "DEEPSEEK": "openai", + "ALIBABA_QWEN": "openai", + "MOONSHOT": "openai", + "ZHIPU": "openai", } provider_prefix = provider_map.get( llm_config.provider.value, llm_config.provider.value.lower() diff --git a/surfsense_web/components/onboard/add-provider-step.tsx b/surfsense_web/components/onboard/add-provider-step.tsx index d7ed3aabe..d3d335b17 100644 --- a/surfsense_web/components/onboard/add-provider-step.tsx +++ b/surfsense_web/components/onboard/add-provider-step.tsx @@ -1,6 +1,6 @@ "use client"; -import { AlertCircle, Bot, Plus, Trash2 } from "lucide-react"; +import { AlertCircle, Bot, Check, ChevronsUpDown, Plus, Trash2 } from "lucide-react"; import { motion } from "motion/react"; import { useTranslations } from "next-intl"; import { useState } from "react"; @@ -9,8 +9,17 @@ import { Alert, AlertDescription } from "@/components/ui/alert"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; +import { + Command, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, +} from "@/components/ui/command"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; +import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; import { Select, SelectContent, @@ -19,8 +28,10 @@ import { SelectValue, } from "@/components/ui/select"; import { LANGUAGES } from "@/contracts/enums/languages"; +import { getModelsByProvider, LLM_MODELS } from "@/contracts/enums/llm-models"; import { LLM_PROVIDERS } from "@/contracts/enums/llm-providers"; import { type CreateLLMConfig, useLLMConfigs } from "@/hooks/use-llm-configs"; +import { cn } from "@/lib/utils"; import InferenceParamsEditor from "../inference-params-editor"; @@ -50,6 +61,7 @@ export function AddProviderStep({ search_space_id: searchSpaceId, }); const [isSubmitting, setIsSubmitting] = useState(false); + const [modelComboboxOpen, setModelComboboxOpen] = useState(false); const handleInputChange = (field: keyof CreateLLMConfig, value: string) => { setFormData((prev) => ({ ...prev, [field]: value })); @@ -85,11 +97,18 @@ export function AddProviderStep({ }; const selectedProvider = LLM_PROVIDERS.find((p) => p.value === formData.provider); + const availableModels = formData.provider ? getModelsByProvider(formData.provider) : []; const handleParamsChange = (newParams: Record) => { setFormData((prev) => ({ ...prev, litellm_params: newParams })); }; + // Reset model when provider changes + const handleProviderChange = (value: string) => { + handleInputChange("provider", value); + setFormData((prev) => ({ ...prev, model_name: "" })); + }; + return (
{/* Info Alert */} @@ -182,14 +201,11 @@ export function AddProviderStep({
- - + {LLM_PROVIDERS.map((provider) => ( {provider.label} @@ -235,18 +251,95 @@ export function AddProviderStep({
- handleInputChange("model_name", e.target.value)} - required - /> - {selectedProvider && ( -

- {t("examples")}: {selectedProvider.example} -

- )} + + + + + + + handleInputChange("model_name", value)} + /> + + +
+ {formData.model_name + ? `Using custom model: "${formData.model_name}"` + : "Type your model name above"} +
+
+ {availableModels.length > 0 && ( + + {availableModels + .filter( + (model) => + !formData.model_name || + model.value + .toLowerCase() + .includes(formData.model_name.toLowerCase()) || + model.label + .toLowerCase() + .includes(formData.model_name.toLowerCase()) + ) + .map((model) => ( + { + handleInputChange("model_name", currentValue); + setModelComboboxOpen(false); + }} + className="flex flex-col items-start py-3" + > +
+ +
+
{model.label}
+ {model.contextWindow && ( +
+ Context: {model.contextWindow} +
+ )} +
+
+
+ ))} +
+ )} +
+
+
+
+

+ {availableModels.length > 0 + ? `Type freely or select from ${availableModels.length} model suggestions` + : selectedProvider?.example + ? `${t("examples")}: ${selectedProvider.example}` + : "Type your model name freely"} +

diff --git a/surfsense_web/components/settings/model-config-manager.tsx b/surfsense_web/components/settings/model-config-manager.tsx index 5c4618baf..20edc228c 100644 --- a/surfsense_web/components/settings/model-config-manager.tsx +++ b/surfsense_web/components/settings/model-config-manager.tsx @@ -38,6 +38,7 @@ import { SelectValue, } from "@/components/ui/select"; import { LANGUAGES } from "@/contracts/enums/languages"; +import { getModelsByProvider } from "@/contracts/enums/llm-models"; import { LLM_PROVIDERS } from "@/contracts/enums/llm-providers"; import { type CreateLLMConfig, type LLMConfig, useLLMConfigs } from "@/hooks/use-llm-configs"; import InferenceParamsEditor from "../inference-params-editor"; @@ -93,12 +94,13 @@ export function ModelConfigManager({ searchSpaceId }: ModelConfigManagerProps) { setFormData((prev) => ({ ...prev, [field]: value })); }; - // Handle provider change with auto-fill API Base URL / 处理 Provider 变更并自动填充 API Base URL + // Handle provider change with auto-fill API Base URL and reset model / 处理 Provider 变更并自动填充 API Base URL 并重置模型 const handleProviderChange = (providerValue: string) => { const provider = LLM_PROVIDERS.find((p) => p.value === providerValue); setFormData((prev) => ({ ...prev, provider: providerValue, + model_name: "", // Reset model when provider changes // Auto-fill API Base URL if provider has a default / 如果提供商有默认值则自动填充 api_base: provider?.apiBase || prev.api_base, })); @@ -157,6 +159,7 @@ export function ModelConfigManager({ searchSpaceId }: ModelConfigManagerProps) { }; const selectedProvider = LLM_PROVIDERS.find((p) => p.value === formData.provider); + const availableModels = formData.provider ? getModelsByProvider(formData.provider) : []; const getProviderInfo = (providerValue: string) => { return LLM_PROVIDERS.find((p) => p.value === providerValue); @@ -530,17 +533,50 @@ export function ModelConfigManager({ searchSpaceId }: ModelConfigManagerProps) {
- handleInputChange("model_name", e.target.value)} - required - /> - {selectedProvider && ( -

- Examples: {selectedProvider.example} -

+ {availableModels.length > 0 ? ( + <> + +

+ {availableModels.length} model{availableModels.length !== 1 ? "s" : ""}{" "} + available +

+ + ) : ( + <> + handleInputChange("model_name", e.target.value)} + required + /> + {selectedProvider && ( +

+ Examples: {selectedProvider.example} +

+ )} + )}
diff --git a/surfsense_web/components/ui/command.tsx b/surfsense_web/components/ui/command.tsx new file mode 100644 index 000000000..203d8b32c --- /dev/null +++ b/surfsense_web/components/ui/command.tsx @@ -0,0 +1,160 @@ +"use client"; + +import { Command as CommandPrimitive } from "cmdk"; +import { SearchIcon } from "lucide-react"; +import type * as React from "react"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog"; +import { cn } from "@/lib/utils"; + +function Command({ className, ...props }: React.ComponentProps) { + return ( + + ); +} + +function CommandDialog({ + title = "Command Palette", + description = "Search for a command to run...", + children, + className, + showCloseButton = true, + ...props +}: React.ComponentProps & { + title?: string; + description?: string; + className?: string; + showCloseButton?: boolean; +}) { + return ( + + + {title} + {description} + + + + {children} + + + + ); +} + +function CommandInput({ + className, + ...props +}: React.ComponentProps) { + return ( +
+ + +
+ ); +} + +function CommandList({ className, ...props }: React.ComponentProps) { + return ( + + ); +} + +function CommandEmpty({ ...props }: React.ComponentProps) { + return ( + + ); +} + +function CommandGroup({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function CommandSeparator({ + className, + ...props +}: React.ComponentProps) { + return ( + + ); +} + +function CommandItem({ className, ...props }: React.ComponentProps) { + return ( + + ); +} + +function CommandShortcut({ className, ...props }: React.ComponentProps<"span">) { + return ( + + ); +} + +export { + Command, + CommandDialog, + CommandInput, + CommandList, + CommandEmpty, + CommandGroup, + CommandItem, + CommandShortcut, + CommandSeparator, +}; diff --git a/surfsense_web/contracts/enums/llm-models.ts b/surfsense_web/contracts/enums/llm-models.ts new file mode 100644 index 000000000..c62b2a9d6 --- /dev/null +++ b/surfsense_web/contracts/enums/llm-models.ts @@ -0,0 +1,1478 @@ +export interface LLMModel { + value: string; + label: string; + provider: string; + contextWindow?: string; +} + +// Comprehensive LLM models database organized by provider +export const LLM_MODELS: LLMModel[] = [ + // OpenAI + { + value: "gpt-4o", + label: "GPT-4o", + provider: "OPENAI", + contextWindow: "128K", + }, + { + value: "gpt-4o-mini", + label: "GPT-4o Mini", + provider: "OPENAI", + contextWindow: "128K", + }, + { + value: "gpt-4o-2024-11-20", + label: "GPT-4o (Nov 2024)", + provider: "OPENAI", + contextWindow: "128K", + }, + { + value: "gpt-4o-2024-08-06", + label: "GPT-4o (Aug 2024)", + provider: "OPENAI", + contextWindow: "128K", + }, + { + value: "gpt-4o-2024-05-13", + label: "GPT-4o (May 2024)", + provider: "OPENAI", + contextWindow: "128K", + }, + { + value: "gpt-4-turbo", + label: "GPT-4 Turbo", + provider: "OPENAI", + contextWindow: "128K", + }, + { value: "gpt-4", label: "GPT-4", provider: "OPENAI", contextWindow: "8K" }, + { + value: "gpt-3.5-turbo", + label: "GPT-3.5 Turbo", + provider: "OPENAI", + contextWindow: "16K", + }, + { value: "o1", label: "O1", provider: "OPENAI", contextWindow: "200K" }, + { + value: "o1-mini", + label: "O1 Mini", + provider: "OPENAI", + contextWindow: "128K", + }, + { + value: "o1-preview", + label: "O1 Preview", + provider: "OPENAI", + contextWindow: "128K", + }, + { value: "o3", label: "O3", provider: "OPENAI", contextWindow: "200K" }, + { + value: "o3-mini", + label: "O3 Mini", + provider: "OPENAI", + contextWindow: "200K", + }, + { + value: "o4-mini", + label: "O4 Mini", + provider: "OPENAI", + contextWindow: "200K", + }, + { + value: "gpt-4.1", + label: "GPT-4.1", + provider: "OPENAI", + contextWindow: "1M", + }, + { + value: "gpt-4.1-mini", + label: "GPT-4.1 Mini", + provider: "OPENAI", + contextWindow: "1M", + }, + { + value: "gpt-4.1-nano", + label: "GPT-4.1 Nano", + provider: "OPENAI", + contextWindow: "1M", + }, + { value: "gpt-5", label: "GPT-5", provider: "OPENAI", contextWindow: "272K" }, + { + value: "gpt-5-mini", + label: "GPT-5 Mini", + provider: "OPENAI", + contextWindow: "272K", + }, + { + value: "gpt-5-nano", + label: "GPT-5 Nano", + provider: "OPENAI", + contextWindow: "272K", + }, + { + value: "chatgpt-4o-latest", + label: "ChatGPT-4o Latest", + provider: "OPENAI", + contextWindow: "128K", + }, + + // Anthropic + { + value: "claude-3-5-sonnet-20241022", + label: "Claude 3.5 Sonnet", + provider: "ANTHROPIC", + contextWindow: "200K", + }, + { + value: "claude-3-7-sonnet-20250219", + label: "Claude 3.7 Sonnet", + provider: "ANTHROPIC", + contextWindow: "200K", + }, + { + value: "claude-4-sonnet-20250514", + label: "Claude 4 Sonnet", + provider: "ANTHROPIC", + contextWindow: "1M", + }, + { + value: "claude-4-opus-20250514", + label: "Claude 4 Opus", + provider: "ANTHROPIC", + contextWindow: "200K", + }, + { + value: "claude-3-5-haiku-20241022", + label: "Claude 3.5 Haiku", + provider: "ANTHROPIC", + contextWindow: "200K", + }, + { + value: "claude-haiku-4-5-20251001", + label: "Claude Haiku 4.5", + provider: "ANTHROPIC", + contextWindow: "200K", + }, + { + value: "claude-3-opus-20240229", + label: "Claude 3 Opus", + provider: "ANTHROPIC", + contextWindow: "200K", + }, + { + value: "claude-3-haiku-20240307", + label: "Claude 3 Haiku", + provider: "ANTHROPIC", + contextWindow: "200K", + }, + { + value: "claude-sonnet-4-5-20250929", + label: "Claude Sonnet 4.5", + provider: "ANTHROPIC", + contextWindow: "200K", + }, + { + value: "claude-opus-4-1-20250805", + label: "Claude Opus 4.1", + provider: "ANTHROPIC", + contextWindow: "200K", + }, + + // Google (Gemini) + { + value: "gemini-2.5-flash", + label: "Gemini 2.5 Flash", + provider: "GOOGLE", + contextWindow: "1M", + }, + { + value: "gemini-2.5-pro", + label: "Gemini 2.5 Pro", + provider: "GOOGLE", + contextWindow: "1M", + }, + { + value: "gemini-2.0-flash", + label: "Gemini 2.0 Flash", + provider: "GOOGLE", + contextWindow: "1M", + }, + { + value: "gemini-2.0-flash-lite", + label: "Gemini 2.0 Flash Lite", + provider: "GOOGLE", + contextWindow: "1M", + }, + { + value: "gemini-1.5-flash", + label: "Gemini 1.5 Flash", + provider: "GOOGLE", + contextWindow: "1M", + }, + { + value: "gemini-1.5-pro", + label: "Gemini 1.5 Pro", + provider: "GOOGLE", + contextWindow: "2M", + }, + { + value: "gemini-pro", + label: "Gemini Pro", + provider: "GOOGLE", + contextWindow: "33K", + }, + { + value: "gemini-pro-vision", + label: "Gemini Pro Vision", + provider: "GOOGLE", + contextWindow: "16K", + }, + + // DeepSeek + { + value: "deepseek-chat", + label: "DeepSeek Chat", + provider: "DEEPSEEK", + contextWindow: "131K", + }, + { + value: "deepseek-reasoner", + label: "DeepSeek Reasoner", + provider: "DEEPSEEK", + contextWindow: "131K", + }, + { + value: "deepseek-coder", + label: "DeepSeek Coder", + provider: "DEEPSEEK", + contextWindow: "128K", + }, + { + value: "deepseek-chat", + label: "DeepSeek Chat V3", + provider: "DEEPSEEK", + contextWindow: "66K", + }, + { + value: "deepseek-v3", + label: "DeepSeek V3", + provider: "DEEPSEEK", + contextWindow: "66K", + }, + { + value: "deepseek-r1", + label: "DeepSeek R1", + provider: "DEEPSEEK", + contextWindow: "66K", + }, + { + value: "deepseek-r1-0528", + label: "DeepSeek R1 (0528)", + provider: "DEEPSEEK", + contextWindow: "65K", + }, + + // xAI (Grok) + { value: "grok-4", label: "Grok 4", provider: "XAI", contextWindow: "256K" }, + { value: "grok-3", label: "Grok 3", provider: "XAI", contextWindow: "131K" }, + { + value: "grok-3-mini", + label: "Grok 3 Mini", + provider: "XAI", + contextWindow: "131K", + }, + { + value: "grok-3-fast-beta", + label: "Grok 3 Fast", + provider: "XAI", + contextWindow: "131K", + }, + { + value: "grok-3-mini-fast", + label: "Grok 3 Mini Fast", + provider: "XAI", + contextWindow: "131K", + }, + { value: "grok-2", label: "Grok 2", provider: "XAI", contextWindow: "131K" }, + { + value: "grok-2-vision", + label: "Grok 2 Vision", + provider: "XAI", + contextWindow: "33K", + }, + + // Azure OpenAI + { + value: "gpt-4o", + label: "Azure GPT-4o", + provider: "AZURE_OPENAI", + contextWindow: "128K", + }, + { + value: "gpt-4o-mini", + label: "Azure GPT-4o Mini", + provider: "AZURE_OPENAI", + contextWindow: "128K", + }, + { + value: "gpt-4o-2024-11-20", + label: "Azure GPT-4o (Nov 2024)", + provider: "AZURE_OPENAI", + contextWindow: "128K", + }, + { + value: "gpt-4-turbo", + label: "Azure GPT-4 Turbo", + provider: "AZURE_OPENAI", + contextWindow: "128K", + }, + { + value: "gpt-4", + label: "Azure GPT-4", + provider: "AZURE_OPENAI", + contextWindow: "8K", + }, + { + value: "gpt-35-turbo", + label: "Azure GPT-3.5 Turbo", + provider: "AZURE_OPENAI", + contextWindow: "4K", + }, + { + value: "o1", + label: "Azure O1", + provider: "AZURE_OPENAI", + contextWindow: "200K", + }, + { + value: "o1-mini", + label: "Azure O1 Mini", + provider: "AZURE_OPENAI", + contextWindow: "128K", + }, + { + value: "o3-mini", + label: "Azure O3 Mini", + provider: "AZURE_OPENAI", + contextWindow: "200K", + }, + { + value: "gpt-4.1", + label: "Azure GPT-4.1", + provider: "AZURE_OPENAI", + contextWindow: "1M", + }, + { + value: "gpt-4.1-mini", + label: "Azure GPT-4.1 Mini", + provider: "AZURE_OPENAI", + contextWindow: "1M", + }, + { + value: "gpt-5", + label: "Azure GPT-5", + provider: "AZURE_OPENAI", + contextWindow: "272K", + }, + + // AWS Bedrock + { + value: "anthropic.claude-3-5-sonnet-20241022-v2:0", + label: "Bedrock Claude 3.5 Sonnet", + provider: "BEDROCK", + contextWindow: "200K", + }, + { + value: "anthropic.claude-3-7-sonnet-20250219-v1:0", + label: "Bedrock Claude 3.7 Sonnet", + provider: "BEDROCK", + contextWindow: "200K", + }, + { + value: "anthropic.claude-4-sonnet-20250514-v1:0", + label: "Bedrock Claude 4 Sonnet", + provider: "BEDROCK", + contextWindow: "1M", + }, + { + value: "anthropic.claude-3-opus-20240229-v1:0", + label: "Bedrock Claude 3 Opus", + provider: "BEDROCK", + contextWindow: "200K", + }, + { + value: "anthropic.claude-3-haiku-20240307-v1:0", + label: "Bedrock Claude 3 Haiku", + provider: "BEDROCK", + contextWindow: "200K", + }, + { + value: "anthropic.claude-haiku-4-5-20251001-v1:0", + label: "Bedrock Claude Haiku 4.5", + provider: "BEDROCK", + contextWindow: "200K", + }, + { + value: "amazon.nova-pro-v1:0", + label: "Amazon Nova Pro", + provider: "BEDROCK", + contextWindow: "300K", + }, + { + value: "amazon.nova-lite-v1:0", + label: "Amazon Nova Lite", + provider: "BEDROCK", + contextWindow: "300K", + }, + { + value: "amazon.nova-micro-v1:0", + label: "Amazon Nova Micro", + provider: "BEDROCK", + contextWindow: "128K", + }, + { + value: "meta.llama3-3-70b-instruct-v1:0", + label: "Bedrock Llama 3.3 70B", + provider: "BEDROCK", + contextWindow: "128K", + }, + { + value: "meta.llama3-1-405b-instruct-v1:0", + label: "Bedrock Llama 3.1 405B", + provider: "BEDROCK", + contextWindow: "128K", + }, + { + value: "meta.llama3-1-70b-instruct-v1:0", + label: "Bedrock Llama 3.1 70B", + provider: "BEDROCK", + contextWindow: "128K", + }, + { + value: "meta.llama3-1-8b-instruct-v1:0", + label: "Bedrock Llama 3.1 8B", + provider: "BEDROCK", + contextWindow: "128K", + }, + { + value: "meta.llama4-maverick-17b-instruct-v1:0", + label: "Bedrock Llama 4 Maverick 17B", + provider: "BEDROCK", + contextWindow: "128K", + }, + { + value: "meta.llama4-scout-17b-instruct-v1:0", + label: "Bedrock Llama 4 Scout 17B", + provider: "BEDROCK", + contextWindow: "128K", + }, + { + value: "mistral.mistral-large-2407-v1:0", + label: "Bedrock Mistral Large", + provider: "BEDROCK", + contextWindow: "128K", + }, + { + value: "mistral.mixtral-8x7b-instruct-v0:1", + label: "Bedrock Mixtral 8x7B", + provider: "BEDROCK", + contextWindow: "32K", + }, + { + value: "cohere.command-r-plus-v1:0", + label: "Bedrock Cohere Command R+", + provider: "BEDROCK", + contextWindow: "128K", + }, + { + value: "cohere.command-r-v1:0", + label: "Bedrock Cohere Command R", + provider: "BEDROCK", + contextWindow: "128K", + }, + { + value: "ai21.jamba-1-5-large-v1:0", + label: "Bedrock Jamba 1.5 Large", + provider: "BEDROCK", + contextWindow: "256K", + }, + { + value: "ai21.jamba-1-5-mini-v1:0", + label: "Bedrock Jamba 1.5 Mini", + provider: "BEDROCK", + contextWindow: "256K", + }, + { + value: "deepseek.v3-v1:0", + label: "Bedrock DeepSeek V3", + provider: "BEDROCK", + contextWindow: "164K", + }, + + // Vertex AI + { + value: "gemini-2.5-flash", + label: "Vertex Gemini 2.5 Flash", + provider: "VERTEX_AI", + contextWindow: "1M", + }, + { + value: "gemini-2.5-pro", + label: "Vertex Gemini 2.5 Pro", + provider: "VERTEX_AI", + contextWindow: "1M", + }, + { + value: "gemini-2.0-flash", + label: "Vertex Gemini 2.0 Flash", + provider: "VERTEX_AI", + contextWindow: "1M", + }, + { + value: "gemini-1.5-flash", + label: "Vertex Gemini 1.5 Flash", + provider: "VERTEX_AI", + contextWindow: "1M", + }, + { + value: "gemini-1.5-pro", + label: "Vertex Gemini 1.5 Pro", + provider: "VERTEX_AI", + contextWindow: "2M", + }, + { + value: "claude-3-5-sonnet-v2@20241022", + label: "Vertex Claude 3.5 Sonnet", + provider: "VERTEX_AI", + contextWindow: "200K", + }, + { + value: "claude-3-7-sonnet@20250219", + label: "Vertex Claude 3.7 Sonnet", + provider: "VERTEX_AI", + contextWindow: "200K", + }, + { + value: "claude-sonnet-4@20250514", + label: "Vertex Claude Sonnet 4", + provider: "VERTEX_AI", + contextWindow: "1M", + }, + { + value: "claude-3-opus@20240229", + label: "Vertex Claude 3 Opus", + provider: "VERTEX_AI", + contextWindow: "200K", + }, + { + value: "claude-3-haiku@20240307", + label: "Vertex Claude 3 Haiku", + provider: "VERTEX_AI", + contextWindow: "200K", + }, + { + value: "claude-haiku-4-5@20251001", + label: "Vertex Claude Haiku 4.5", + provider: "VERTEX_AI", + contextWindow: "200K", + }, + { + value: "meta/llama-3.1-405b-instruct-maas", + label: "Vertex Llama 3.1 405B", + provider: "VERTEX_AI", + contextWindow: "128K", + }, + { + value: "mistral-large@2411-001", + label: "Vertex Mistral Large", + provider: "VERTEX_AI", + contextWindow: "128K", + }, + + // Groq + { + value: "llama-3.3-70b-versatile", + label: "Groq Llama 3.3 70B", + provider: "GROQ", + contextWindow: "128K", + }, + { + value: "llama-3.3-70b-specdec", + label: "Groq Llama 3.3 70B Specdec", + provider: "GROQ", + contextWindow: "8K", + }, + { + value: "llama-3.1-70b-versatile", + label: "Groq Llama 3.1 70B", + provider: "GROQ", + contextWindow: "8K", + }, + { + value: "llama-3.1-8b-instant", + label: "Groq Llama 3.1 8B", + provider: "GROQ", + contextWindow: "128K", + }, + { + value: "llama-3.2-90b-vision-preview", + label: "Groq Llama 3.2 90B Vision", + provider: "GROQ", + contextWindow: "8K", + }, + { + value: "llama-3.2-11b-vision-preview", + label: "Groq Llama 3.2 11B Vision", + provider: "GROQ", + contextWindow: "8K", + }, + { + value: "llama-3.2-3b-preview", + label: "Groq Llama 3.2 3B", + provider: "GROQ", + contextWindow: "8K", + }, + { + value: "llama-3.2-1b-preview", + label: "Groq Llama 3.2 1B", + provider: "GROQ", + contextWindow: "8K", + }, + { + value: "mixtral-8x7b-32768", + label: "Groq Mixtral 8x7B", + provider: "GROQ", + contextWindow: "33K", + }, + { + value: "gemma2-9b-it", + label: "Groq Gemma 2 9B", + provider: "GROQ", + contextWindow: "8K", + }, + { + value: "deepseek-r1-distill-llama-70b", + label: "Groq DeepSeek R1 Distill", + provider: "GROQ", + contextWindow: "128K", + }, + { + value: "meta-llama/llama-4-maverick-17b-128e-instruct", + label: "Groq Llama 4 Maverick", + provider: "GROQ", + contextWindow: "131K", + }, + { + value: "meta-llama/llama-4-scout-17b-16e-instruct", + label: "Groq Llama 4 Scout", + provider: "GROQ", + contextWindow: "131K", + }, + { + value: "openai/gpt-oss-120b", + label: "Groq GPT-OSS-120B", + provider: "GROQ", + contextWindow: "131K", + }, + { + value: "openai/gpt-oss-20b", + label: "Groq GPT-OSS-20B", + provider: "GROQ", + contextWindow: "131K", + }, + { + value: "moonshotai/kimi-k2-instruct", + label: "Groq Kimi K2", + provider: "GROQ", + contextWindow: "131K", + }, + + // Cohere + { + value: "command-a-03-2025", + label: "Command A (03-2025)", + provider: "COHERE", + contextWindow: "256K", + }, + { + value: "command-r-plus", + label: "Command R+", + provider: "COHERE", + contextWindow: "128K", + }, + { + value: "command-r", + label: "Command R", + provider: "COHERE", + contextWindow: "128K", + }, + { + value: "command-r-plus-08-2024", + label: "Command R+ (08-2024)", + provider: "COHERE", + contextWindow: "128K", + }, + { + value: "command-r-08-2024", + label: "Command R (08-2024)", + provider: "COHERE", + contextWindow: "128K", + }, + { + value: "command", + label: "Command", + provider: "COHERE", + contextWindow: "4K", + }, + + // Mistral + { + value: "mistral-large-latest", + label: "Mistral Large Latest", + provider: "MISTRAL", + contextWindow: "128K", + }, + { + value: "mistral-large-2411", + label: "Mistral Large 2411", + provider: "MISTRAL", + contextWindow: "128K", + }, + { + value: "mistral-medium-latest", + label: "Mistral Medium Latest", + provider: "MISTRAL", + contextWindow: "131K", + }, + { + value: "mistral-medium-2505", + label: "Mistral Medium 2505", + provider: "MISTRAL", + contextWindow: "131K", + }, + { + value: "mistral-small-latest", + label: "Mistral Small Latest", + provider: "MISTRAL", + contextWindow: "32K", + }, + { + value: "open-mistral-nemo", + label: "Mistral Nemo", + provider: "MISTRAL", + contextWindow: "128K", + }, + { + value: "open-mixtral-8x7b", + label: "Mixtral 8x7B", + provider: "MISTRAL", + contextWindow: "32K", + }, + { + value: "open-mixtral-8x22b", + label: "Mixtral 8x22B", + provider: "MISTRAL", + contextWindow: "65K", + }, + { + value: "codestral-latest", + label: "Codestral Latest", + provider: "MISTRAL", + contextWindow: "32K", + }, + { + value: "pixtral-large-latest", + label: "Pixtral Large Latest", + provider: "MISTRAL", + contextWindow: "128K", + }, + { + value: "magistral-medium-latest", + label: "Magistral Medium Latest", + provider: "MISTRAL", + contextWindow: "40K", + }, + + // Together AI + { + value: "meta-llama/Meta-Llama-3.3-70B-Instruct-Turbo", + label: "Together Llama 3.3 70B Turbo", + provider: "TOGETHER_AI", + contextWindow: "128K", + }, + { + value: "meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo", + label: "Together Llama 3.1 405B Turbo", + provider: "TOGETHER_AI", + contextWindow: "128K", + }, + { + value: "meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo", + label: "Together Llama 3.1 70B Turbo", + provider: "TOGETHER_AI", + contextWindow: "128K", + }, + { + value: "meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo", + label: "Together Llama 3.1 8B Turbo", + provider: "TOGETHER_AI", + contextWindow: "128K", + }, + { + value: "meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8", + label: "Together Llama 4 Maverick", + provider: "TOGETHER_AI", + contextWindow: "131K", + }, + { + value: "meta-llama/Llama-4-Scout-17B-16E-Instruct", + label: "Together Llama 4 Scout", + provider: "TOGETHER_AI", + contextWindow: "131K", + }, + { + value: "deepseek-ai/DeepSeek-V3.1", + label: "Together DeepSeek V3.1", + provider: "TOGETHER_AI", + contextWindow: "128K", + }, + { + value: "deepseek-ai/DeepSeek-V3", + label: "Together DeepSeek V3", + provider: "TOGETHER_AI", + contextWindow: "66K", + }, + { + value: "deepseek-ai/DeepSeek-R1", + label: "Together DeepSeek R1", + provider: "TOGETHER_AI", + contextWindow: "128K", + }, + { + value: "mistralai/Mixtral-8x7B-Instruct-v0.1", + label: "Together Mixtral 8x7B", + provider: "TOGETHER_AI", + contextWindow: "32K", + }, + { + value: "Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8", + label: "Together Qwen3 Coder 480B", + provider: "TOGETHER_AI", + contextWindow: "256K", + }, + { + value: "Qwen/Qwen3-235B-A22B-Instruct-2507-tput", + label: "Together Qwen3 235B", + provider: "TOGETHER_AI", + contextWindow: "262K", + }, + { + value: "moonshotai/Kimi-K2-Instruct", + label: "Together Kimi K2", + provider: "TOGETHER_AI", + contextWindow: "131K", + }, + { + value: "openai/gpt-oss-120b", + label: "Together GPT-OSS-120B", + provider: "TOGETHER_AI", + contextWindow: "128K", + }, + { + value: "openai/gpt-oss-20b", + label: "Together GPT-OSS-20B", + provider: "TOGETHER_AI", + contextWindow: "128K", + }, + + // Fireworks AI + { + value: "accounts/fireworks/models/llama-v3p3-70b-instruct", + label: "Fireworks Llama 3.3 70B", + provider: "FIREWORKS_AI", + contextWindow: "131K", + }, + { + value: "accounts/fireworks/models/llama-v3p1-405b-instruct", + label: "Fireworks Llama 3.1 405B", + provider: "FIREWORKS_AI", + contextWindow: "128K", + }, + { + value: "accounts/fireworks/models/llama4-maverick-instruct-basic", + label: "Fireworks Llama 4 Maverick", + provider: "FIREWORKS_AI", + contextWindow: "131K", + }, + { + value: "accounts/fireworks/models/llama4-scout-instruct-basic", + label: "Fireworks Llama 4 Scout", + provider: "FIREWORKS_AI", + contextWindow: "131K", + }, + { + value: "accounts/fireworks/models/deepseek-v3p1", + label: "Fireworks DeepSeek V3.1", + provider: "FIREWORKS_AI", + contextWindow: "128K", + }, + { + value: "accounts/fireworks/models/deepseek-v3", + label: "Fireworks DeepSeek V3", + provider: "FIREWORKS_AI", + contextWindow: "128K", + }, + { + value: "accounts/fireworks/models/deepseek-r1", + label: "Fireworks DeepSeek R1", + provider: "FIREWORKS_AI", + contextWindow: "128K", + }, + { + value: "accounts/fireworks/models/mixtral-8x22b-instruct-hf", + label: "Fireworks Mixtral 8x22B", + provider: "FIREWORKS_AI", + contextWindow: "66K", + }, + { + value: "accounts/fireworks/models/qwen2p5-coder-32b-instruct", + label: "Fireworks Qwen2.5 Coder 32B", + provider: "FIREWORKS_AI", + contextWindow: "4K", + }, + { + value: "accounts/fireworks/models/kimi-k2-instruct", + label: "Fireworks Kimi K2", + provider: "FIREWORKS_AI", + contextWindow: "131K", + }, + + // Replicate + { + value: "meta/llama-3-70b-instruct", + label: "Replicate Llama 3 70B", + provider: "REPLICATE", + contextWindow: "8K", + }, + { + value: "meta/llama-3-8b-instruct", + label: "Replicate Llama 3 8B", + provider: "REPLICATE", + contextWindow: "8K", + }, + { + value: "meta/llama-2-70b-chat", + label: "Replicate Llama 2 70B", + provider: "REPLICATE", + contextWindow: "4K", + }, + { + value: "mistralai/mixtral-8x7b-instruct-v0.1", + label: "Replicate Mixtral 8x7B", + provider: "REPLICATE", + contextWindow: "4K", + }, + + // Perplexity + { + value: "sonar-pro", + label: "Sonar Pro", + provider: "PERPLEXITY", + contextWindow: "200K", + }, + { + value: "sonar", + label: "Sonar", + provider: "PERPLEXITY", + contextWindow: "128K", + }, + { + value: "sonar-reasoning-pro", + label: "Sonar Reasoning Pro", + provider: "PERPLEXITY", + contextWindow: "128K", + }, + { + value: "sonar-reasoning", + label: "Sonar Reasoning", + provider: "PERPLEXITY", + contextWindow: "128K", + }, + { + value: "llama-3.1-sonar-large-128k-online", + label: "Llama 3.1 Sonar Large Online", + provider: "PERPLEXITY", + contextWindow: "127K", + }, + { + value: "llama-3.1-sonar-small-128k-online", + label: "Llama 3.1 Sonar Small Online", + provider: "PERPLEXITY", + contextWindow: "127K", + }, + + // OpenRouter + { + value: "anthropic/claude-4-opus", + label: "OpenRouter Claude 4 Opus", + provider: "OPENROUTER", + contextWindow: "200K", + }, + { + value: "anthropic/claude-sonnet-4", + label: "OpenRouter Claude Sonnet 4", + provider: "OPENROUTER", + contextWindow: "1M", + }, + { + value: "anthropic/claude-3.7-sonnet", + label: "OpenRouter Claude 3.7 Sonnet", + provider: "OPENROUTER", + contextWindow: "200K", + }, + { + value: "anthropic/claude-3.5-sonnet", + label: "OpenRouter Claude 3.5 Sonnet", + provider: "OPENROUTER", + contextWindow: "200K", + }, + { + value: "openai/gpt-5", + label: "OpenRouter GPT-5", + provider: "OPENROUTER", + contextWindow: "272K", + }, + { + value: "openai/gpt-4.1", + label: "OpenRouter GPT-4.1", + provider: "OPENROUTER", + contextWindow: "1M", + }, + { + value: "openai/gpt-4o", + label: "OpenRouter GPT-4o", + provider: "OPENROUTER", + contextWindow: "128K", + }, + { + value: "openai/o3-mini", + label: "OpenRouter O3 Mini", + provider: "OPENROUTER", + contextWindow: "128K", + }, + { + value: "x-ai/grok-4", + label: "OpenRouter Grok 4", + provider: "OPENROUTER", + contextWindow: "256K", + }, + { + value: "deepseek/deepseek-chat-v3.1", + label: "OpenRouter DeepSeek Chat V3.1", + provider: "OPENROUTER", + contextWindow: "164K", + }, + { + value: "deepseek/deepseek-r1", + label: "OpenRouter DeepSeek R1", + provider: "OPENROUTER", + contextWindow: "65K", + }, + { + value: "google/gemini-2.5-flash", + label: "OpenRouter Gemini 2.5 Flash", + provider: "OPENROUTER", + contextWindow: "1M", + }, + { + value: "google/gemini-2.5-pro", + label: "OpenRouter Gemini 2.5 Pro", + provider: "OPENROUTER", + contextWindow: "1M", + }, + + // Ollama (Local) + { + value: "llama3.3", + label: "Ollama Llama 3.3", + provider: "OLLAMA", + contextWindow: "128K", + }, + { + value: "llama3.1", + label: "Ollama Llama 3.1", + provider: "OLLAMA", + contextWindow: "8K", + }, + { + value: "llama3", + label: "Ollama Llama 3", + provider: "OLLAMA", + contextWindow: "8K", + }, + { + value: "llama2", + label: "Ollama Llama 2", + provider: "OLLAMA", + contextWindow: "4K", + }, + { + value: "mistral", + label: "Ollama Mistral", + provider: "OLLAMA", + contextWindow: "8K", + }, + { + value: "mixtral-8x7B-Instruct-v0.1", + label: "Ollama Mixtral 8x7B", + provider: "OLLAMA", + contextWindow: "33K", + }, + { + value: "codellama", + label: "Ollama CodeLlama", + provider: "OLLAMA", + contextWindow: "4K", + }, + { + value: "deepseek-coder-v2-instruct", + label: "Ollama DeepSeek Coder V2", + provider: "OLLAMA", + contextWindow: "33K", + }, + + // Alibaba Qwen + { + value: "qwen-plus", + label: "Qwen Plus", + provider: "ALIBABA_QWEN", + contextWindow: "129K", + }, + { + value: "qwen-turbo", + label: "Qwen Turbo", + provider: "ALIBABA_QWEN", + contextWindow: "129K", + }, + { + value: "qwen-max", + label: "Qwen Max", + provider: "ALIBABA_QWEN", + contextWindow: "31K", + }, + { + value: "qwen-coder", + label: "Qwen Coder", + provider: "ALIBABA_QWEN", + contextWindow: "1M", + }, + { + value: "qwen3-32b", + label: "Qwen3 32B", + provider: "ALIBABA_QWEN", + contextWindow: "131K", + }, + { + value: "qwen3-30b-a3b", + label: "Qwen3 30B-A3B", + provider: "ALIBABA_QWEN", + contextWindow: "129K", + }, + { + value: "qwen3-coder-plus", + label: "Qwen3 Coder Plus", + provider: "ALIBABA_QWEN", + contextWindow: "998K", + }, + { + value: "qwq-plus", + label: "QwQ Plus", + provider: "ALIBABA_QWEN", + contextWindow: "98K", + }, + + // Moonshot (Kimi) + { + value: "kimi-latest", + label: "Kimi Latest", + provider: "MOONSHOT", + contextWindow: "131K", + }, + { + value: "kimi-k2-thinking", + label: "Kimi K2 Thinking", + provider: "MOONSHOT", + contextWindow: "262K", + }, + { + value: "moonshot-v1-128k", + label: "Moonshot V1 128K", + provider: "MOONSHOT", + contextWindow: "131K", + }, + { + value: "moonshot-v1-32k", + label: "Moonshot V1 32K", + provider: "MOONSHOT", + contextWindow: "33K", + }, + { + value: "moonshot-v1-8k", + label: "Moonshot V1 8K", + provider: "MOONSHOT", + contextWindow: "8K", + }, + + // Zhipu (GLM) + { + value: "z-ai/glm-4.6", + label: "GLM 4.6", + provider: "ZHIPU", + contextWindow: "203K", + }, + { + value: "z-ai/glm-4.6:exacto", + label: "GLM 4.6 Exacto", + provider: "ZHIPU", + contextWindow: "203K", + }, + + // Anyscale + { + value: "meta-llama/Meta-Llama-3-70B-Instruct", + label: "Anyscale Llama 3 70B", + provider: "ANYSCALE", + contextWindow: "8K", + }, + { + value: "meta-llama/Meta-Llama-3-8B-Instruct", + label: "Anyscale Llama 3 8B", + provider: "ANYSCALE", + contextWindow: "8K", + }, + { + value: "mistralai/Mixtral-8x7B-Instruct-v0.1", + label: "Anyscale Mixtral 8x7B", + provider: "ANYSCALE", + contextWindow: "16K", + }, + + // DeepInfra + { + value: "meta-llama/Meta-Llama-3.3-70B-Instruct", + label: "DeepInfra Llama 3.3 70B", + provider: "DEEPINFRA", + contextWindow: "131K", + }, + { + value: "meta-llama/Meta-Llama-3.1-405B-Instruct", + label: "DeepInfra Llama 3.1 405B", + provider: "DEEPINFRA", + contextWindow: "33K", + }, + { + value: "meta-llama/Meta-Llama-3.1-70B-Instruct", + label: "DeepInfra Llama 3.1 70B", + provider: "DEEPINFRA", + contextWindow: "131K", + }, + { + value: "deepseek-ai/DeepSeek-V3", + label: "DeepInfra DeepSeek V3", + provider: "DEEPINFRA", + contextWindow: "164K", + }, + { + value: "deepseek-ai/DeepSeek-R1", + label: "DeepInfra DeepSeek R1", + provider: "DEEPINFRA", + contextWindow: "164K", + }, + { + value: "Qwen/Qwen2.5-72B-Instruct", + label: "DeepInfra Qwen 2.5 72B", + provider: "DEEPINFRA", + contextWindow: "33K", + }, + { + value: "Qwen/Qwen3-235B-A22B", + label: "DeepInfra Qwen3 235B", + provider: "DEEPINFRA", + contextWindow: "131K", + }, + { + value: "google/gemini-2.5-flash", + label: "DeepInfra Gemini 2.5 Flash", + provider: "DEEPINFRA", + contextWindow: "1M", + }, + { + value: "anthropic/claude-3-7-sonnet-latest", + label: "DeepInfra Claude 3.7 Sonnet", + provider: "DEEPINFRA", + contextWindow: "200K", + }, + + // Cerebras + { + value: "llama-3.3-70b", + label: "Cerebras Llama 3.3 70B", + provider: "CEREBRAS", + contextWindow: "128K", + }, + { + value: "llama3.1-70b", + label: "Cerebras Llama 3.1 70B", + provider: "CEREBRAS", + contextWindow: "128K", + }, + { + value: "llama3.1-8b", + label: "Cerebras Llama 3.1 8B", + provider: "CEREBRAS", + contextWindow: "128K", + }, + { + value: "qwen-3-32b", + label: "Cerebras Qwen 3 32B", + provider: "CEREBRAS", + contextWindow: "128K", + }, + { + value: "openai/gpt-oss-120b", + label: "Cerebras GPT-OSS-120B", + provider: "CEREBRAS", + contextWindow: "131K", + }, + + // SambaNova + { + value: "Meta-Llama-3.3-70B-Instruct", + label: "SambaNova Llama 3.3 70B", + provider: "SAMBANOVA", + contextWindow: "131K", + }, + { + value: "Meta-Llama-3.1-405B-Instruct", + label: "SambaNova Llama 3.1 405B", + provider: "SAMBANOVA", + contextWindow: "16K", + }, + { + value: "Meta-Llama-3.1-8B-Instruct", + label: "SambaNova Llama 3.1 8B", + provider: "SAMBANOVA", + contextWindow: "16K", + }, + { + value: "DeepSeek-R1", + label: "SambaNova DeepSeek R1", + provider: "SAMBANOVA", + contextWindow: "33K", + }, + { + value: "DeepSeek-V3-0324", + label: "SambaNova DeepSeek V3", + provider: "SAMBANOVA", + contextWindow: "33K", + }, + { + value: "Llama-4-Maverick-17B-128E-Instruct", + label: "SambaNova Llama 4 Maverick", + provider: "SAMBANOVA", + contextWindow: "131K", + }, + { + value: "Llama-4-Scout-17B-16E-Instruct", + label: "SambaNova Llama 4 Scout", + provider: "SAMBANOVA", + contextWindow: "8K", + }, + { + value: "QwQ-32B", + label: "SambaNova QwQ 32B", + provider: "SAMBANOVA", + contextWindow: "16K", + }, + { + value: "Qwen3-32B", + label: "SambaNova Qwen3 32B", + provider: "SAMBANOVA", + contextWindow: "8K", + }, + + // AI21 Labs + { + value: "jamba-1.5-large", + label: "Jamba 1.5 Large", + provider: "AI21", + contextWindow: "256K", + }, + { + value: "jamba-1.5-mini", + label: "Jamba 1.5 Mini", + provider: "AI21", + contextWindow: "256K", + }, + { + value: "jamba-large-1.6", + label: "Jamba Large 1.6", + provider: "AI21", + contextWindow: "256K", + }, + { + value: "jamba-mini-1.6", + label: "Jamba Mini 1.6", + provider: "AI21", + contextWindow: "256K", + }, + + // Cloudflare + { + value: "@cf/meta/llama-2-7b-chat-fp16", + label: "Cloudflare Llama 2 7B", + provider: "CLOUDFLARE", + contextWindow: "3K", + }, + { + value: "@cf/mistral/mistral-7b-instruct-v0.1", + label: "Cloudflare Mistral 7B", + provider: "CLOUDFLARE", + contextWindow: "8K", + }, + + // Databricks + { + value: "databricks-meta-llama-3-3-70b-instruct", + label: "Databricks Llama 3.3 70B", + provider: "DATABRICKS", + contextWindow: "128K", + }, + { + value: "databricks-meta-llama-3-1-405b-instruct", + label: "Databricks Llama 3.1 405B", + provider: "DATABRICKS", + contextWindow: "128K", + }, + { + value: "databricks-claude-3-7-sonnet", + label: "Databricks Claude 3.7 Sonnet", + provider: "DATABRICKS", + contextWindow: "200K", + }, + { + value: "databricks-llama-4-maverick", + label: "Databricks Llama 4 Maverick", + provider: "DATABRICKS", + contextWindow: "128K", + }, +]; + +// Helper function to get models by provider +export function getModelsByProvider(provider: string): LLMModel[] { + return LLM_MODELS.filter((model) => model.provider === provider); +} + +// Helper function to get all providers that have models +export function getProvidersWithModels(): string[] { + return Array.from(new Set(LLM_MODELS.map((model) => model.provider))); +} diff --git a/surfsense_web/contracts/enums/llm-providers.ts b/surfsense_web/contracts/enums/llm-providers.ts index 814ea16cf..cbe33d840 100644 --- a/surfsense_web/contracts/enums/llm-providers.ts +++ b/surfsense_web/contracts/enums/llm-providers.ts @@ -3,127 +3,180 @@ export interface LLMProvider { label: string; example: string; description: string; - apiBase?: string; // Default API Base URL for the provider / 提供商的默认 API Base URL + apiBase?: string; } export const LLM_PROVIDERS: LLMProvider[] = [ { value: "OPENAI", label: "OpenAI", - example: "gpt-4o, gpt-4, gpt-3.5-turbo", - description: "Industry-leading GPT models with broad capabilities", + example: "gpt-4o, gpt-4o-mini, o1, o3-mini", + description: "Industry-leading GPT models", }, { value: "ANTHROPIC", label: "Anthropic", - example: "claude-3-5-sonnet-20241022, claude-3-opus-20240229", - description: "Claude models with strong reasoning and long context windows", + example: "claude-3-5-sonnet, claude-3-opus, claude-4-sonnet", + description: "Claude models with strong reasoning", }, { - value: "GROQ", - label: "Groq", - example: "llama3-70b-8192, mixtral-8x7b-32768", - description: "Lightning-fast inference with custom LPU hardware", - }, - { - value: "COHERE", - label: "Cohere", - example: "command-r-plus, command-r", - description: "Enterprise NLP models optimized for business applications", - }, - { - value: "HUGGINGFACE", - label: "HuggingFace", - example: "microsoft/DialoGPT-medium", - description: "Access thousands of open-source models", + value: "GOOGLE", + label: "Google (Gemini)", + example: "gemini-2.5-flash, gemini-2.5-pro, gemini-1.5-pro", + description: "Gemini models with multimodal capabilities", }, { value: "AZURE_OPENAI", label: "Azure OpenAI", - example: "gpt-4, gpt-35-turbo", - description: "OpenAI models with Microsoft Azure enterprise features", + example: "azure/gpt-4o, azure/gpt-4o-mini", + description: "OpenAI models on Azure", }, { - value: "GOOGLE", - label: "Google", - example: "gemini-pro, gemini-pro-vision", - description: "Gemini models with multimodal capabilities", - }, - { - value: "AWS_BEDROCK", + value: "BEDROCK", label: "AWS Bedrock", - example: "anthropic.claude-v2", - description: "Fully managed foundation models on AWS infrastructure", + example: "anthropic.claude-3-5-sonnet, meta.llama3-70b", + description: "Foundation models on AWS", }, { - value: "OLLAMA", - label: "Ollama", - example: "llama2, codellama", - description: "Run open-source models locally on your machine", + value: "VERTEX_AI", + label: "Google Vertex AI", + example: "vertex_ai/claude-3-5-sonnet, vertex_ai/gemini-2.5-pro", + description: "Models on Google Cloud Vertex AI", + }, + { + value: "GROQ", + label: "Groq", + example: "groq/llama-3.3-70b-versatile, groq/mixtral-8x7b", + description: "Ultra-fast inference", + }, + { + value: "COHERE", + label: "Cohere", + example: "command-a-03-2025, command-r-plus", + description: "Enterprise NLP models", }, { value: "MISTRAL", - label: "Mistral", - example: "mistral-large-latest, mistral-medium", - description: "High-performance open-source models from Europe", + label: "Mistral AI", + example: "mistral-large-latest, mistral-medium-latest", + description: "European open-source models", }, { - value: "TOGETHER_AI", - label: "Together AI", - example: "togethercomputer/llama-2-70b-chat", - description: "Scalable cloud platform for open-source models", + value: "DEEPSEEK", + label: "DeepSeek", + example: "deepseek-chat, deepseek-reasoner", + description: "High-performance reasoning models", + apiBase: "https://api.deepseek.com", }, { - value: "REPLICATE", - label: "Replicate", - example: "meta/llama-2-70b-chat", - description: "Cloud API for running machine learning models", + value: "XAI", + label: "xAI (Grok)", + example: "grok-4, grok-3, grok-3-mini", + description: "Grok models from xAI", }, { value: "OPENROUTER", label: "OpenRouter", - example: "anthropic/claude-opus-4.1, openai/gpt-5", - description: "Unified API gateway for multiple LLM providers", + example: "openrouter/anthropic/claude-4-opus", + description: "Unified API for multiple providers", }, { - value: "COMETAPI", - label: "CometAPI", - example: "gpt-5-mini, claude-sonnet-4-5", - description: "Access 500+ AI models through one unified API", + value: "TOGETHER_AI", + label: "Together AI", + example: "together_ai/meta-llama/Llama-3.3-70B-Instruct-Turbo", + description: "Fast open-source models", }, - // Chinese LLM Providers / 国产 LLM 提供商 { - value: "DEEPSEEK", - label: "DeepSeek", - example: "deepseek-chat, deepseek-coder", - description: "Chinese high-performance AI models", - apiBase: "https://api.deepseek.com", + value: "FIREWORKS_AI", + label: "Fireworks AI", + example: "fireworks_ai/accounts/fireworks/models/llama-v3p3-70b-instruct", + description: "Scalable inference platform", + }, + { + value: "REPLICATE", + label: "Replicate", + example: "replicate/meta/llama-3-70b-instruct", + description: "ML model hosting platform", + }, + { + value: "PERPLEXITY", + label: "Perplexity", + example: "perplexity/sonar-pro, perplexity/sonar-reasoning", + description: "Search-augmented models", + }, + { + value: "OLLAMA", + label: "Ollama", + example: "ollama/llama3.1, ollama/mistral", + description: "Run models locally", }, { value: "ALIBABA_QWEN", - label: "Qwen", - example: "qwen-max, qwen-plus, qwen-turbo", - description: "Alibaba Cloud Qwen LLM", + label: "Alibaba Qwen", + example: "dashscope/qwen-plus, dashscope/qwen-turbo", + description: "Qwen series models", apiBase: "https://dashscope.aliyuncs.com/compatible-mode/v1", }, { value: "MOONSHOT", - label: "Kimi", - example: "moonshot-v1-8k, moonshot-v1-32k, moonshot-v1-128k", - description: "Moonshot AI Kimi models", + label: "Moonshot (Kimi)", + example: "moonshot/kimi-latest, moonshot/kimi-k2-thinking", + description: "Kimi AI models", apiBase: "https://api.moonshot.cn/v1", }, { value: "ZHIPU", - label: "GLM", - example: "glm-4, glm-4-flash, glm-3-turbo", - description: "Zhipu AI GLM series models", + label: "Zhipu (GLM)", + example: "openrouter/z-ai/glm-4.6", + description: "GLM series models", apiBase: "https://open.bigmodel.cn/api/paas/v4", }, + { + value: "ANYSCALE", + label: "Anyscale", + example: "anyscale/meta-llama/Meta-Llama-3-70B-Instruct", + description: "Ray-based inference platform", + }, + { + value: "DEEPINFRA", + label: "DeepInfra", + example: "deepinfra/meta-llama/Meta-Llama-3.3-70B-Instruct", + description: "Serverless GPU inference", + }, + { + value: "CEREBRAS", + label: "Cerebras", + example: "cerebras/llama-3.3-70b, cerebras/qwen-3-32b", + description: "Fastest inference with Wafer-Scale Engine", + }, + { + value: "SAMBANOVA", + label: "SambaNova", + example: "sambanova/Meta-Llama-3.3-70B-Instruct", + description: "AI inference platform", + }, + { + value: "AI21", + label: "AI21 Labs", + example: "jamba-1.5-large, jamba-1.5-mini", + description: "Jamba series models", + }, + { + value: "CLOUDFLARE", + label: "Cloudflare Workers AI", + example: "cloudflare/@cf/meta/llama-2-7b-chat", + description: "AI on Cloudflare edge network", + }, + { + value: "DATABRICKS", + label: "Databricks", + example: "databricks/databricks-meta-llama-3-3-70b-instruct", + description: "Databricks Model Serving", + }, { value: "CUSTOM", label: "Custom Provider", example: "your-custom-model", - description: "Connect to your own custom model endpoint", + description: "Custom OpenAI-compatible endpoint", }, ]; diff --git a/surfsense_web/package.json b/surfsense_web/package.json index 8181c5422..accb237a3 100644 --- a/surfsense_web/package.json +++ b/surfsense_web/package.json @@ -56,6 +56,7 @@ "canvas-confetti": "^1.9.3", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", + "cmdk": "^1.1.1", "date-fns": "^4.1.0", "dotenv": "^17.2.3", "drizzle-orm": "^0.44.5", diff --git a/surfsense_web/pnpm-lock.yaml b/surfsense_web/pnpm-lock.yaml index 3a3c8fc82..777e53773 100644 --- a/surfsense_web/pnpm-lock.yaml +++ b/surfsense_web/pnpm-lock.yaml @@ -113,6 +113,9 @@ importers: clsx: specifier: ^2.1.1 version: 2.1.1 + cmdk: + specifier: ^1.1.1 + version: 1.1.1(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) date-fns: specifier: ^4.1.0 version: 4.1.0 @@ -2783,6 +2786,12 @@ packages: react: ^18.0.0 react-dom: ^18.0.0 + cmdk@1.1.1: + resolution: {integrity: sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==} + peerDependencies: + react: ^18 || ^19 || ^19.0.0-rc + react-dom: ^18 || ^19 || ^19.0.0-rc + codemirror@6.0.2: resolution: {integrity: sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==} @@ -8493,6 +8502,18 @@ snapshots: transitivePeerDependencies: - '@types/react' + cmdk@1.1.1(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-dialog': 1.1.14(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.8)(react@19.1.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.6(@types/react@19.1.8))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + codemirror@6.0.2: dependencies: '@codemirror/autocomplete': 6.18.6