diff --git a/open-sse/config/petals.ts b/open-sse/config/petals.ts deleted file mode 100644 index 569c65ba1d..0000000000 --- a/open-sse/config/petals.ts +++ /dev/null @@ -1,19 +0,0 @@ -export const PETALS_DEFAULT_BASE_URL = "https://chat.petals.dev/api/v1/generate"; -export const PETALS_DEFAULT_MODEL = "stabilityai/StableBeluga2"; - -export function normalizePetalsBaseUrl(baseUrl: string | null | undefined): string { - const normalized = String(baseUrl || PETALS_DEFAULT_BASE_URL) - .trim() - .replace(/\/+$/, ""); - - if (normalized.endsWith("/api/v1/generate")) { - return normalized; - } - if (normalized.endsWith("/api/v1")) { - return `${normalized}/generate`; - } - if (normalized.endsWith("/api")) { - return `${normalized}/v1/generate`; - } - return `${normalized}/api/v1/generate`; -} diff --git a/open-sse/config/providerRegistry.ts b/open-sse/config/providerRegistry.ts index 8e9a50e666..6e8c696e23 100644 --- a/open-sse/config/providerRegistry.ts +++ b/open-sse/config/providerRegistry.ts @@ -2334,16 +2334,6 @@ const _REGISTRY_EAGER: Record = { models: [{ id: "auto", name: "Auto" }], }, - lepton: { - id: "lepton", - alias: "lepton", - format: "openai", - executor: "default", - baseUrl: "https://api.lepton.ai/v1/chat/completions", - authType: "apikey", - authHeader: "bearer", - models: [{ id: "llama-3.1-8b", name: "Llama 3.1 8B" }], - }, kluster: { id: "kluster", @@ -2378,16 +2368,6 @@ const _REGISTRY_EAGER: Record = { models: [{ id: "liquid-lfm-40b", name: "Liquid LFM 40B" }], }, - nomic: { - id: "nomic", - alias: "nomic", - format: "openai", - executor: "default", - baseUrl: "https://api.nomic.ai/v1/chat/completions", - authType: "apikey", - authHeader: "bearer", - models: [{ id: "nomic-embed-text-v1.5", name: "Nomic Embed Text" }], - }, monsterapi: { id: "monsterapi", @@ -2426,16 +2406,6 @@ const _REGISTRY_EAGER: Record = { ], }, - poolside: { - id: "poolside", - alias: "poolside", - format: "openai", - executor: "default", - baseUrl: "https://api.poolside.ai/v1/chat/completions", - authType: "apikey", - authHeader: "bearer", - models: [{ id: "poolside-model", name: "Poolside Model" }], - }, chutes: { id: "chutes", @@ -2655,35 +2625,6 @@ const _REGISTRY_EAGER: Record = { { id: "gemini-3-flash-preview", name: "Gemini 3 Flash" }, ], }, - enally: { - id: "enally", - alias: "enly", - format: "openai", - executor: "default", - baseUrl: "https://ai.enally.in", - authType: "apikey", - authHeader: "X-API-Key", - models: [ - { id: "default", name: "Default Model" }, - { id: "chat", name: "Chat Model" }, - { id: "reasoning", name: "Reasoning Model" }, - { id: "multimodal", name: "Multimodal Model" }, - ], - }, - freetheai: { - id: "freetheai", - alias: "fta", - format: "openai", - executor: "default", - baseUrl: "https://api.freetheai.xyz/v1/chat/completions", - authType: "apikey", - authHeader: "bearer", - models: [ - { id: "free-fast", name: "Free Fast (Low Latency)" }, - { id: "free-smart", name: "Free Smart (Reasoning)" }, - { id: "free", name: "Free (Max Uptime)" }, - ], - }, xai: { id: "xai", alias: "xai", @@ -3631,42 +3572,6 @@ const _REGISTRY_EAGER: Record = { ], }, - replicate: { - id: "replicate", - alias: "rep", - format: "openai", - executor: "default", - baseUrl: "https://openai-proxy.replicate.com/v1/chat/completions", - modelsUrl: "https://openai-proxy.replicate.com/v1/models", - authType: "apikey", - authHeader: "Authorization", - authPrefix: "Bearer", - passthroughModels: true, - defaultContextLength: 128000, - models: [ - { - id: "meta/meta-llama-3.1-405b-instruct", - name: "Llama 3.1 405B Instruct (Free)", - contextLength: 128000, - }, - { - id: "meta/meta-llama-3.1-70b-instruct", - name: "Llama 3.1 70B Instruct (Free)", - contextLength: 128000, - }, - { - id: "mistralai/mixtral-8x7b-instruct-v0.1", - name: "Mixtral 8x7B Instruct (Free)", - contextLength: 32768, - }, - { - id: "deepseek-ai/deepseek-r1", - name: "DeepSeek R1 (Free)", - contextLength: 65536, - supportsReasoning: true, - }, - ], - }, hackclub: { id: "hackclub", diff --git a/src/lib/providers/imageValidation.ts b/src/lib/providers/imageValidation.ts index 150a3a1804..de5057acda 100644 --- a/src/lib/providers/imageValidation.ts +++ b/src/lib/providers/imageValidation.ts @@ -12,10 +12,6 @@ const IMAGE_PROVIDER_VALIDATION_ENDPOINTS: Record< string, { baseUrl?: string; path: string; method?: string } > = { - nanobanana: { - baseUrl: "https://api.nanobananaapi.ai", - path: "/api/v1/common/credit", - }, "fal-ai": { baseUrl: "https://api.fal.ai", path: "/v1/models?limit=1", diff --git a/src/lib/providers/staticModels.ts b/src/lib/providers/staticModels.ts index 6e17464449..0cf74fe5fe 100644 --- a/src/lib/providers/staticModels.ts +++ b/src/lib/providers/staticModels.ts @@ -31,10 +31,6 @@ const STATIC_MODEL_PROVIDERS: Record Array<{ id: string; name: str { id: "universal-3-pro", name: "Universal 3 Pro (Transcription)" }, { id: "universal-2", name: "Universal 2 (Transcription)" }, ], - nanobanana: () => [ - { id: "nanobanana-flash", name: "NanoBanana Flash (Gemini 2.5 Flash)" }, - { id: "nanobanana-pro", name: "NanoBanana Pro (Gemini 3 Pro)" }, - ], antigravity: () => ANTIGRAVITY_PUBLIC_MODELS.map((model) => ({ ...model })), claude: () => [ { id: "claude-opus-4-8", name: "Claude Opus 4.8" }, diff --git a/src/lib/providers/validation.ts b/src/lib/providers/validation.ts index 19976bd5bd..6af959ddcd 100644 --- a/src/lib/providers/validation.ts +++ b/src/lib/providers/validation.ts @@ -69,7 +69,6 @@ import { buildRunwayHeaders, normalizeRunwayBaseUrl, } from "@omniroute/open-sse/config/runway.ts"; -import { PETALS_DEFAULT_MODEL, normalizePetalsBaseUrl } from "@omniroute/open-sse/config/petals.ts"; import { buildMaritalkChatUrl, buildMaritalkModelsUrl, @@ -961,10 +960,6 @@ async function validateAssemblyAIProvider({ apiKey, providerSpecificData = {} }: } } -async function validateNanoBananaProvider({ apiKey, providerSpecificData = {} }: any) { - return validateImageProviderApiKey({ provider: "nanobanana", apiKey, providerSpecificData }); -} - async function validateElevenLabsProvider({ apiKey, providerSpecificData = {} }: any) { try { // Lightweight auth check endpoint @@ -2013,67 +2008,6 @@ async function validateRunwayProvider({ apiKey, providerSpecificData = {} }: any return { valid: false, error: "Connection failed while testing Runway" }; } -async function validatePetalsProvider({ apiKey, providerSpecificData = {} }: any) { - const url = normalizePetalsBaseUrl(providerSpecificData.baseUrl); - const modelId = - typeof providerSpecificData.validationModelId === "string" && - providerSpecificData.validationModelId.trim() - ? providerSpecificData.validationModelId.trim() - : PETALS_DEFAULT_MODEL; - const headers: Record = { - "Content-Type": "application/x-www-form-urlencoded", - }; - if (apiKey) { - headers.Authorization = `Bearer ${apiKey}`; - } - - const body = new URLSearchParams({ - model: modelId, - inputs: "test", - max_new_tokens: "1", - }); - - try { - const response = await validationWrite(url, { - method: "POST", - headers, - body: body.toString(), - }); - - if (response.ok) { - const payload = (await response.json().catch(() => ({}))) as Record; - if (payload.ok === false) { - return { - valid: false, - error: "Petals API rejected validation request", - }; - } - return { valid: true, error: null, method: "petals_generate" }; - } - - if (response.status === 401 || response.status === 403) { - return { valid: false, error: "Invalid API key" }; - } - - if (response.status === 429) { - return { - valid: true, - error: null, - method: "petals_generate", - warning: "Rate limited, but endpoint is reachable", - }; - } - - if (response.status >= 500) { - return { valid: false, error: `Provider unavailable (${response.status})` }; - } - } catch (error: any) { - return toValidationErrorResult(error); - } - - return { valid: false, error: "Connection failed while testing Petals" }; -} - async function validateNousResearchProvider({ apiKey, providerSpecificData = {} }: any) { const baseUrl = normalizeBaseUrl(providerSpecificData.baseUrl) || "https://inference-api.nousresearch.com/v1"; @@ -3785,7 +3719,6 @@ export async function validateProviderApiKey({ provider, apiKey, providerSpecifi "command-code": validateCommandCodeProvider, deepgram: validateDeepgramProvider, assemblyai: validateAssemblyAIProvider, - nanobanana: validateNanoBananaProvider, "fal-ai": ({ apiKey, providerSpecificData }: any) => validateImageProviderApiKey({ provider: "fal-ai", apiKey, providerSpecificData }), "stability-ai": ({ apiKey, providerSpecificData }: any) => @@ -3818,7 +3751,6 @@ export async function validateProviderApiKey({ provider, apiKey, providerSpecifi isLocal, }), "nous-research": validateNousResearchProvider, - petals: validatePetalsProvider, poe: validatePoeProvider, clarifai: validateClarifaiProvider, reka: validateRekaProvider, @@ -3970,37 +3902,6 @@ export async function validateProviderApiKey({ provider, apiKey, providerSpecifi return toValidationErrorResult(error); } }, - // Poolside (#2723) — API has no /v1/models endpoint and returns 401 from - // unknown routes, which the generic /models probe misreads as "invalid API key". - // Validate via direct chat/completions probe with a minimal body. - poolside: async ({ apiKey, providerSpecificData }: any) => { - try { - const baseUrl = normalizeBaseUrl( - providerSpecificData?.baseUrl || "https://api.poolside.ai/v1" - ); - const chatUrl = `${baseUrl.replace(/\/chat\/completions$/, "")}/chat/completions`; - const res = await validationWrite( - chatUrl, - { - method: "POST", - headers: buildBearerHeaders(apiKey, providerSpecificData), - body: JSON.stringify({ - model: "poolside-model", - messages: [{ role: "user", content: "test" }], - max_tokens: 1, - }), - }, - isLocal - ); - if (res.status === 401 || res.status === 403) { - return { valid: false, error: "Invalid API key" }; - } - // Any non-auth response (200, 400, 422, 429) means auth passed - return { valid: true, error: null }; - } catch (error: any) { - return toValidationErrorResult(error); - } - }, // Xiaomi MiMo — Token Plan keys (tp-*) only work on regional endpoints // (e.g. token-plan-sgp, token-plan-ams), not api.xiaomimimo.com. // /v1/models works but validate via chat/completions for stronger auth check. diff --git a/src/shared/constants/providers.ts b/src/shared/constants/providers.ts index 7f6a7ef57c..d30a90c893 100644 --- a/src/shared/constants/providers.ts +++ b/src/shared/constants/providers.ts @@ -585,31 +585,6 @@ export const APIKEY_PROVIDERS = { "55 free tier models including Grok-3, Claude 3.7, Qwen3, Kimi-K2, Gemini 2.5 Flash, DeepSeek-V3", apiHint: "Get your API key from https://panel.api.airforce — OpenAI-compatible endpoint at https://api.airforce/v1", - capabilities: { embeddings: false }, - }, - astraflow: { - id: "astraflow", - alias: "astraflow", - name: "Astraflow (UCloud Global)", - icon: "cloud", - color: "#0052D9", - textIcon: "AF", - passthroughModels: true, - website: "https://astraflow.ucloud-global.com", - apiHint: - "Astraflow by UCloud — OpenAI-compatible platform supporting 200+ models (global endpoint). Get your API key at https://astraflow.ucloud-global.com", - }, - "astraflow-cn": { - id: "astraflow-cn", - alias: "astraflow-cn", - name: "Astraflow (UCloud China)", - icon: "cloud", - color: "#0052D9", - textIcon: "AFC", - passthroughModels: true, - website: "https://astraflow.ucloud.cn", - apiHint: - "Astraflow by UCloud — OpenAI-compatible platform supporting 200+ models (China endpoint). Get your API key at https://astraflow.ucloud.cn", }, qianfan: { id: "qianfan", @@ -934,32 +909,6 @@ export const APIKEY_PROVIDERS = { freeNote: "Free unlimited access to Claude, GPT, Gemini — no credit card, no rate limits", apiHint: "Sign up at https://completions.me for free API key. OpenAI-compatible endpoint.", }, - enally: { - id: "enally", - alias: "enly", - name: "Enally AI", - icon: "school", - color: "#8B5CF6", - textIcon: "EN", - website: "https://ai.enally.in", - hasFree: true, - freeNote: "Free for students and developers — no credit card, OTP verification", - apiHint: - "Get free API key at https://ai.enally.in/api — requires email and domain whitelisting.", - }, - freetheai: { - id: "freetheai", - alias: "fta", - name: "FreeTheAi", - icon: "lock_open", - color: "#10B981", - textIcon: "FT", - website: "https://freetheai.xyz", - hasFree: true, - freeNote: "Community-run — free forever, no paid tiers, no credit card", - apiHint: - "Get free API key via Discord: https://freetheai.xyz — 16,000+ models, OpenAI-compatible.", - }, xai: { id: "xai", alias: "xai", @@ -1078,15 +1027,6 @@ export const APIKEY_PROVIDERS = { 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", - }, kie: { id: "kie", alias: "kie", @@ -1255,20 +1195,6 @@ export const APIKEY_PROVIDERS = { passthroughModels: true, authHint: "No auth required. API accepts any non-empty string as key for identification.", }, - replicate: { - id: "replicate", - alias: "rep", - name: "Replicate", - icon: "auto_awesome", - color: "#3B82F6", - textIcon: "RE", - website: "https://replicate.com", - hasFree: true, - freeNote: - "Free community models — Llama 3.1, Mixtral, DeepSeek R1. Passthrough for SDXL, Whisper, MusicGen.", - passthroughModels: true, - authHint: "Get API token at replicate.com/account/api-tokens", - }, hackclub: { id: "hackclub", alias: "hc", @@ -1512,17 +1438,6 @@ export const APIKEY_PROVIDERS = { apiHint: "Works without API key (use 'unused' as key). Get free token at token.llm7.io for higher limits.", }, - lepton: { - id: "lepton", - alias: "lepton", - name: "Lepton AI", - icon: "bolt", - color: "#10B981", - textIcon: "LP", - website: "https://lepton.ai", - hasFree: true, - freeNote: "Free tier available - fast inference on custom hardware", - }, kluster: { id: "kluster", alias: "kluster", @@ -1897,19 +1812,6 @@ export const APIKEY_PROVIDERS = { 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", @@ -2198,19 +2100,6 @@ export const APIKEY_PROVIDERS = { passthroughModels: true, authHint: "Get API key from your Dify instance.", }, - poolside: { - id: "poolside", - alias: "poolside", - name: "Poolside", - icon: "code", - color: "#3B82F6", - textIcon: "PS", - website: "https://poolside.ai", - hasFree: true, - freeNote: "Free Laguna XS.2 and Laguna M.1 coding agent models. No credit card required.", - passthroughModels: true, - authHint: "Get API key at poolside.ai", - }, "arcee-ai": { id: "arcee-ai", alias: "arcee", @@ -2264,19 +2153,6 @@ export const APIKEY_PROVIDERS = { passthroughModels: true, authHint: "Get API key at atlas.nomic.ai", }, - krutrim: { - id: "krutrim", - alias: "krutrim", - name: "Krutrim", - icon: "auto_awesome", - color: "#F59E0B", - textIcon: "KR", - website: "https://krutrim.ai", - hasFree: true, - freeNote: "India's first AI (by Ola). Free tier available. No credit card required.", - passthroughModels: true, - authHint: "Get API key at krutrim.ai", - }, monsterapi: { id: "monsterapi", alias: "monster",