/** * Shared LLM provider constants. * * Single source of truth for provider configuration used by both * server-side endpoints and client-side Svelte components. */ /** Supported LLM providers. */ export const LLM_PROVIDERS = [ "openai", "ollama", "groq", "together", "mistral", "deepseek", "xai", "lmstudio", "model-runner", "google", "huggingface", "openai-compatible", ] as const; /** Default base URLs per provider. */ export const PROVIDER_DEFAULT_URLS: Record = { openai: "https://api.openai.com", groq: "https://api.groq.com/openai", mistral: "https://api.mistral.ai", together: "https://api.together.xyz", deepseek: "https://api.deepseek.com", xai: "https://api.x.ai", lmstudio: "http://host.docker.internal:1234", ollama: "http://host.docker.internal:11434", "model-runner": "http://model-runner.docker.internal/engines", google: "https://generativelanguage.googleapis.com", huggingface: "https://router.huggingface.co/v1", }; /** Map provider name → env var for the API key. */ export const PROVIDER_KEY_MAP: Record = { openai: "OPENAI_API_KEY", groq: "GROQ_API_KEY", mistral: "MISTRAL_API_KEY", google: "GOOGLE_API_KEY", deepseek: "DEEPSEEK_API_KEY", together: "TOGETHER_API_KEY", xai: "XAI_API_KEY", huggingface: "HF_TOKEN", }; export type HardwareProfileVariant = 'cpu' | 'cuda' | 'rocm'; /** Known embedding model dimensions. Keyed by `provider/model`. */ export const EMBEDDING_DIMS: Record = { "openai/text-embedding-3-small": 1536, "openai/text-embedding-3-large": 3072, "openai/text-embedding-ada-002": 1536, "ollama/nomic-embed-text": 768, "ollama/mxbai-embed-large": 1024, "ollama/mxbai-embed-large-v1": 1024, "ollama/all-minilm": 384, "ollama/snowflake-arctic-embed": 1024, "model-runner/ai/mxbai-embed-large-v1": 1024, "mistral/mistral-embed": 1024, "google/text-embedding-004": 768, "huggingface/sentence-transformers/all-MiniLM-L6-v2": 384, "huggingface/intfloat/multilingual-e5-large": 1024, }; /** Bare model-name lookup used by the browser wizard helpers. */ export const KNOWN_EMBEDDING_MODEL_DIMS: Record = Object.fromEntries( Object.entries(EMBEDDING_DIMS).map(([key, dims]) => [key.slice(key.indexOf('/') + 1), dims]) ); /** * Look up embedding model dimensions. Tries the full key first, then strips * any trailing `:tag` from the model name (Ollama-style versions). * Returns 0 when no match is found. */ export function lookupEmbeddingDims(provider: string, model: string): number { if (!provider || !model) return 0; const key = `${provider}/${model}`; if (EMBEDDING_DIMS[key]) return EMBEDDING_DIMS[key]; const colon = model.lastIndexOf(":"); if (colon > 0) { const bare = `${provider}/${model.slice(0, colon)}`; if (EMBEDDING_DIMS[bare]) return EMBEDDING_DIMS[bare]; } return 0; } /** Provider display labels for UI. */ export const PROVIDER_LABELS: Record = { openai: "OpenAI", ollama: "Ollama", groq: "Groq", together: "Together AI", mistral: "Mistral", deepseek: "DeepSeek", xai: "xAI (Grok)", lmstudio: "LM Studio", "model-runner": "Docker Model Runner", google: "Google AI", huggingface: "Hugging Face", "openai-compatible": "Custom (OpenAI-compatible)", }; /** Default models to pull when enabling Ollama from the wizard. */ export const OLLAMA_DEFAULT_MODELS = { chat: "llama3.2:latest", embedding: "nomic-embed-text", } as const; export const OLLAMA_DEFAULT_CHAT_MODEL = OLLAMA_DEFAULT_MODELS.chat; /** * Base URL for Ollama when running as an in-stack compose service. * Uses Docker network name instead of host.docker.internal. */ export const OLLAMA_INSTACK_URL = "http://ollama:11434"; export function addonProfileId(addon: string, variant: HardwareProfileVariant): string { return `addon.${addon}.${variant}`; } /** Contextual help for local/self-hosted providers. */ export const LOCAL_PROVIDER_HELP: Record = { "model-runner": "Add models with: docker model pull ai/model-name", ollama: "Add models with: ollama pull model-name", lmstudio: "Download models from the LM Studio Discover tab.", };