// Provider definitions

// Free Providers
export const FREE_PROVIDERS = {
  qoder: { id: "qoder", alias: "if", name: "Qoder AI", icon: "water_drop", color: "#6366F1" },
  qwen: {
    id: "qwen",
    alias: "qw",
    name: "Qwen Code",
    icon: "psychology",
    color: "#10B981",
    deprecated: true,
    deprecationReason:
      "Qwen OAuth free tier was discontinued on 2026-04-15. Use 'alicode', 'alicode-intl', or 'openrouter' provider with API key instead.",
  },
  "gemini-cli": {
    id: "gemini-cli",
    alias: "gemini-cli",
    name: "Gemini CLI",
    icon: "terminal",
    color: "#4285F4",
    deprecated: true,
    deprecationReason:
      "Google restricts third-party OAuth usage for Gemini CLI (Mar 2026). Pro models require paid plans. Use 'gemini' (API key) provider instead.",
  },
  kiro: { id: "kiro", alias: "kr", name: "Kiro AI", icon: "psychology_alt", color: "#FF6B35" },
  "amazon-q": {
    id: "amazon-q",
    alias: "aq",
    name: "Amazon Q",
    icon: "cloud",
    color: "#FF9900",
    textIcon: "AQ",
    website: "https://aws.amazon.com/q/developer/",
    authHint:
      "Uses the same AWS Builder ID or imported refresh-token flow as Kiro, but keeps Amazon Q connections separate.",
  },
};

export const FREE_APIKEY_PROVIDER_IDS = new Set(["qoder"]);

export function supportsApiKeyOnFreeProvider(providerId: unknown): boolean {
  return typeof providerId === "string" && FREE_APIKEY_PROVIDER_IDS.has(providerId);
}

// OAuth Providers
export const OAUTH_PROVIDERS = {
  claude: { id: "claude", alias: "cc", name: "Claude Code", icon: "smart_toy", color: "#D97757" },
  antigravity: {
    id: "antigravity",
    alias: undefined,
    name: "Antigravity",
    icon: "rocket_launch",
    color: "#F59E0B",
  },
  codex: { id: "codex", alias: "cx", name: "OpenAI Codex", icon: "code", color: "#3B82F6" },
  github: { id: "github", alias: "gh", name: "GitHub Copilot", icon: "code", color: "#333333" },
  "gitlab-duo": {
    id: "gitlab-duo",
    alias: "gitlab-duo",
    name: "GitLab Duo",
    icon: "hub",
    color: "#FC6D26",
    textIcon: "GL",
    website: "https://docs.gitlab.com/user/duo_agent_platform/code_suggestions/",
    authHint:
      "OAuth application with ai_features + read_user scopes. Configure GITLAB_DUO_OAUTH_CLIENT_ID and optionally GITLAB_DUO_OAUTH_CLIENT_SECRET on this OmniRoute instance.",
  },
  cursor: { id: "cursor", alias: "cu", name: "Cursor IDE", icon: "edit_note", color: "#00D4AA" },
  "kimi-coding": {
    id: "kimi-coding",
    alias: "kmc",
    name: "Kimi Coding",
    icon: "psychology",
    color: "#1E40AF",
    textIcon: "KC",
  },
  kilocode: {
    id: "kilocode",
    alias: "kc",
    name: "Kilo Code",
    icon: "code",
    color: "#FF6B35",
    textIcon: "KC",
  },
  cline: {
    id: "cline",
    alias: "cl",
    name: "Cline",
    icon: "smart_toy",
    color: "#5B9BD5",
    textIcon: "CL",
  },
};

// Web / Cookie Providers
export const WEB_COOKIE_PROVIDERS = {
  "chatgpt-web": {
    id: "chatgpt-web",
    alias: "cgpt-web",
    name: "ChatGPT Web (Plus/Pro)",
    icon: "auto_awesome",
    color: "#10A37F",
    textIcon: "CG",
    website: "https://chatgpt.com",
    authHint: "Paste your __Secure-next-auth.session-token cookie value from chatgpt.com",
  },
  "grok-web": {
    id: "grok-web",
    alias: "gw",
    name: "Grok Web (Subscription)",
    icon: "auto_awesome",
    color: "#1DA1F2",
    textIcon: "GW",
    website: "https://grok.com",
    authHint: "Paste your sso= cookie value from grok.com",
  },
  "perplexity-web": {
    id: "perplexity-web",
    alias: "pplx-web",
    name: "Perplexity Web (Pro/Max)",
    icon: "search",
    color: "#20808D",
    textIcon: "PW",
    website: "https://www.perplexity.ai",
    authHint: "Paste your __Secure-next-auth.session-token cookie value from perplexity.ai",
  },
  "blackbox-web": {
    id: "blackbox-web",
    alias: "bb-web",
    name: "Blackbox Web (Subscription)",
    icon: "view_in_ar",
    color: "#1A1A2E",
    textIcon: "BW",
    website: "https://app.blackbox.ai",
    authHint:
      "Paste your __Secure-authjs.session-token value or full cookie header from app.blackbox.ai",
  },
  "muse-spark-web": {
    id: "muse-spark-web",
    alias: "ms-web",
    name: "Muse Spark Web (Meta AI)",
    icon: "auto_awesome",
    color: "#0866FF",
    textIcon: "MS",
    website: "https://www.meta.ai",
    authHint: "Paste your abra_sess value or full cookie header from meta.ai",
  },
};

// API Key Providers
export const APIKEY_PROVIDERS = {
  agentrouter: {
    id: "agentrouter",
    alias: "agentrouter",
    name: "AgentRouter",
    icon: "router",
    color: "#10B981",
    textIcon: "AR",
    passthroughModels: true,
    website: "https://agentrouter.org",
    hasFree: true,
    freeNote: "$200 free credits on signup - multi-model routing gateway",
    apiHint: "Get $200 free credits at https://agentrouter.org/register — no credit card required.",
  },
  openrouter: {
    id: "openrouter",
    alias: "openrouter",
    name: "OpenRouter",
    icon: "router",
    color: "#F97316",
    textIcon: "OR",
    passthroughModels: true,
    website: "https://openrouter.ai",
    hasFree: true,
    freeNote: "Free models at $0/token with :free suffix - 20 RPM / 200 RPD",
  },
  qianfan: {
    id: "qianfan",
    alias: "qianfan",
    name: "Baidu Qianfan",
    icon: "cloud",
    color: "#2468F2",
    textIcon: "BD",
    website: "https://cloud.baidu.com/product/wenxinworkshop",
    passthroughModels: true,
    apiHint:
      "Use a Qianfan API key from Baidu AI Cloud. The default endpoint is OpenAI-compatible v2.",
  },
  glm: {
    id: "glm",
    alias: "glm",
    name: "GLM Coding",
    icon: "code",
    color: "#2563EB",
    textIcon: "GL",
    website: "https://open.bigmodel.cn",
  },
  "glm-cn": {
    id: "glm-cn",
    alias: "glmcn",
    name: "GLM Coding (China)",
    icon: "code",
    color: "#DC2626",
    textIcon: "GC",
    website: "https://open.bigmodel.cn",
  },
  glmt: {
    id: "glmt",
    alias: "glmt",
    name: "GLM Thinking",
    icon: "psychology",
    color: "#1D4ED8",
    textIcon: "GT",
    website: "https://open.bigmodel.cn",
    apiHint: "Preset GLM profile with higher token budget, thinking enabled, and longer timeout.",
  },
  "bailian-coding-plan": {
    id: "bailian-coding-plan",
    alias: "bcp",
    name: "Alibaba Coding Plan",
    icon: "code",
    color: "#FF6A00",
    textIcon: "BCP",
    website: "https://www.alibabacloud.com/help/en/model-studio/coding-plan",
  },
  kimi: {
    id: "kimi",
    alias: "kimi",
    name: "Kimi",
    icon: "psychology",
    color: "#1E3A8A",
    textIcon: "KM",
    website: "https://kimi.moonshot.cn",
  },
  "kimi-coding-apikey": {
    id: "kimi-coding-apikey",
    alias: "kmca",
    name: "Kimi Coding (API Key)",
    icon: "psychology",
    color: "#1E40AF",
    textIcon: "KC",
    website: "https://kimi.com",
  },
  minimax: {
    id: "minimax",
    alias: "minimax",
    name: "Minimax Coding",
    icon: "memory",
    color: "#7C3AED",
    textIcon: "MM",
    website: "https://www.minimaxi.com",
  },
  "minimax-cn": {
    id: "minimax-cn",
    alias: "minimax-cn",
    name: "Minimax (China)",
    icon: "memory",
    color: "#DC2626",
    textIcon: "MC",
    website: "https://www.minimaxi.com",
  },
  crof: {
    id: "crof",
    alias: "crof",
    name: "CrofAI",
    icon: "auto_awesome",
    color: "#0EA5E9",
    textIcon: "CR",
    website: "https://crof.ai",
  },
  alicode: {
    id: "alicode",
    alias: "alicode",
    name: "Alibaba",
    icon: "cloud",
    color: "#FF6A00",
    textIcon: "ALi",
    website: "https://bailian.console.aliyun.com",
  },
  "alicode-intl": {
    id: "alicode-intl",
    alias: "alicode-intl",
    name: "Alibaba Intl",
    icon: "cloud",
    color: "#FF6A00",
    textIcon: "ALi",
    website: "https://modelstudio.console.alibabacloud.com",
  },
  openai: {
    id: "openai",
    alias: "openai",
    name: "OpenAI",
    icon: "auto_awesome",
    color: "#10A37F",
    textIcon: "OA",
    website: "https://platform.openai.com",
  },
  "azure-openai": {
    id: "azure-openai",
    alias: "azure",
    name: "Azure OpenAI",
    icon: "cloud",
    color: "#0078D4",
    textIcon: "AZ",
    website: "https://azure.microsoft.com/products/ai-services/openai-service",
    authHint:
      "Use your Azure OpenAI API key. Base URL should be your resource endpoint, for example https://my-resource.openai.azure.com.",
    passthroughModels: true,
  },
  "azure-ai": {
    id: "azure-ai",
    alias: "azure-ai",
    name: "Azure AI Foundry",
    icon: "cloud",
    color: "#2563EB",
    textIcon: "AF",
    website: "https://learn.microsoft.com/azure/ai-foundry/",
    authHint:
      "Use your Azure AI Foundry key. Base URL can be https://<resource>.services.ai.azure.com/openai/v1/ or https://<resource>.openai.azure.com/openai/v1/.",
    apiHint:
      "Foundry uses the OpenAI v1 surface with deployment names as models. OmniRoute normalizes root resource URLs to the v1 chat and /models endpoints.",
    passthroughModels: true,
  },
  bedrock: {
    id: "bedrock",
    alias: "bedrock",
    name: "Amazon Bedrock",
    icon: "cloud",
    color: "#FF9900",
    textIcon: "BR",
    website: "https://aws.amazon.com/bedrock/",
    authHint:
      "Use your Amazon Bedrock API key in Authorization: Bearer <key>. OmniRoute defaults to the OpenAI-compatible bedrock-mantle endpoint in us-east-1; set a regional base URL if your account uses another region or the bedrock-runtime /openai/v1 path.",
    apiHint:
      "This integration targets Amazon Bedrock's current OpenAI-compatible surface. bedrock-mantle is the default for /models and chat; advanced users can also point baseUrl to bedrock-runtime/.../openai/v1 for runtime-specific model IDs.",
    passthroughModels: true,
  },
  watsonx: {
    id: "watsonx",
    alias: "watsonx",
    name: "IBM watsonx.ai Gateway",
    icon: "hub",
    color: "#0F62FE",
    textIcon: "WX",
    website: "https://www.ibm.com/products/watsonx-ai",
    authHint:
      "Use your watsonx bearer token. Base URL can be https://<region>.ml.cloud.ibm.com/ml/gateway/v1/ or a self-managed /ml/gateway/v1 endpoint.",
    apiHint:
      "The watsonx model gateway exposes OpenAI-compatible /chat/completions and /models under /ml/gateway/v1.",
    passthroughModels: true,
  },
  oci: {
    id: "oci",
    alias: "oci",
    name: "OCI Generative AI",
    icon: "cloud",
    color: "#C74634",
    textIcon: "OCI",
    website: "https://www.oracle.com/artificial-intelligence/generative-ai/",
    authHint:
      "Use your OCI Generative AI API key or IAM bearer token. Base URL can be https://inference.generativeai.<region>.oci.oraclecloud.com/openai/v1/.",
    apiHint:
      "OCI exposes OpenAI-compatible chat and responses endpoints. Project ID is optional in OmniRoute but may be required for Responses and agentic workflows.",
    passthroughModels: true,
  },
  sap: {
    id: "sap",
    alias: "sap",
    name: "SAP Generative AI Hub",
    icon: "business",
    color: "#0FAAFF",
    textIcon: "SAP",
    website:
      "https://help.sap.com/docs/sap-ai-core/sap-ai-core-service-guide/generative-ai-hub-in-sap-ai-core",
    authHint:
      "Use your SAP AI Core bearer token. Base URL can be your AI_API_URL root or a deploymentUrl from Generative AI Hub.",
    apiHint:
      "Model discovery uses /v2/lm/scenarios/foundation-models/models on AI_API_URL. Chat requests use deploymentUrl/chat/completions and require AI-Resource-Group.",
    passthroughModels: true,
  },
  modal: {
    id: "modal",
    alias: "mdl",
    name: "Modal",
    icon: "cloud_queue",
    color: "#7C3AED",
    textIcon: "MDL",
    website: "https://modal.com/docs",
    authHint:
      "Use the bearer token that protects your Modal deployment, if enabled. Base URL should point to your OpenAI-compatible Modal app, for example https://<workspace>--<app>.modal.run/v1.",
    apiHint:
      "Modal commonly serves user-hosted OpenAI-compatible apps on /v1. OmniRoute will probe /v1/models and route chat traffic to /v1/chat/completions.",
    hasFree: true,
    freeNote: "$30/month free credits for new accounts",
    passthroughModels: true,
  },
  reka: {
    id: "reka",
    alias: "reka",
    name: "Reka",
    icon: "auto_awesome",
    color: "#111827",
    textIcon: "RK",
    website: "https://docs.reka.ai/chat/overview",
    authHint:
      "Use your Reka API key. OmniRoute supports the OpenAI-compatible base URL https://api.reka.ai/v1 and sends both Authorization and X-Api-Key headers for compatibility.",
    apiHint:
      "Reka Chat is OpenAI-compatible on /v1. OmniRoute probes /v1/models and routes chat traffic to /v1/chat/completions.",
    hasFree: true,
    freeNote: "$10/month recurring free API credits",
    passthroughModels: true,
  },
  nlpcloud: {
    id: "nlpcloud",
    alias: "nlpc",
    name: "NLP Cloud",
    icon: "psychology",
    color: "#2196F3",
    textIcon: "NLPC",
    website: "https://docs.nlpcloud.com",
    authHint:
      "Use your NLP Cloud API key in Authorization: Token <key>. OmniRoute targets the chatbot endpoint on https://api.nlpcloud.io/v1/gpu/<model>/chatbot by default.",
    apiHint:
      "NLP Cloud uses a proprietary chatbot API instead of OpenAI chat/completions. OmniRoute adapts OpenAI messages to input/context/history and exposes a local catalog of supported chatbot models.",
    hasFree: true,
    freeNote: "Trial credits for new accounts",
  },
  runwayml: {
    id: "runwayml",
    alias: "runway",
    name: "Runway",
    icon: "movie",
    color: "#111827",
    textIcon: "RW",
    website: "https://docs.dev.runwayml.com",
    authHint:
      "Use your Runway API key in Authorization: Bearer <key>. OmniRoute targets the current Runway API at https://api.dev.runwayml.com/v1 and sends the required X-Runway-Version header automatically.",
    apiHint:
      "Runway video generation is task-based. OmniRoute submits text-to-video or image-to-video jobs, polls /v1/tasks/{id}, and normalizes the finished video outputs back into the OpenAI-like /v1/videos/generations response.",
  },
  anthropic: {
    id: "anthropic",
    alias: "anthropic",
    name: "Anthropic",
    icon: "smart_toy",
    color: "#D97757",
    textIcon: "AN",
    website: "https://console.anthropic.com",
  },
  gemini: {
    id: "gemini",
    alias: "gemini",
    name: "Gemini (Google AI Studio)",
    icon: "diamond",
    color: "#4285F4",
    textIcon: "GE",
    website: "https://ai.google.dev",
    hasFree: true,
    freeNote:
      "Free forever: 1,500 req/day for Gemini 2.5 Flash — no credit card, get key at aistudio.google.com",
  },
  deepseek: {
    id: "deepseek",
    alias: "ds",
    name: "DeepSeek",
    icon: "bolt",
    color: "#4D6BFE",
    textIcon: "DS",
    website: "https://deepseek.com",
    hasFree: true,
    freeNote: "5M free tokens on signup - no credit card required",
  },
  groq: {
    id: "groq",
    alias: "groq",
    name: "Groq",
    icon: "speed",
    color: "#F55036",
    textIcon: "GQ",
    website: "https://groq.com",
    hasFree: true,
    freeNote: "Free tier: 30 RPM / 14.4K RPD — no credit card",
  },
  blackbox: {
    id: "blackbox",
    alias: "bb",
    name: "Blackbox AI",
    icon: "view_in_ar",
    color: "#1A1A2E",
    textIcon: "BB",
    website: "https://blackbox.ai",
    hasFree: true,
    freeNote: "Free tier: unlimited basic chat plus Minimax-M2.5, no credit card required",
  },
  xai: {
    id: "xai",
    alias: "xai",
    name: "xAI (Grok)",
    icon: "auto_awesome",
    color: "#1DA1F2",
    textIcon: "XA",
    website: "https://x.ai",
  },
  mistral: {
    id: "mistral",
    alias: "mistral",
    name: "Mistral",
    icon: "air",
    color: "#FF7000",
    textIcon: "MI",
    website: "https://mistral.ai",
    hasFree: true,
    freeNote: "Free Experiment tier: rate-limited access to all models, no credit card required",
  },
  perplexity: {
    id: "perplexity",
    alias: "pplx",
    name: "Perplexity",
    icon: "search",
    color: "#20808D",
    textIcon: "PP",
    website: "https://www.perplexity.ai",
  },
  together: {
    id: "together",
    alias: "together",
    name: "Together AI",
    icon: "group_work",
    color: "#0F6FFF",
    textIcon: "TG",
    website: "https://www.together.ai",
    hasFree: true,
    freeNote:
      "$25 signup credits + 3 permanently free models: Llama 3.3 70B, Vision, DeepSeek-R1 distill",
  },
  fireworks: {
    id: "fireworks",
    alias: "fireworks",
    name: "Fireworks AI",
    icon: "local_fire_department",
    color: "#7B2EF2",
    textIcon: "FW",
    website: "https://fireworks.ai",
    hasFree: true,
    freeNote: "$1 free starter credits on signup for API testing",
  },
  cerebras: {
    id: "cerebras",
    alias: "cerebras",
    name: "Cerebras",
    icon: "memory",
    color: "#FF4F00",
    textIcon: "CB",
    website: "https://inference.cerebras.ai",
    hasFree: true,
    freeNote: "Free: 1M tokens/day, 60K TPM — world's fastest inference",
  },
  cohere: {
    id: "cohere",
    alias: "cohere",
    name: "Cohere",
    icon: "hub",
    color: "#39594D",
    textIcon: "CO",
    website: "https://cohere.com",
    hasFree: true,
    freeNote: "Free Trial: 1,000 API calls/month for testing, no credit card required",
  },
  nvidia: {
    id: "nvidia",
    alias: "nvidia",
    name: "NVIDIA NIM",
    icon: "developer_board",
    color: "#76B900",
    textIcon: "NV",
    website: "https://build.nvidia.com",
    hasFree: true,
    freeNote: "Free dev access: ~40 RPM, 70+ models (Kimi K2.5, GLM 4.7, DeepSeek V3.2...)",
  },
  nebius: {
    id: "nebius",
    alias: "nebius",
    name: "Nebius AI",
    icon: "cloud",
    color: "#6C5CE7",
    textIcon: "NB",
    website: "https://nebius.com",
    hasFree: true,
    freeNote: "~$1 trial credits on signup for API testing",
  },
  siliconflow: {
    id: "siliconflow",
    alias: "siliconflow",
    name: "SiliconFlow",
    icon: "cloud_queue",
    color: "#5B6EF5",
    textIcon: "SF",
    website: "https://cloud.siliconflow.com",
    hasFree: true,
    freeNote: "$1 free credits plus permanently free models after identity verification",
  },
  hyperbolic: {
    id: "hyperbolic",
    alias: "hyp",
    name: "Hyperbolic",
    icon: "bolt",
    color: "#00D4FF",
    textIcon: "HY",
    website: "https://hyperbolic.xyz",
    hasFree: true,
    freeNote: "$1-5 trial credits on signup for serverless inference",
  },
  nanobanana: {
    id: "nanobanana",
    alias: "nb",
    name: "NanoBanana",
    icon: "image",
    color: "#FFD700",
    textIcon: "NB",
    website: "https://nanobananaapi.ai",
  },
  "ollama-cloud": {
    id: "ollama-cloud",
    alias: "ollamacloud",
    name: "Ollama Cloud",
    icon: "cloud",
    color: "#58A6FF",
    textIcon: "OC",
    website: "https://ollama.com/settings/api-keys",
  },
  huggingface: {
    id: "huggingface",
    alias: "hf",
    name: "HuggingFace",
    icon: "face",
    color: "#FFD21E",
    textIcon: "HF",
    website: "https://huggingface.co",
    hasFree: true,
    freeNote: "Free Inference API for thousands of models (Whisper, VITS, SDXL…)",
  },
  synthetic: {
    id: "synthetic",
    alias: "synthetic",
    name: "Synthetic",
    icon: "verified_user",
    color: "#6366F1",
    textIcon: "SY",
    website: "https://synthetic.new",
    passthroughModels: true,
  },
  "kilo-gateway": {
    id: "kilo-gateway",
    alias: "kg",
    name: "Kilo Gateway",
    icon: "hub",
    color: "#617A91",
    textIcon: "KG",
    website: "https://kilo.ai",
    passthroughModels: true,
  },
  vertex: {
    id: "vertex",
    alias: "vertex",
    name: "Vertex AI",
    icon: "cloud",
    color: "#4285F4",
    textIcon: "VA",
    website: "https://cloud.google.com/vertex-ai",
    authHint: "Provide Service Account JSON or OAuth access_token",
  },
  "vertex-partner": {
    id: "vertex-partner",
    alias: "vp",
    name: "Vertex AI Partners",
    icon: "cloud",
    color: "#34A853",
    textIcon: "VP",
    website: "https://cloud.google.com/vertex-ai",
    authHint: "Provide the same Service Account JSON used for Vertex AI partner models.",
  },
  zai: {
    id: "zai",
    alias: "zai",
    name: "Z.AI",
    icon: "psychology",
    color: "#2563EB",
    textIcon: "ZA",
    website: "https://open.bigmodel.cn",
    apiHint: "API key from https://open.bigmodel.cn/usercenter/apikeys",
  },
  "opencode-zen": {
    id: "opencode-zen",
    alias: "opencode-zen",
    name: "OpenCode Zen",
    icon: "opencode",
    color: "#6366f1",
    website: "https://opencode.ai/zen",
  },
  "opencode-go": {
    id: "opencode-go",
    alias: "opencode-go",
    name: "OpenCode Go",
    icon: "opencode",
    color: "#6366f1",
    website: "https://opencode.ai/zen/go",
  },
  alibaba: {
    id: "alibaba",
    alias: "ali",
    name: "Alibaba Cloud (DashScope)",
    icon: "cloud_queue",
    color: "#FF6600",
    textIcon: "AL",
    website: "https://dashscope-intl.aliyuncs.com",
    hasFree: false,
  },
  longcat: {
    id: "longcat",
    alias: "lc",
    name: "LongCat AI",
    icon: "auto_awesome",
    color: "#FF6B9D",
    textIcon: "LC",
    website: "https://longcat.chat",
    hasFree: true,
    freeNote:
      "50M tokens/day (Flash-Lite) + 500K/day (Chat/Thinking) — 100% free while public beta",
  },
  pollinations: {
    id: "pollinations",
    alias: "pol",
    name: "Pollinations AI",
    icon: "local_florist",
    color: "#4CAF50",
    textIcon: "PO",
    website: "https://pollinations.ai",
    hasFree: false,
    freeNote: "API key required. Spore tier: ~0.01 pollen/hour ($0.01/hr).",
  },
  puter: {
    id: "puter",
    alias: "pu",
    name: "Puter AI",
    icon: "cloud_circle",
    color: "#6366F1",
    textIcon: "PU",
    website: "https://puter.com",
    hasFree: true,
    freeNote:
      "500+ models (GPT-5, Claude Opus 4, Gemini 3 Pro, Grok 4, DeepSeek V3...) — Users pay via free Puter account",
    passthroughModels: true,
    authHint: "Get token at puter.com/dashboard → Copy Auth Token",
  },
  "cloudflare-ai": {
    id: "cloudflare-ai",
    alias: "cf",
    name: "Cloudflare Workers AI",
    icon: "cloud",
    color: "#F48120",
    textIcon: "CF",
    website: "https://developers.cloudflare.com/workers-ai/",
    hasFree: true,
    freeNote:
      "Free 10K Neurons/day: ~150 LLM responses or 500s Whisper audio — edge inference globally",
    authHint: "Requires API Token AND Account ID (found at dash.cloudflare.com)",
  },
  scaleway: {
    id: "scaleway",
    alias: "scw",
    name: "Scaleway AI",
    icon: "cloud",
    color: "#4F0599",
    textIcon: "SCW",
    website: "https://www.scaleway.com/en/ai/generative-apis/",
    hasFree: true,
    freeNote: "1M free tokens for new accounts — EU/GDPR compliant (Paris), Qwen3 235B & Llama 70B",
  },
  deepinfra: {
    id: "deepinfra",
    alias: "deepinfra",
    name: "DeepInfra",
    icon: "hub",
    color: "#2563EB",
    textIcon: "DI",
    website: "https://deepinfra.com",
    hasFree: true,
    freeNote: "Free signup credits for API testing and model exploration",
  },
  "vercel-ai-gateway": {
    id: "vercel-ai-gateway",
    alias: "vag",
    name: "Vercel AI Gateway",
    icon: "route",
    color: "#111827",
    textIcon: "VAI",
    website: "https://vercel.com/docs/ai-gateway",
  },
  "lambda-ai": {
    id: "lambda-ai",
    alias: "lambda",
    name: "Lambda AI",
    icon: "bolt",
    color: "#7C3AED",
    textIcon: "LA",
    website: "https://lambda.ai",
  },
  sambanova: {
    id: "sambanova",
    alias: "samba",
    name: "SambaNova",
    icon: "memory",
    color: "#DC2626",
    textIcon: "SN",
    website: "https://sambanova.ai",
    hasFree: true,
    freeNote: "$5 free credits on signup (30-day validity), no credit card required",
  },
  nscale: {
    id: "nscale",
    alias: "nscale",
    name: "nScale",
    icon: "token",
    color: "#0891B2",
    textIcon: "NS",
    website: "https://nscale.com",
    hasFree: true,
    freeNote: "$5 free credits on signup for inference testing",
  },
  ovhcloud: {
    id: "ovhcloud",
    alias: "ovh",
    name: "OVHcloud AI",
    icon: "cloud",
    color: "#2563EB",
    textIcon: "OVH",
    website: "https://www.ovhcloud.com",
  },
  baseten: {
    id: "baseten",
    alias: "baseten",
    name: "Baseten",
    icon: "deployed_code",
    color: "#111827",
    textIcon: "BT",
    website: "https://baseten.co",
    hasFree: true,
    freeNote: "$30 free trial credits for GPU inference",
  },
  publicai: {
    id: "publicai",
    alias: "publicai",
    name: "PublicAI",
    icon: "public",
    color: "#059669",
    textIcon: "PA",
    website: "https://publicai.co",
    hasFree: true,
    freeNote: "Free community inference tier for testing",
  },
  moonshot: {
    id: "moonshot",
    alias: "moonshot",
    name: "Moonshot AI",
    icon: "rocket_launch",
    color: "#1E40AF",
    textIcon: "MS",
    website: "https://platform.moonshot.ai",
  },
  "meta-llama": {
    id: "meta-llama",
    alias: "meta",
    name: "Meta Llama API",
    icon: "smart_toy",
    color: "#0F766E",
    textIcon: "ML",
    website: "https://llama.developer.meta.com",
  },
  "v0-vercel": {
    id: "v0-vercel",
    alias: "v0",
    name: "v0 (Vercel)",
    icon: "code_blocks",
    color: "#111827",
    textIcon: "V0",
    website: "https://v0.dev",
  },
  morph: {
    id: "morph",
    alias: "morph",
    name: "Morph",
    icon: "auto_fix_high",
    color: "#2563EB",
    textIcon: "MP",
    website: "https://morphllm.com",
    hasFree: true,
    freeNote: "Free tier: 250K credits/month, $0",
  },
  "featherless-ai": {
    id: "featherless-ai",
    alias: "featherless",
    name: "Featherless AI",
    icon: "flutter_dash",
    color: "#EA580C",
    textIcon: "FL",
    website: "https://featherless.ai",
  },
  friendliai: {
    id: "friendliai",
    alias: "friendli",
    name: "FriendliAI",
    icon: "handshake",
    color: "#EC4899",
    textIcon: "FR",
    website: "https://friendli.ai",
  },
  llamagate: {
    id: "llamagate",
    alias: "llamagate",
    name: "LlamaGate",
    icon: "gate",
    color: "#16A34A",
    textIcon: "LG",
    website: "https://llamagate.ai",
  },
  heroku: {
    id: "heroku",
    alias: "heroku",
    name: "Heroku AI",
    icon: "cloud_upload",
    color: "#7C3AED",
    textIcon: "HK",
    website: "https://www.heroku.com",
  },
  galadriel: {
    id: "galadriel",
    alias: "galadriel",
    name: "Galadriel",
    icon: "auto_awesome",
    color: "#F59E0B",
    textIcon: "GA",
    website: "https://galadriel.com",
  },
  databricks: {
    id: "databricks",
    alias: "databricks",
    name: "Databricks",
    icon: "table_chart",
    color: "#F97316",
    textIcon: "DB",
    website: "https://www.databricks.com",
  },
  datarobot: {
    id: "datarobot",
    alias: "datarobot",
    name: "DataRobot",
    icon: "precision_manufacturing",
    color: "#6D28D9",
    textIcon: "DR",
    website: "https://docs.datarobot.com",
    authHint:
      "Use your DataRobot API token. Optional Base URL can be the account root (for LLM Gateway) or a deployment URL under /api/v2/deployments/<id>.",
    apiHint:
      "The default gateway catalogs active models from /genai/llmgw/catalog/. Deployment URLs are also supported for direct OpenAI-compatible chat requests.",
    passthroughModels: true,
  },
  clarifai: {
    id: "clarifai",
    alias: "clarifai",
    name: "Clarifai",
    icon: "hub",
    color: "#7C3AED",
    textIcon: "CF",
    website: "https://docs.clarifai.com",
    authHint:
      "Use your Clarifai PAT or app-specific API key. OmniRoute targets the OpenAI-compatible endpoint at https://api.clarifai.com/v2/ext/openai/v1 and authenticates with Authorization: Key <token>.",
    apiHint:
      "Clarifai exposes OpenAI-compatible chat, responses and /models on /v2/ext/openai/v1. Public/community models typically require a PAT; app-scoped keys only work for resources inside that app.",
    passthroughModels: true,
  },
  snowflake: {
    id: "snowflake",
    alias: "snowflake",
    name: "Snowflake Cortex",
    icon: "ac_unit",
    color: "#29B5E8",
    textIcon: "SF",
    website: "https://www.snowflake.com",
  },
  wandb: {
    id: "wandb",
    alias: "wandb",
    name: "Weights & Biases Inference",
    icon: "monitoring",
    color: "#FFBE0B",
    textIcon: "WB",
    website: "https://wandb.ai",
  },
  volcengine: {
    id: "volcengine",
    alias: "volcengine",
    name: "Volcengine",
    icon: "local_fire_department",
    color: "#DC2626",
    textIcon: "VE",
    website: "https://www.volcengine.com",
  },
  ai21: {
    id: "ai21",
    alias: "ai21",
    name: "AI21 Labs",
    icon: "psychology_alt",
    color: "#0284C7",
    textIcon: "AI21",
    website: "https://www.ai21.com",
    hasFree: true,
    freeNote: "$10 trial credits on signup (valid 3 months), no credit card required",
  },
  gigachat: {
    id: "gigachat",
    alias: "gigachat",
    name: "GigaChat (Sber)",
    icon: "lock_person",
    color: "#10B981",
    textIcon: "GC",
    website: "https://developers.sber.ru",
  },
  venice: {
    id: "venice",
    alias: "venice",
    name: "Venice.ai",
    icon: "travel_explore",
    color: "#0EA5E9",
    textIcon: "VN",
    website: "https://venice.ai",
  },
  codestral: {
    id: "codestral",
    alias: "codestral",
    name: "Codestral",
    icon: "terminal",
    color: "#FF7000",
    textIcon: "CS",
    website: "https://mistral.ai",
  },
  upstage: {
    id: "upstage",
    alias: "upstage",
    name: "Upstage",
    icon: "trending_up",
    color: "#0F766E",
    textIcon: "UP",
    website: "https://www.upstage.ai",
  },
  maritalk: {
    id: "maritalk",
    alias: "maritalk",
    name: "Maritalk",
    icon: "translate",
    color: "#1D4ED8",
    textIcon: "MT",
    website: "https://www.maritaca.ai",
  },
  "xiaomi-mimo": {
    id: "xiaomi-mimo",
    alias: "mimo",
    name: "Xiaomi MiMo",
    icon: "devices",
    color: "#EA580C",
    textIcon: "MM",
    website: "https://mimo.mi.com",
  },
  "inference-net": {
    id: "inference-net",
    alias: "inet",
    name: "Inference.net",
    icon: "dns",
    color: "#2563EB",
    textIcon: "IN",
    website: "https://inference.net",
    hasFree: true,
    freeNote: "$25 free credits on signup plus research grants available",
  },
  nanogpt: {
    id: "nanogpt",
    alias: "nanogpt",
    name: "NanoGPT",
    icon: "chat",
    color: "#4F46E5",
    textIcon: "NG",
    website: "https://nano-gpt.com",
  },
  predibase: {
    id: "predibase",
    alias: "predibase",
    name: "Predibase",
    icon: "deployed_code_history",
    color: "#0F766E",
    textIcon: "PB",
    website: "https://predibase.com",
    hasFree: true,
    freeNote: "$25 free trial credits (30-day validity)",
  },
  bytez: {
    id: "bytez",
    alias: "bytez",
    name: "Bytez",
    icon: "api",
    color: "#6366F1",
    textIcon: "BZ",
    website: "https://bytez.com",
    hasFree: true,
    freeNote: "$1 free credits, refreshes every 4 weeks",
  },
  aimlapi: {
    id: "aimlapi",
    alias: "aiml",
    name: "AI/ML API",
    icon: "hub",
    color: "#6366F1",
    textIcon: "AI",
    website: "https://aimlapi.com",
    hasFree: true,
    freeNote:
      "$0.025/day free credits — 200+ models (GPT-4o, Claude, Gemini, Llama) via single endpoint",
    passthroughModels: true,
  },
  novita: {
    id: "novita",
    alias: "novita",
    name: "Novita AI",
    icon: "auto_awesome",
    color: "#FF4081",
    textIcon: "NV",
    website: "https://novita.ai",
    hasFree: true,
    freeNote: "$0.50 trial credits on signup (valid about 1 year)",
    passthroughModels: true,
  },
  piapi: {
    id: "piapi",
    alias: "pi",
    name: "PiAPI",
    icon: "api",
    color: "#7C4DFF",
    textIcon: "PI",
    website: "https://piapi.ai",
    passthroughModels: true,
  },
  getgoapi: {
    id: "getgoapi",
    alias: "ggo",
    name: "GoAPI",
    icon: "rocket_launch",
    color: "#FF6D00",
    textIcon: "GO",
    website: "https://api.getgoapi.com",
    passthroughModels: true,
  },
  laozhang: {
    id: "laozhang",
    alias: "lz",
    name: "LaoZhang AI",
    icon: "hub",
    color: "#FF1744",
    textIcon: "LZ",
    website: "https://api.laozhang.ai",
    passthroughModels: true,
  },
  glhf: {
    id: "glhf",
    alias: "glhf",
    name: "GLHF Chat",
    icon: "hub",
    color: "#10B981",
    textIcon: "GH",
    website: "https://glhf.chat",
    authHint: "Bearer API key for the GLHF OpenAI-compatible gateway.",
    hasFree: true,
    freeNote: "Free tier for open-source model inference",
    passthroughModels: true,
  },
  cablyai: {
    id: "cablyai",
    alias: "cablyai",
    name: "CablyAI",
    icon: "hub",
    color: "#FF4081",
    textIcon: "CA",
    website: "https://cablyai.com",
    authHint: "Bearer API key for the CablyAI OpenAI-compatible gateway.",
    passthroughModels: true,
  },
  thebai: {
    id: "thebai",
    alias: "thebai",
    name: "TheB.AI",
    icon: "hub",
    color: "#3B82F6",
    textIcon: "TB",
    website: "https://theb.ai",
    authHint: "Bearer API key for the TheB.AI OpenAI-compatible gateway.",
    passthroughModels: true,
  },
  fenayai: {
    id: "fenayai",
    alias: "fenayai",
    name: "FenayAI",
    icon: "hub",
    color: "#FF9800",
    textIcon: "FN",
    website: "https://fenayai.com",
    authHint: "Bearer API key for the FenayAI OpenAI-compatible gateway.",
    passthroughModels: true,
  },
  empower: {
    id: "empower",
    alias: "empower",
    name: "Empower",
    icon: "hub",
    color: "#14B8A6",
    textIcon: "EM",
    website: "https://docs.empower.dev",
    authHint: "Bearer API key for the Empower OpenAI-compatible endpoint.",
    apiHint:
      "Empower exposes OpenAI-compatible chat on https://app.empower.dev/api/v1 with tool-calling support on empower-functions.",
    passthroughModels: true,
  },
  "nous-research": {
    id: "nous-research",
    alias: "nous",
    name: "Nous Research",
    icon: "hub",
    color: "#2563EB",
    textIcon: "NO",
    website: "https://portal.nousresearch.com/help",
    authHint:
      "Use your Nous Portal API key. OmniRoute targets the official OpenAI-compatible inference endpoint at https://inference-api.nousresearch.com/v1.",
    apiHint:
      "Nous exposes an OpenAI-compatible /v1 surface with a large remote /models catalog. The /chat/completions endpoint requires a valid API key for programmatic inference.",
    hasFree: true,
    freeNote: "Free tier: 50 RPM, 500,000 TPM — no credit card",
  },
  petals: {
    id: "petals",
    alias: "petals",
    name: "Petals",
    icon: "hub",
    color: "#10B981",
    textIcon: "PT",
    website: "https://chat.petals.dev",
    authHint:
      "No API key is required for the public research endpoint. Leave the field blank, or provide a bearer token if your self-hosted Petals gateway uses auth.",
    apiHint:
      "Petals exposes a public HTTP API at https://chat.petals.dev/api/v1/generate and a WebSocket API at /api/v2/generate. OmniRoute targets the HTTP generate endpoint and supports self-hosted base URLs.",
  },
  poe: {
    id: "poe",
    alias: "poe",
    name: "Poe",
    icon: "hub",
    color: "#F97316",
    textIcon: "PO",
    website: "https://creator.poe.com/api-reference",
    authHint: "Bearer API key for the Poe OpenAI-compatible API.",
    apiHint:
      "Poe exposes OpenAI-compatible chat and responses on https://api.poe.com/v1, with authenticated balance checks on /usage/current_balance.",
    passthroughModels: true,
  },
  gitlab: {
    id: "gitlab",
    alias: "gitlab",
    name: "GitLab Duo PAT",
    icon: "hub",
    color: "#FC6D26",
    textIcon: "GL",
    website: "https://docs.gitlab.com/user/duo_agent_platform/code_suggestions/",
    authHint:
      "GitLab personal access token for the public Code Suggestions API. Configure a self-hosted base URL when not using gitlab.com.",
  },
  chutes: {
    id: "chutes",
    alias: "chutes",
    name: "Chutes.ai",
    icon: "hub",
    color: "#06B6D4",
    textIcon: "CH",
    website: "https://chutes.ai",
    authHint: "Bearer API key for the Chutes OpenAI-compatible gateway.",
    passthroughModels: true,
  },
  "voyage-ai": {
    id: "voyage-ai",
    alias: "voyage",
    name: "Voyage AI",
    icon: "blur_on",
    color: "#0F766E",
    textIcon: "VA",
    website: "https://www.voyageai.com",
    authHint: "Bearer API key for Voyage AI embeddings and rerank APIs.",
    hasFree: true,
    freeNote: "200M free tokens for embeddings and reranking",
  },
  "jina-ai": {
    id: "jina-ai",
    alias: "jina",
    name: "Jina AI",
    icon: "sort",
    color: "#2563EB",
    textIcon: "JA",
    website: "https://jina.ai",
    authHint: "Bearer API key for the Jina AI rerank API.",
    hasFree: true,
    freeNote: "10M free tokens on signup (non-commercial), no credit card required",
  },
  "fal-ai": {
    id: "fal-ai",
    alias: "fal",
    name: "Fal.ai",
    icon: "image",
    color: "#2563EB",
    textIcon: "FL",
    website: "https://fal.ai",
  },
  "stability-ai": {
    id: "stability-ai",
    alias: "stability",
    name: "Stability AI",
    icon: "image",
    color: "#8B5CF6",
    textIcon: "SA",
    website: "https://stability.ai",
  },
  "black-forest-labs": {
    id: "black-forest-labs",
    alias: "bfl",
    name: "Black Forest Labs",
    icon: "image",
    color: "#111827",
    textIcon: "BF",
    website: "https://blackforestlabs.ai",
  },
  recraft: {
    id: "recraft",
    alias: "recraft",
    name: "Recraft",
    icon: "image",
    color: "#EC4899",
    textIcon: "RC",
    website: "https://recraft.ai",
  },
  topaz: {
    id: "topaz",
    alias: "topaz",
    name: "Topaz",
    icon: "image",
    color: "#059669",
    textIcon: "TP",
    website: "https://topazlabs.com",
  },
};

// Sub-categories within APIKEY_PROVIDERS (used by dashboard and catalog views).
export const IMAGE_ONLY_PROVIDER_IDS = new Set([
  "nanobanana",
  "fal-ai",
  "stability-ai",
  "black-forest-labs",
  "recraft",
  "topaz",
]);

export const AGGREGATOR_PROVIDER_IDS = new Set([
  "openrouter",
  "synthetic",
  "kilo-gateway",
  "aimlapi",
  "novita",
  "piapi",
  "getgoapi",
  "laozhang",
  "vercel-ai-gateway",
  "agentrouter",
  "glhf",
  "cablyai",
  "thebai",
  "fenayai",
  "empower",
  "poe",
  "chutes",
]);

export const ENTERPRISE_CLOUD_PROVIDER_IDS = new Set([
  "azure-openai",
  "azure-ai",
  "bedrock",
  "watsonx",
  "oci",
  "sap",
  "vertex",
  "vertex-partner",
  "databricks",
  "datarobot",
  "clarifai",
  "snowflake",
  "heroku",
  "modal",
]);

export const VIDEO_PROVIDER_IDS = new Set(["runwayml"]);

export const EMBEDDING_RERANK_PROVIDER_IDS = new Set(["voyage-ai", "jina-ai"]);

// Local / Self-Hosted Providers
export const LOCAL_PROVIDERS = {
  "lm-studio": {
    id: "lm-studio",
    alias: "lmstudio",
    name: "LM Studio",
    icon: "server",
    color: "#4A148C",
    textIcon: "LM",
    website: "https://lmstudio.ai",
    authHint:
      "API key optional. Configure the local LM Studio OpenAI-compatible base URL (default: http://localhost:1234/v1).",
    localDefault: "http://localhost:1234/v1",
    passthroughModels: true,
  },
  vllm: {
    id: "vllm",
    alias: "vllm",
    name: "vLLM",
    icon: "memory",
    color: "#0F766E",
    textIcon: "VL",
    website: "https://github.com/vllm-project/vllm",
    authHint:
      "API key optional. Configure the local vLLM OpenAI-compatible base URL (default: http://localhost:8000/v1).",
    localDefault: "http://localhost:8000/v1",
    passthroughModels: true,
  },
  lemonade: {
    id: "lemonade",
    alias: "lemonade",
    name: "Lemonade Server",
    icon: "bolt",
    color: "#F59E0B",
    textIcon: "LM",
    website: "https://lemonade-server.ai",
    authHint:
      "API key optional. Configure the local Lemonade OpenAI-compatible base URL (default: http://localhost:13305/api/v1).",
    localDefault: "http://localhost:13305/api/v1",
    passthroughModels: true,
  },
  llamafile: {
    id: "llamafile",
    alias: "llamafile",
    name: "Llamafile",
    icon: "article",
    color: "#EA580C",
    textIcon: "LF",
    website: "https://github.com/Mozilla-Ocho/llamafile",
    authHint:
      "API key optional. Configure the local Llamafile OpenAI-compatible base URL (default: http://127.0.0.1:8080/v1).",
    localDefault: "http://127.0.0.1:8080/v1",
    passthroughModels: true,
  },
  triton: {
    id: "triton",
    alias: "triton",
    name: "NVIDIA Triton",
    icon: "developer_board",
    color: "#76B900",
    textIcon: "TR",
    website: "https://developer.nvidia.com/triton-inference-server",
    authHint:
      "API key optional. Configure the Triton OpenAI-compatible base URL (default: http://localhost:8000/v1).",
    localDefault: "http://localhost:8000/v1",
    passthroughModels: true,
  },
  "docker-model-runner": {
    id: "docker-model-runner",
    alias: "dmr",
    name: "Docker Model Runner",
    icon: "inventory_2",
    color: "#2496ED",
    textIcon: "DM",
    website: "https://docs.docker.com/ai/model-runner/",
    authHint:
      "API key optional. Configure the local Docker Model Runner OpenAI-compatible base URL (default: http://localhost:12434/v1).",
    localDefault: "http://localhost:12434/v1",
    passthroughModels: true,
  },
  xinference: {
    id: "xinference",
    alias: "xinference",
    name: "XInference",
    icon: "hub",
    color: "#DC2626",
    textIcon: "XI",
    website: "https://inference.readthedocs.io",
    authHint:
      "API key optional. Configure the local XInference OpenAI-compatible base URL (default: http://localhost:9997/v1).",
    localDefault: "http://localhost:9997/v1",
    passthroughModels: true,
  },
  oobabooga: {
    id: "oobabooga",
    alias: "ooba",
    name: "oobabooga",
    icon: "dns",
    color: "#8B5CF6",
    textIcon: "OO",
    website: "https://github.com/oobabooga/text-generation-webui",
    authHint:
      "API key optional. Configure the local oobabooga OpenAI-compatible base URL (default: http://localhost:5000/v1).",
    localDefault: "http://localhost:5000/v1",
    passthroughModels: true,
  },
  sdwebui: {
    id: "sdwebui",
    alias: "sdwebui",
    name: "SD WebUI",
    icon: "brush",
    color: "#FF7043",
    textIcon: "SD",
    website: "https://github.com/AUTOMATIC1111/stable-diffusion-webui",
    authHint:
      "No API key required. Configure the local WebUI base URL (default: http://localhost:7860).",
    localDefault: "http://localhost:7860",
  },
  comfyui: {
    id: "comfyui",
    alias: "comfyui",
    name: "ComfyUI",
    icon: "account_tree",
    color: "#4CAF50",
    textIcon: "CF",
    website: "https://github.com/comfyanonymous/ComfyUI",
    authHint:
      "No API key required. Configure the local ComfyUI base URL (default: http://localhost:8188).",
    localDefault: "http://localhost:8188",
  },
};

// Search Providers
export const SEARCH_PROVIDERS = {
  "perplexity-search": {
    id: "perplexity-search",
    alias: "pplx-search",
    name: "Perplexity Search",
    icon: "search",
    color: "#20808D",
    textIcon: "PS",
    website: "https://docs.perplexity.ai/guides/search-quickstart",
    authHint: "Same API key as Perplexity (pplx-...)",
  },
  "serper-search": {
    id: "serper-search",
    alias: "serper-search",
    name: "Serper Search",
    icon: "search",
    color: "#4285F4",
    textIcon: "SP",
    website: "https://serper.dev",
    authHint: "API key from serper.dev dashboard",
  },
  "brave-search": {
    id: "brave-search",
    alias: "brave-search",
    name: "Brave Search",
    icon: "travel_explore",
    color: "#FB542B",
    textIcon: "BR",
    website: "https://brave.com/search/api",
    authHint: "Subscription token from Brave Search API dashboard",
  },
  "exa-search": {
    id: "exa-search",
    alias: "exa-search",
    name: "Exa Search",
    icon: "neurology",
    color: "#1E40AF",
    textIcon: "EX",
    website: "https://exa.ai",
    authHint: "API key from dashboard.exa.ai",
  },
  "tavily-search": {
    id: "tavily-search",
    alias: "tavily-search",
    name: "Tavily Search",
    icon: "manage_search",
    color: "#5B4FDB",
    textIcon: "TV",
    website: "https://tavily.com",
    authHint: "API key from app.tavily.com (format: tvly-...)",
  },
  "google-pse-search": {
    id: "google-pse-search",
    alias: "google-pse",
    name: "Google Programmable Search",
    icon: "travel_explore",
    color: "#4285F4",
    textIcon: "GP",
    website: "https://developers.google.com/custom-search/v1/overview",
    authHint: "Requires a Google API key and your Programmable Search Engine ID (cx)",
  },
  "linkup-search": {
    id: "linkup-search",
    alias: "linkup",
    name: "Linkup Search",
    icon: "public",
    color: "#0F766E",
    textIcon: "LU",
    website: "https://docs.linkup.so",
    authHint: "Bearer API key from the Linkup dashboard",
  },
  "searchapi-search": {
    id: "searchapi-search",
    alias: "searchapi",
    name: "SearchAPI",
    icon: "manage_search",
    color: "#2563EB",
    textIcon: "SA",
    website: "https://www.searchapi.io/docs",
    authHint: "API key from SearchAPI (query param or Bearer auth)",
  },
  "youcom-search": {
    id: "youcom-search",
    alias: "youcom-search",
    name: "You.com Search",
    icon: "travel_explore",
    color: "#2563EB",
    textIcon: "YOU",
    website: "https://you.com/docs/search/overview",
    authHint: "X-API-Key from the You.com platform dashboard",
  },
  "searxng-search": {
    id: "searxng-search",
    alias: "searxng",
    name: "SearXNG Search",
    icon: "search",
    color: "#1A237E",
    textIcon: "SX",
    website: "https://docs.searxng.org",
    authHint:
      "API key is optional. Set your SearXNG base URL. Some instances may require a bearer token for access.",
  },
};

// Audio Only Providers
export const AUDIO_ONLY_PROVIDERS = {
  deepgram: {
    id: "deepgram",
    alias: "dg",
    name: "Deepgram",
    icon: "mic",
    color: "#13EF93",
    textIcon: "DG",
    website: "https://deepgram.com",
  },
  assemblyai: {
    id: "assemblyai",
    alias: "aai",
    name: "AssemblyAI",
    icon: "record_voice_over",
    color: "#0062FF",
    textIcon: "AA",
    website: "https://assemblyai.com",
  },
  elevenlabs: {
    id: "elevenlabs",
    alias: "el",
    name: "ElevenLabs",
    icon: "record_voice_over",
    color: "#6C47FF",
    textIcon: "EL",
    website: "https://elevenlabs.io",
  },
  cartesia: {
    id: "cartesia",
    alias: "cartesia",
    name: "Cartesia",
    icon: "spatial_audio",
    color: "#FF4F8B",
    textIcon: "CA",
    website: "https://cartesia.ai",
  },
  playht: {
    id: "playht",
    alias: "playht",
    name: "PlayHT",
    icon: "play_circle",
    color: "#00B4D8",
    textIcon: "PH",
    website: "https://play.ht",
  },
  inworld: {
    id: "inworld",
    alias: "inworld",
    name: "Inworld",
    icon: "voice_chat",
    color: "#7B2EF2",
    textIcon: "IW",
    website: "https://inworld.ai",
  },
  "aws-polly": {
    id: "aws-polly",
    alias: "polly",
    name: "AWS Polly",
    icon: "record_voice_over",
    color: "#FF9900",
    textIcon: "PL",
    website: "https://aws.amazon.com/polly/",
    authHint:
      "Use AWS Secret Access Key as API key; set providerSpecificData.accessKeyId and optional region.",
  },
};

export const OPENAI_COMPATIBLE_PREFIX = "openai-compatible-";
export const ANTHROPIC_COMPATIBLE_PREFIX = "anthropic-compatible-";
export const CLAUDE_CODE_COMPATIBLE_PREFIX = "anthropic-compatible-cc-";

export function isOpenAICompatibleProvider(providerId: unknown): providerId is string {
  return typeof providerId === "string" && providerId.startsWith(OPENAI_COMPATIBLE_PREFIX);
}

export function isAnthropicCompatibleProvider(providerId: unknown): providerId is string {
  return typeof providerId === "string" && providerId.startsWith(ANTHROPIC_COMPATIBLE_PREFIX);
}

export const UPSTREAM_PROXY_PROVIDERS = {
  cliproxyapi: {
    id: "cliproxyapi",
    alias: "cpa",
    name: "CLIProxyAPI",
    icon: "proxy",
    color: "#6366F1",
    textIcon: "CPA",
    website: "https://github.com/router-for-me/CLIProxyAPI",
    defaultPort: 8317,
    healthEndpoint: "/v1/models",
    managementPrefix: "/v0/management",
    configDir: "~/.cli-proxy-api",
    binaryName: "cli-proxy-api",
    githubRepo: "router-for-me/CLIProxyAPI",
  },
};

export function isClaudeCodeCompatibleProvider(providerId: unknown): providerId is string {
  return typeof providerId === "string" && providerId.startsWith(CLAUDE_CODE_COMPATIBLE_PREFIX);
}

export function isLocalProvider(providerId: unknown): boolean {
  return (
    typeof providerId === "string" &&
    Object.prototype.hasOwnProperty.call(LOCAL_PROVIDERS, providerId)
  );
}

export const SELF_HOSTED_CHAT_PROVIDER_IDS = new Set([
  "lm-studio",
  "vllm",
  "lemonade",
  "llamafile",
  "triton",
  "docker-model-runner",
  "xinference",
  "oobabooga",
]);

export function isSelfHostedChatProvider(providerId: unknown): boolean {
  return typeof providerId === "string" && SELF_HOSTED_CHAT_PROVIDER_IDS.has(providerId);
}

// All providers (combined)
export const AI_PROVIDERS = {
  ...FREE_PROVIDERS,
  ...OAUTH_PROVIDERS,
  ...APIKEY_PROVIDERS,
  ...WEB_COOKIE_PROVIDERS,
  ...LOCAL_PROVIDERS,
  ...SEARCH_PROVIDERS,
  ...AUDIO_ONLY_PROVIDERS,
  ...UPSTREAM_PROXY_PROVIDERS,
};

export type AiProviderId = keyof typeof AI_PROVIDERS;
export type AiProviderDefinition = (typeof AI_PROVIDERS)[AiProviderId];

// Auth methods
export const AUTH_METHODS = {
  oauth: { id: "oauth", name: "OAuth", icon: "lock" },
  apikey: { id: "apikey", name: "API Key", icon: "key" },
};

// Helper: Get provider by alias
export function getProviderByAlias(alias: string): AiProviderDefinition | null {
  for (const provider of Object.values(AI_PROVIDERS)) {
    if (provider.alias === alias || provider.id === alias) {
      return provider;
    }
  }
  return null;
}

// Helper: Get provider ID from alias
export function resolveProviderId(aliasOrId: string): string {
  const provider = getProviderByAlias(aliasOrId);
  return provider?.id || aliasOrId;
}

// Helper: Get alias from provider ID
export function getProviderAlias(providerId: string): string {
  const provider = Object.prototype.hasOwnProperty.call(AI_PROVIDERS, providerId)
    ? AI_PROVIDERS[providerId as AiProviderId]
    : undefined;
  return provider?.alias || providerId;
}

// Alias to ID mapping (for quick lookup)
export const ALIAS_TO_ID = Object.values(AI_PROVIDERS).reduce<Record<string, string>>((acc, p) => {
  if (p.alias) acc[p.alias] = p.id;
  return acc;
}, {});

// ID to Alias mapping
export const ID_TO_ALIAS = Object.values(AI_PROVIDERS).reduce<Record<string, string>>((acc, p) => {
  acc[p.id] = p.alias || p.id;
  return acc;
}, {});

// Providers that support usage/quota API
export const USAGE_SUPPORTED_PROVIDERS = [
  "antigravity",
  "gemini-cli",
  "kiro",
  "amazon-q",
  "github",
  "codex",
  "claude",
  "kimi-coding",
  "glm",
  "glmt",
  "minimax",
  "minimax-cn",
  "crof",
  "nanogpt",
];

// ── Zod validation at module load (Phase 7.2) ──
import { validateProviders } from "../validation/providerSchema";

validateProviders(FREE_PROVIDERS, "FREE_PROVIDERS");
validateProviders(OAUTH_PROVIDERS, "OAUTH_PROVIDERS");
validateProviders(APIKEY_PROVIDERS, "APIKEY_PROVIDERS");
validateProviders(WEB_COOKIE_PROVIDERS, "WEB_COOKIE_PROVIDERS");
validateProviders(LOCAL_PROVIDERS, "LOCAL_PROVIDERS");
validateProviders(SEARCH_PROVIDERS, "SEARCH_PROVIDERS");
validateProviders(AUDIO_ONLY_PROVIDERS, "AUDIO_ONLY_PROVIDERS");
validateProviders(UPSTREAM_PROXY_PROVIDERS, "UPSTREAM_PROXY_PROVIDERS");
