From d4bc42e1f593802e78f28d3aa36b37dc0d4262d8 Mon Sep 17 00:00:00 2001 From: decolua Date: Tue, 5 May 2026 10:32:59 +0700 Subject: [PATCH] feat: add STT support, Gemini TTS, and expand usage tracking - Speech-to-Text: full pipeline with sttCore handler, /v1/audio/transcriptions endpoint, sttConfig for OpenAI, Gemini, Groq, Deepgram, AssemblyAI, HuggingFace, NVIDIA Parakeet; new 9router-stt skill - Gemini TTS: add gemini provider with 30 prebuilt voices and TTS_PROVIDER_CONFIG - Usage: implement GLM (intl/cn) and MiniMax (intl/cn) quota fetchers; refactor Gemini CLI usage to use retrieveUserQuota with per-model buckets - Disabled models: lowdb-backed disabledModelsDb + /api/models/disabled route - Header search: reusable Zustand store (headerSearchStore) wired into Header - CLI tools: add Claude Cowork tool card and cowork-settings API - Providers: introduce mediaPriority sorting in getProvidersByKind, add Kimi K2.6, reorder hermes, drop qwen STT kind - UI: expand media-providers/[kind]/[id] page (+314), enhance OAuthModal, ModelSelectModal, ProviderTopology, ProxyPools, ProviderLimits - Assets: refresh provider PNGs (alicode, byteplus, cloudflare-ai, nvidia, ollama, vertex, volcengine-ark) and add aws-polly, fal-ai, jina-ai, recraft, runwayml, stability-ai, topaz, black-forest-labs --- open-sse/config/providerModels.js | 29 ++ open-sse/config/ttsModels.js | 20 + open-sse/handlers/sttCore.js | 194 +++++++++ open-sse/handlers/ttsCore.js | 6 +- open-sse/handlers/ttsProviders/gemini.js | 117 +++++ open-sse/handlers/ttsProviders/index.js | 5 +- open-sse/services/usage.js | 345 ++++++++++++++- open-sse/utils/reasoningContentInjector.js | 6 +- package.json | 2 +- public/providers/alicode-intl.png | Bin 4859 -> 3546 bytes public/providers/alicode.png | Bin 4859 -> 3546 bytes public/providers/aws-polly.png | Bin 0 -> 30178 bytes public/providers/black-forest-labs.png | Bin 0 -> 4654 bytes public/providers/byteplus.png | Bin 2924 -> 2709 bytes public/providers/cloudflare-ai.png | Bin 24109 -> 3947 bytes public/providers/fal-ai.png | Bin 0 -> 6389 bytes public/providers/jina-ai.png | Bin 0 -> 3874 bytes public/providers/nebius.png | Bin 4287 -> 3837 bytes public/providers/nvidia.png | Bin 3517 -> 10349 bytes public/providers/ollama-local.png | Bin 7487 -> 5637 bytes public/providers/ollama.png | Bin 7487 -> 5637 bytes public/providers/recraft.png | Bin 0 -> 4083 bytes public/providers/runwayml.png | Bin 0 -> 5346 bytes public/providers/stability-ai.png | Bin 0 -> 24455 bytes public/providers/topaz.png | Bin 0 -> 1134 bytes public/providers/vertex-partner.png | Bin 10060 -> 8908 bytes public/providers/vertex.png | Bin 10060 -> 8908 bytes public/providers/volcengine-ark.png | Bin 41730 -> 6005 bytes skills/9router-stt/SKILL.md | 77 ++++ skills/9router/SKILL.md | 1 + skills/README.md | 1 + .../dashboard/cli-tools/CLIToolsPageClient.js | 27 +- .../cli-tools/components/CoworkToolCard.js | 401 ++++++++++++++++++ .../dashboard/cli-tools/components/index.js | 1 + .../media-providers/[kind]/[id]/page.js | 323 +++++++++++++- .../providers/[id]/AddCustomModelModal.js | 18 +- .../dashboard/providers/[id]/ModelRow.js | 15 +- .../dashboard/providers/[id]/page.js | 147 ++++++- .../providers/components/ModelsCard.js | 10 +- .../(dashboard)/dashboard/providers/page.js | 84 +++- .../(dashboard)/dashboard/proxy-pools/page.js | 208 ++++++++- .../usage/components/ProviderLimits/index.js | 36 +- .../usage/components/ProviderTopology.js | 41 +- .../api/cli-tools/cowork-settings/route.js | 246 +++++++++++ .../api/media-providers/tts/voices/route.js | 3 +- src/app/api/models/disabled/route.js | 50 +++ src/app/api/models/route.js | 27 +- .../api/oauth/[provider]/[action]/route.js | 36 +- src/app/api/providers/route.js | 4 +- src/app/api/providers/validate/route.js | 2 +- src/app/api/usage/[connectionId]/route.js | 36 +- src/app/api/v1/audio/transcriptions/route.js | 19 + src/lib/disabledModelsDb.js | 67 +++ src/lib/initCloudSync.js | 16 +- src/lib/oauth/utils/server.js | 124 +++++- src/mitm/dns/dnsConfig.js | 43 +- src/shared/components/Header.js | 36 ++ src/shared/components/ModelSelectModal.js | 46 +- src/shared/components/OAuthModal.js | 79 +++- src/shared/components/Sidebar.js | 2 +- src/shared/constants/cliTools.js | 24 +- src/shared/constants/providers.js | 53 ++- src/shared/constants/skills.js | 7 + src/shared/constants/ttsProviders.js | 10 + src/sse/handlers/stt.js | 88 ++++ src/sse/handlers/tts.js | 13 +- src/store/headerSearchStore.js | 19 + 67 files changed, 2930 insertions(+), 234 deletions(-) create mode 100644 open-sse/handlers/sttCore.js create mode 100644 open-sse/handlers/ttsProviders/gemini.js create mode 100644 public/providers/aws-polly.png create mode 100644 public/providers/black-forest-labs.png mode change 100755 => 100644 public/providers/byteplus.png create mode 100644 public/providers/fal-ai.png create mode 100644 public/providers/jina-ai.png create mode 100644 public/providers/recraft.png create mode 100644 public/providers/runwayml.png create mode 100644 public/providers/stability-ai.png create mode 100644 public/providers/topaz.png create mode 100644 skills/9router-stt/SKILL.md create mode 100644 src/app/(dashboard)/dashboard/cli-tools/components/CoworkToolCard.js create mode 100644 src/app/api/cli-tools/cowork-settings/route.js create mode 100644 src/app/api/models/disabled/route.js create mode 100644 src/app/api/v1/audio/transcriptions/route.js create mode 100644 src/lib/disabledModelsDb.js create mode 100644 src/sse/handlers/stt.js create mode 100644 src/store/headerSearchStore.js diff --git a/open-sse/config/providerModels.js b/open-sse/config/providerModels.js index 1e991183..a0888ed7 100644 --- a/open-sse/config/providerModels.js +++ b/open-sse/config/providerModels.js @@ -156,6 +156,7 @@ export const PROVIDER_MODELS = { { id: "gpt-5.3-codex", name: "GPT 5.3 Codex" }, ], kmc: [ // Kimi Coding + { id: "kimi-k2.6", name: "Kimi K2.6" }, { id: "kimi-k2.5", name: "Kimi K2.5" }, { id: "kimi-k2.5-thinking", name: "Kimi K2.5 Thinking" }, { id: "kimi-latest", name: "Kimi Latest" }, @@ -233,6 +234,10 @@ export const PROVIDER_MODELS = { { id: "tts-1", name: "TTS-1", type: "tts" }, { id: "tts-1-hd", name: "TTS-1 HD", type: "tts" }, { id: "gpt-4o-mini-tts", name: "GPT-4o Mini TTS", type: "tts" }, + // STT models + { id: "whisper-1", name: "Whisper 1", type: "stt", params: ["language", "response_format", "temperature", "prompt"] }, + { id: "gpt-4o-transcribe", name: "GPT-4o Transcribe", type: "stt", params: ["language", "response_format", "temperature", "prompt"] }, + { id: "gpt-4o-mini-transcribe", name: "GPT-4o Mini Transcribe", type: "stt", params: ["language", "response_format", "temperature", "prompt"] }, // Image models { id: "gpt-image-1", name: "GPT Image 1", type: "image", params: ["n", "size", "quality", "response_format"] }, { id: "dall-e-3", name: "DALL-E 3", type: "image", params: ["size", "quality", "style", "response_format"] }, @@ -267,6 +272,11 @@ export const PROVIDER_MODELS = { { id: "gemini-3.1-flash-image-preview", name: "Gemini 3.1 Flash Image (Nano Banana 2)", type: "image", params: [] }, { id: "gemini-3-pro-image-preview", name: "Gemini 3 Pro Image (Nano Banana Pro)", type: "image", params: [] }, { id: "gemini-2.5-flash-image", name: "Gemini 2.5 Flash Image (Nano Banana)", type: "image", params: [] }, + // STT models (multimodal generateContent) + { id: "gemini-2.5-pro", name: "Gemini 2.5 Pro (Best)", type: "stt", params: ["language", "prompt"] }, + { id: "gemini-2.5-flash", name: "Gemini 2.5 Flash", type: "stt", params: ["language", "prompt"] }, + { id: "gemini-2.5-flash-lite", name: "Gemini 2.5 Flash Lite (Cheapest)", type: "stt", params: ["language", "prompt"] }, + { id: "gemini-2.0-flash", name: "Gemini 2.0 Flash", type: "stt", params: ["language", "prompt"] }, ], openrouter: [ // Embedding models @@ -301,6 +311,7 @@ export const PROVIDER_MODELS = { { id: "glm-4.5-air", name: "GLM-4.5-Air" }, ], kimi: [ + { id: "kimi-k2.6", name: "Kimi K2.6" }, { id: "kimi-k2.5", name: "Kimi K2.5" }, { id: "kimi-k2.5-thinking", name: "Kimi K2.5 Thinking" }, { id: "kimi-latest", name: "Kimi Latest" }, @@ -402,6 +413,10 @@ export const PROVIDER_MODELS = { { id: "meta-llama/llama-4-maverick-17b-128e-instruct", name: "Llama 4 Maverick" }, { id: "qwen/qwen3-32b", name: "Qwen3 32B" }, { id: "openai/gpt-oss-120b", name: "GPT-OSS 120B" }, + // STT models + { id: "whisper-large-v3", name: "Whisper Large v3", type: "stt", params: ["language", "response_format", "temperature", "prompt"] }, + { id: "whisper-large-v3-turbo", name: "Whisper Large v3 Turbo", type: "stt", params: ["language", "response_format", "temperature", "prompt"] }, + { id: "distil-whisper-large-v3-en", name: "Distil Whisper Large v3 EN", type: "stt", params: ["language", "response_format", "temperature", "prompt"] }, ], xai: [ { id: "grok-4", name: "Grok 4" }, @@ -450,6 +465,8 @@ export const PROVIDER_MODELS = { { id: "minimaxai/minimax-m2.7", name: "Minimax M2.7" }, { id: "z-ai/glm4.7", name: "GLM 4.7" }, { id: "nvidia/nv-embedqa-e5-v5", name: "NV EmbedQA E5 v5", type: "embedding" }, + // STT models + { id: "nvidia/parakeet-ctc-1.1b-asr", name: "Parakeet CTC 1.1B", type: "stt", params: ["language"] }, ], nebius: [ { id: "meta-llama/Llama-3.3-70B-Instruct", name: "Llama 3.3 70B Instruct" }, @@ -555,6 +572,18 @@ export const PROVIDER_MODELS = { huggingface: [ { id: "black-forest-labs/FLUX.1-schnell", name: "FLUX.1 Schnell", type: "image", params: [] }, { id: "stabilityai/stable-diffusion-xl-base-1.0", name: "SDXL Base 1.0", type: "image", params: [] }, + // STT models + { id: "openai/whisper-large-v3", name: "Whisper Large v3 (HF)", type: "stt", params: ["language"] }, + { id: "openai/whisper-small", name: "Whisper Small (HF)", type: "stt", params: ["language"] }, + ], + deepgram: [ + { id: "nova-3", name: "Nova 3", type: "stt", params: ["language"] }, + { id: "nova-2", name: "Nova 2", type: "stt", params: ["language"] }, + { id: "whisper-large", name: "Whisper Large", type: "stt", params: ["language"] }, + ], + assemblyai: [ + { id: "universal-3-pro", name: "Universal 3 Pro", type: "stt", params: ["language"] }, + { id: "universal-2", name: "Universal 2", type: "stt", params: ["language"] }, ], "fal-ai": [ { id: "fal-ai/flux/schnell", name: "FLUX Schnell", type: "image", params: ["n", "size"] }, diff --git a/open-sse/config/ttsModels.js b/open-sse/config/ttsModels.js index b9dd539b..78ae7fbe 100644 --- a/open-sse/config/ttsModels.js +++ b/open-sse/config/ttsModels.js @@ -24,6 +24,15 @@ const VOICES_STANDARD = v("alloy", "ash", "coral", "echo", "fable", "nova", "ony // 13 voices for gpt-4o-mini-tts const VOICES_FULL = v("alloy", "ash", "ballad", "cedar", "coral", "echo", "fable", "marin", "nova", "onyx", "sage", "shimmer", "verse"); +// Gemini prebuilt voices (30 voices, multi-language auto-detect) +const GEMINI_VOICES = [ + "Zephyr", "Puck", "Charon", "Kore", "Fenrir", "Leda", "Orus", "Aoede", + "Callirrhoe", "Autonoe", "Enceladus", "Iapetus", "Umbriel", "Algieba", + "Despina", "Erinome", "Algenib", "Rasalgethi", "Laomedeia", "Achernar", + "Alnilam", "Schedar", "Gacrux", "Pulcherrima", "Achird", "Zubenelgenubi", + "Vindemiatrix", "Sadachbia", "Sadaltager", "Sulafat", +].map((id) => ({ id, name: id, type: "tts" })); + // ── TTS Config (config-driven, single source of truth) ───────────────────── export const TTS_MODELS_CONFIG = { openai: { @@ -85,6 +94,17 @@ export const TTS_MODELS_CONFIG = { "google-tts": { defaults: GOOGLE_TTS_LANGUAGES, }, + gemini: { + models: [ + { id: "gemini-2.5-flash-preview-tts", name: "Gemini 2.5 Flash TTS", type: "tts" }, + { id: "gemini-2.5-pro-preview-tts", name: "Gemini 2.5 Pro TTS", type: "tts" }, + ], + voices: { + "gemini-2.5-flash-preview-tts": GEMINI_VOICES, + "gemini-2.5-pro-preview-tts": GEMINI_VOICES, + }, + allVoices: GEMINI_VOICES, + }, }; // ── Helper: get voices for a specific model ──────────────────────────────── diff --git a/open-sse/handlers/sttCore.js b/open-sse/handlers/sttCore.js new file mode 100644 index 00000000..cfce0580 --- /dev/null +++ b/open-sse/handlers/sttCore.js @@ -0,0 +1,194 @@ +import { Buffer } from "node:buffer"; +import { createErrorResult } from "../utils/error.js"; +import { HTTP_STATUS } from "../config/runtimeConfig.js"; +import { AI_PROVIDERS } from "../../src/shared/constants/providers.js"; + +// Build auth headers from sttConfig + token +function buildAuthHeaders(cfg, token) { + if (!token) return {}; + switch (cfg.authHeader) { + case "bearer": return { "Authorization": `Bearer ${token}` }; + case "token": return { "Authorization": `Token ${token}` }; + case "x-api-key": return { "x-api-key": token }; + case "key": return { "Authorization": `Key ${token}` }; + default: return { "Authorization": `Bearer ${token}` }; + } +} + +// Map browser file MIME / ext → audio MIME for binary formats (deepgram/HF) +function resolveAudioContentType(file) { + const t = (file.type || "").toLowerCase(); + if (t.startsWith("audio/")) return t; + const name = typeof file.name === "string" ? file.name.toLowerCase() : ""; + const ext = name.includes(".") ? name.split(".").pop() : ""; + const map = { mp3: "audio/mpeg", mp4: "audio/mp4", m4a: "audio/mp4", wav: "audio/wav", ogg: "audio/ogg", flac: "audio/flac", webm: "audio/webm", aac: "audio/aac", opus: "audio/opus" }; + return map[ext] || "application/octet-stream"; +} + +async function upstreamError(res) { + let txt = ""; + try { txt = await res.text(); } catch {} + let msg = txt || `Upstream error (${res.status})`; + try { const j = JSON.parse(txt); msg = j?.error?.message || j?.error || j?.message || msg; } catch {} + return createErrorResult(res.status, typeof msg === "string" ? msg : JSON.stringify(msg)); +} + +// Deepgram: raw binary POST + model query param +async function transcribeDeepgram(cfg, file, model, token, formData) { + const url = new URL(cfg.baseUrl); + url.searchParams.set("model", model); + url.searchParams.set("smart_format", "true"); + url.searchParams.set("punctuate", "true"); + const lang = formData.get("language"); + if (typeof lang === "string" && lang.trim()) url.searchParams.set("language", lang.trim()); + else url.searchParams.set("detect_language", "true"); + + const buf = await file.arrayBuffer(); + const res = await fetch(url, { + method: "POST", + headers: { ...buildAuthHeaders(cfg, token), "Content-Type": resolveAudioContentType(file) }, + body: buf, + }); + if (!res.ok) return upstreamError(res); + const data = await res.json(); + const text = data.results?.channels?.[0]?.alternatives?.[0]?.transcript ?? ""; + return jsonResponse({ text }); +} + +// AssemblyAI: upload → submit → poll (max 120s) +async function transcribeAssemblyAI(cfg, file, model, token) { + const auth = buildAuthHeaders(cfg, token); + const buf = await file.arrayBuffer(); + const up = await fetch("https://api.assemblyai.com/v2/upload", { + method: "POST", headers: { ...auth, "Content-Type": "application/octet-stream" }, body: buf, + }); + if (!up.ok) return upstreamError(up); + const { upload_url } = await up.json(); + + const sub = await fetch(cfg.baseUrl, { + method: "POST", + headers: { ...auth, "Content-Type": "application/json" }, + body: JSON.stringify({ audio_url: upload_url, speech_models: [model], language_detection: true }), + }); + if (!sub.ok) return upstreamError(sub); + const { id } = await sub.json(); + + const start = Date.now(); + while (Date.now() - start < 120_000) { + await new Promise((r) => setTimeout(r, 2000)); + const poll = await fetch(`${cfg.baseUrl}/${id}`, { headers: auth }); + if (!poll.ok) continue; + const r = await poll.json(); + if (r.status === "completed") return jsonResponse({ text: r.text || "" }); + if (r.status === "error") return createErrorResult(500, r.error || "AssemblyAI failed"); + } + return createErrorResult(504, "AssemblyAI timeout after 120s"); +} + +// Nvidia NIM: multipart, normalize response +async function transcribeNvidia(cfg, file, model, token) { + const fd = new FormData(); + fd.append("file", file, file.name || "audio.wav"); + fd.append("model", model); + const res = await fetch(cfg.baseUrl, { method: "POST", headers: buildAuthHeaders(cfg, token), body: fd }); + if (!res.ok) return upstreamError(res); + const data = await res.json(); + return jsonResponse({ text: data.text || data.transcript || "" }); +} + +// Gemini: generateContent with inline_data audio + transcription prompt +async function transcribeGemini(cfg, file, model, token, formData) { + const buf = await file.arrayBuffer(); + const b64 = Buffer.from(buf).toString("base64"); + const mime = resolveAudioContentType(file); + const lang = formData.get("language"); + const userPrompt = formData.get("prompt"); + let promptText = userPrompt && typeof userPrompt === "string" && userPrompt.trim() + ? userPrompt.trim() + : "Generate a transcript of the speech. Return only the transcribed text, no commentary."; + if (typeof lang === "string" && lang.trim()) promptText += ` Language: ${lang.trim()}.`; + + const url = `${cfg.baseUrl}/${model}:generateContent?key=${token}`; + const res = await fetch(url, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + contents: [{ parts: [{ text: promptText }, { inline_data: { mime_type: mime, data: b64 } }] }], + }), + }); + if (!res.ok) return upstreamError(res); + const data = await res.json(); + const text = data?.candidates?.[0]?.content?.parts?.map((p) => p.text).filter(Boolean).join("") || ""; + return jsonResponse({ text }); +} + +// HuggingFace: POST raw binary to {baseUrl}/{model_id} +async function transcribeHuggingFace(cfg, file, model, token) { + if (model.includes("..") || model.includes("//")) return createErrorResult(400, "Invalid model ID"); + const url = `${cfg.baseUrl.replace(/\/+$/, "")}/${model}`; + const buf = await file.arrayBuffer(); + const res = await fetch(url, { + method: "POST", + headers: { ...buildAuthHeaders(cfg, token), "Content-Type": resolveAudioContentType(file) }, + body: buf, + }); + if (!res.ok) return upstreamError(res); + const data = await res.json(); + return jsonResponse({ text: data.text || "" }); +} + +// Default: OpenAI/Groq/Whisper-compatible multipart +async function transcribeOpenAICompatible(cfg, file, model, token, formData) { + const fd = new FormData(); + fd.append("file", file, file.name || "audio.wav"); + fd.append("model", model); + for (const k of ["language", "prompt", "response_format", "temperature"]) { + const v = formData.get(k); + if (v !== null && v !== undefined && v !== "") fd.append(k, v); + } + const res = await fetch(cfg.baseUrl, { method: "POST", headers: buildAuthHeaders(cfg, token), body: fd }); + if (!res.ok) return upstreamError(res); + const ct = res.headers.get("content-type") || "application/json"; + const txt = await res.text(); + return { success: true, response: new Response(txt, { status: 200, headers: { "Content-Type": ct, "Access-Control-Allow-Origin": "*" } }) }; +} + +function jsonResponse(obj) { + return { + success: true, + response: new Response(JSON.stringify(obj), { + status: 200, + headers: { "Content-Type": "application/json", "Access-Control-Allow-Origin": "*" }, + }), + }; +} + +/** + * STT core handler — dispatch by sttConfig.format. + * @returns {Promise<{success, response, status?, error?}>} + */ +export async function handleSttCore({ provider, model, formData, credentials }) { + const file = formData.get("file"); + if (!file) return createErrorResult(HTTP_STATUS.BAD_REQUEST, "Missing required field: file"); + + const cfg = AI_PROVIDERS[provider]?.sttConfig; + if (!cfg) return createErrorResult(HTTP_STATUS.BAD_REQUEST, `Provider '${provider}' does not support STT`); + + const token = cfg.authType === "none" ? null : (credentials?.apiKey || credentials?.accessToken); + if (cfg.authType !== "none" && !token) { + return createErrorResult(HTTP_STATUS.UNAUTHORIZED, `No credentials for STT provider: ${provider}`); + } + + try { + switch (cfg.format) { + case "deepgram": return await transcribeDeepgram(cfg, file, model, token, formData); + case "assemblyai": return await transcribeAssemblyAI(cfg, file, model, token); + case "nvidia-asr": return await transcribeNvidia(cfg, file, model, token); + case "huggingface-asr": return await transcribeHuggingFace(cfg, file, model, token); + case "gemini-stt": return await transcribeGemini(cfg, file, model, token, formData); + default: return await transcribeOpenAICompatible(cfg, file, model, token, formData); + } + } catch (err) { + return createErrorResult(HTTP_STATUS.BAD_GATEWAY, err.message || "STT request failed"); + } +} diff --git a/open-sse/handlers/ttsCore.js b/open-sse/handlers/ttsCore.js index ff8c52a9..b4b69eeb 100644 --- a/open-sse/handlers/ttsCore.js +++ b/open-sse/handlers/ttsCore.js @@ -48,16 +48,16 @@ function createTtsResponse(base64Audio, format, responseFormat) { * * @returns {Promise<{success, response, status?, error?}>} */ -export async function handleTtsCore({ provider, model, input, credentials, responseFormat = "mp3" }) { +export async function handleTtsCore({ provider, model, input, credentials, responseFormat = "mp3", language }) { if (!input?.trim()) { return createErrorResult(HTTP_STATUS.BAD_REQUEST, "Missing required field: input"); } try { - // Special-case adapters (google-tts, edge-tts, local-device, elevenlabs, openai, openrouter) + // Special-case adapters (google-tts, edge-tts, local-device, elevenlabs, openai, openrouter, gemini) const adapter = getTtsAdapter(provider); if (adapter) { - const result = await adapter.synthesize(input.trim(), model, credentials, responseFormat); + const result = await adapter.synthesize(input.trim(), model, credentials, responseFormat, { language }); // Adapter may return a full {success, response} (legacy) or {base64, format} if (result.success !== undefined) return result; return createTtsResponse(result.base64, result.format, responseFormat); diff --git a/open-sse/handlers/ttsProviders/gemini.js b/open-sse/handlers/ttsProviders/gemini.js new file mode 100644 index 00000000..9dff6e11 --- /dev/null +++ b/open-sse/handlers/ttsProviders/gemini.js @@ -0,0 +1,117 @@ +// Gemini TTS — generateContent with AUDIO modality returns PCM L16, wrap as WAV +import { Buffer } from "node:buffer"; + +const DEFAULT_MODEL = "gemini-2.5-flash-preview-tts"; +const DEFAULT_VOICE = "Kore"; +const KNOWN_MODELS = ["gemini-2.5-flash-preview-tts", "gemini-2.5-pro-preview-tts"]; + +// Parse "model/voice" — if input doesn't match a known TTS model, treat it as voice with default model +function parseGeminiModelVoice(input) { + if (!input) return { modelId: DEFAULT_MODEL, voiceId: DEFAULT_VOICE }; + for (const id of KNOWN_MODELS) { + if (input === id) return { modelId: id, voiceId: DEFAULT_VOICE }; + if (input.startsWith(`${id}/`)) return { modelId: id, voiceId: input.slice(id.length + 1) }; + } + return { modelId: DEFAULT_MODEL, voiceId: input }; +} +// Gemini returns PCM 16-bit signed mono @ 24kHz +const SAMPLE_RATE = 24000; +const CHANNELS = 1; +const BITS_PER_SAMPLE = 16; + +// Build WAV header for raw PCM payload +function pcmToWav(pcmBuffer) { + const dataSize = pcmBuffer.length; + const byteRate = SAMPLE_RATE * CHANNELS * BITS_PER_SAMPLE / 8; + const blockAlign = CHANNELS * BITS_PER_SAMPLE / 8; + const header = Buffer.alloc(44); + header.write("RIFF", 0); + header.writeUInt32LE(36 + dataSize, 4); + header.write("WAVE", 8); + header.write("fmt ", 12); + header.writeUInt32LE(16, 16); + header.writeUInt16LE(1, 20); + header.writeUInt16LE(CHANNELS, 22); + header.writeUInt32LE(SAMPLE_RATE, 24); + header.writeUInt32LE(byteRate, 28); + header.writeUInt16LE(blockAlign, 32); + header.writeUInt16LE(BITS_PER_SAMPLE, 34); + header.write("data", 36); + header.writeUInt32LE(dataSize, 40); + return Buffer.concat([header, pcmBuffer]); +} + +// Build TTS prompt: add "Say [in {language}]:" prefix to force TTS mode +function buildPrompt(text, language) { + if (/:\s/.test(text)) return text; // user already provided style instruction + return language ? `Say in ${language}: ${text}` : `Say: ${text}`; +} + +export default { + async synthesize(text, model, credentials, _responseFormat, opts = {}) { + if (!credentials?.apiKey) throw new Error("No Gemini API key configured"); + const { modelId, voiceId } = parseGeminiModelVoice(model); + const url = `https://generativelanguage.googleapis.com/v1beta/models/${modelId}:generateContent?key=${credentials.apiKey}`; + const res = await fetch(url, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + contents: [{ parts: [{ text: buildPrompt(text, opts.language) }] }], + generationConfig: { + responseModalities: ["AUDIO"], + speechConfig: { voiceConfig: { prebuiltVoiceConfig: { voiceName: voiceId } } }, + }, + }), + }); + if (!res.ok) { + const err = await res.json().catch(() => ({})); + throw new Error(err?.error?.message || `Gemini TTS failed: ${res.status}`); + } + const data = await res.json(); + const b64 = data?.candidates?.[0]?.content?.parts?.find((p) => p.inlineData?.data)?.inlineData?.data; + if (!b64) { + const reason = data?.candidates?.[0]?.finishReason || data?.promptFeedback?.blockReason || "unknown"; + throw new Error(`Gemini TTS returned no audio (finishReason: ${reason}, voice: ${voiceId}, model: ${modelId})`); + } + const wav = pcmToWav(Buffer.from(b64, "base64")); + return { base64: wav.toString("base64"), format: "wav" }; + }, +}; + +// Voice fetcher — return prebuilt voices (Gemini has no list API) +const PREBUILT_VOICES = [ + { id: "Zephyr", lang: "en", gender: "Female" }, + { id: "Puck", lang: "en", gender: "Male" }, + { id: "Charon", lang: "en", gender: "Male" }, + { id: "Kore", lang: "en", gender: "Female" }, + { id: "Fenrir", lang: "en", gender: "Male" }, + { id: "Leda", lang: "en", gender: "Female" }, + { id: "Orus", lang: "en", gender: "Male" }, + { id: "Aoede", lang: "en", gender: "Female" }, + { id: "Callirrhoe", lang: "en", gender: "Female" }, + { id: "Autonoe", lang: "en", gender: "Female" }, + { id: "Enceladus", lang: "en", gender: "Male" }, + { id: "Iapetus", lang: "en", gender: "Male" }, + { id: "Umbriel", lang: "en", gender: "Male" }, + { id: "Algieba", lang: "en", gender: "Male" }, + { id: "Despina", lang: "en", gender: "Female" }, + { id: "Erinome", lang: "en", gender: "Female" }, + { id: "Algenib", lang: "en", gender: "Male" }, + { id: "Rasalgethi", lang: "en", gender: "Male" }, + { id: "Laomedeia", lang: "en", gender: "Female" }, + { id: "Achernar", lang: "en", gender: "Female" }, + { id: "Alnilam", lang: "en", gender: "Male" }, + { id: "Schedar", lang: "en", gender: "Male" }, + { id: "Gacrux", lang: "en", gender: "Female" }, + { id: "Pulcherrima", lang: "en", gender: "Female" }, + { id: "Achird", lang: "en", gender: "Male" }, + { id: "Zubenelgenubi", lang: "en", gender: "Male" }, + { id: "Vindemiatrix", lang: "en", gender: "Female" }, + { id: "Sadachbia", lang: "en", gender: "Male" }, + { id: "Sadaltager", lang: "en", gender: "Male" }, + { id: "Sulafat", lang: "en", gender: "Female" }, +]; + +export async function fetchGeminiVoices() { + return PREBUILT_VOICES.map((v) => ({ voice_id: v.id, name: v.id, labels: { language: v.lang, gender: v.gender } })); +} diff --git a/open-sse/handlers/ttsProviders/index.js b/open-sse/handlers/ttsProviders/index.js index 02345a88..f80ddf8b 100644 --- a/open-sse/handlers/ttsProviders/index.js +++ b/open-sse/handlers/ttsProviders/index.js @@ -5,6 +5,7 @@ import localDevice, { fetchLocalDeviceVoices } from "./localDevice.js"; import elevenlabs, { fetchElevenLabsVoices } from "./elevenlabs.js"; import openai from "./openai.js"; import openrouter from "./openrouter.js"; +import gemini, { fetchGeminiVoices } from "./gemini.js"; import { FORMAT_HANDLERS } from "./genericFormats.js"; import { parseModelVoice } from "./_base.js"; @@ -16,6 +17,7 @@ const SPECIAL_ADAPTERS = { elevenlabs, openai, openrouter, + gemini, }; export function getTtsAdapter(provider) { @@ -41,7 +43,8 @@ export const VOICE_FETCHERS = { "edge-tts": fetchEdgeTtsVoices, "local-device": fetchLocalDeviceVoices, elevenlabs: fetchElevenLabsVoices, + gemini: fetchGeminiVoices, }; // Re-export for backward compat -export { fetchEdgeTtsVoices, fetchLocalDeviceVoices, fetchElevenLabsVoices }; +export { fetchEdgeTtsVoices, fetchLocalDeviceVoices, fetchElevenLabsVoices, fetchGeminiVoices }; diff --git a/open-sse/services/usage.js b/open-sse/services/usage.js index 094aa86e..9bc03251 100644 --- a/open-sse/services/usage.js +++ b/open-sse/services/usage.js @@ -11,6 +11,24 @@ const GITHUB_CONFIG = { userAgent: "GitHubCopilotChat/0.26.7", }; +// GLM quota endpoints (region-aware) +const GLM_QUOTA_URLS = { + international: "https://api.z.ai/api/monitor/usage/quota/limit", + china: "https://open.bigmodel.cn/api/monitor/usage/quota/limit", +}; + +// MiniMax usage endpoints (try in order, fallback on transient errors) +const MINIMAX_USAGE_URLS = { + minimax: [ + "https://www.minimax.io/v1/token_plan/remains", + "https://api.minimax.io/v1/api/openplatform/coding_plan/remains", + ], + "minimax-cn": [ + "https://www.minimaxi.com/v1/api/openplatform/coding_plan/remains", + "https://api.minimaxi.com/v1/api/openplatform/coding_plan/remains", + ], +}; + // Antigravity API config (from Quotio) const ANTIGRAVITY_CONFIG = { quotaApiUrl: "https://cloudcode-pa.googleapis.com/v1internal:fetchAvailableModels", @@ -40,13 +58,13 @@ const CLAUDE_CONFIG = { * @returns {Object} Usage data with quotas */ export async function getUsageForProvider(connection, proxyOptions = null) { - const { provider, accessToken, providerSpecificData } = connection; + const { provider, accessToken, apiKey, providerSpecificData } = connection; switch (provider) { case "github": return await getGitHubUsage(accessToken, providerSpecificData, proxyOptions); case "gemini-cli": - return await getGeminiUsage(accessToken, proxyOptions); + return await getGeminiUsage(accessToken, providerSpecificData, proxyOptions); case "antigravity": return await getAntigravityUsage(accessToken, providerSpecificData, proxyOptions); case "claude": @@ -61,6 +79,12 @@ export async function getUsageForProvider(connection, proxyOptions = null) { return await getIflowUsage(accessToken); case "ollama": return await getOllamaUsage(accessToken); + case "glm": + case "glm-cn": + return await getGlmUsage(apiKey, provider, proxyOptions); + case "minimax": + case "minimax-cn": + return await getMiniMaxUsage(apiKey, provider, proxyOptions); default: return { message: `Usage API not implemented for ${provider}` }; } @@ -188,31 +212,115 @@ function formatGitHubQuotaSnapshot(quota) { } /** - * Gemini CLI Usage (Google Cloud) + * Gemini CLI Usage — fetch per-model quota via Cloud Code Assist API. + * Uses retrieveUserQuota (same endpoint as `gemini /stats`) returning + * per-model buckets with remainingFraction + resetTime. */ -async function getGeminiUsage(accessToken, proxyOptions = null) { +async function getGeminiUsage(accessToken, providerSpecificData, proxyOptions = null) { + if (!accessToken) { + return { plan: "Free", message: "Gemini CLI access token not available." }; + } + + try { + // Resolve project id: prefer connection-stored id, else loadCodeAssist lookup + let projectId = providerSpecificData?.projectId || null; + let plan = "Free"; + + if (!projectId) { + const subInfo = await getGeminiSubscriptionInfo(accessToken, proxyOptions); + projectId = subInfo?.cloudaicompanionProject || null; + plan = subInfo?.currentTier?.name || plan; + } + + if (!projectId) { + return { plan, message: "Gemini CLI project ID not available." }; + } + + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), 10000); + let response; + try { + response = await proxyAwareFetch( + "https://cloudcode-pa.googleapis.com/v1internal:retrieveUserQuota", + { + method: "POST", + headers: { + Authorization: `Bearer ${accessToken}`, + "Content-Type": "application/json", + }, + body: JSON.stringify({ project: projectId }), + signal: controller.signal, + }, + proxyOptions + ); + } finally { + clearTimeout(timeoutId); + } + + if (!response.ok) { + return { plan, message: `Gemini CLI quota error (${response.status}).` }; + } + + const data = await response.json(); + const quotas = {}; + + if (Array.isArray(data.buckets)) { + for (const bucket of data.buckets) { + if (!bucket.modelId || bucket.remainingFraction == null) continue; + + const remainingFraction = Number(bucket.remainingFraction) || 0; + const total = 1000; // Normalized base, matches antigravity convention + const remaining = Math.round(total * remainingFraction); + const used = Math.max(0, total - remaining); + + quotas[bucket.modelId] = { + used, + total, + resetAt: parseResetTime(bucket.resetTime), + remainingPercentage: remainingFraction * 100, + unlimited: false, + }; + } + } + + return { plan, quotas }; + } catch (error) { + return { message: `Gemini CLI error: ${error.message}` }; + } +} + +/** + * Get Gemini CLI subscription info via loadCodeAssist + */ +async function getGeminiSubscriptionInfo(accessToken, proxyOptions = null) { + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), 10000); try { - // Gemini CLI uses Google Cloud quotas - // Try to get quota info from Cloud Resource Manager const response = await proxyAwareFetch( - "https://cloudresourcemanager.googleapis.com/v1/projects?filter=lifecycleState:ACTIVE", + "https://cloudcode-pa.googleapis.com/v1internal:loadCodeAssist", { + method: "POST", headers: { Authorization: `Bearer ${accessToken}`, - Accept: "application/json", + "Content-Type": "application/json", }, + body: JSON.stringify({ + metadata: { + ideType: "IDE_UNSPECIFIED", + platform: "PLATFORM_UNSPECIFIED", + pluginType: "GEMINI", + }, + }), + signal: controller.signal, }, proxyOptions ); - - if (!response.ok) { - // Quota API may not be accessible, return generic message - return { message: "Gemini CLI uses Google Cloud quotas. Check Google Cloud Console for details." }; - } - - return { message: "Gemini CLI connected. Usage tracked via Google Cloud Console." }; - } catch (error) { - return { message: "Unable to fetch Gemini usage. Check Google Cloud Console." }; + if (!response.ok) return null; + return await response.json(); + } catch { + return null; + } finally { + clearTimeout(timeoutId); } } @@ -798,3 +906,206 @@ async function getOllamaUsage(accessToken, providerSpecificData) { return { message: "Unable to fetch Ollama Cloud usage." }; } } + +/** + * GLM Coding Plan usage (international + China regions) + */ +async function getGlmUsage(apiKey, provider, proxyOptions = null) { + if (!apiKey) { + return { message: "GLM API key not available." }; + } + + const region = provider === "glm-cn" ? "china" : "international"; + const quotaUrl = GLM_QUOTA_URLS[region]; + + try { + const response = await proxyAwareFetch(quotaUrl, { + headers: { + Authorization: `Bearer ${apiKey}`, + Accept: "application/json", + }, + }, proxyOptions); + + if (!response.ok) { + if (response.status === 401) { + return { message: "GLM API key invalid or expired." }; + } + return { message: `GLM quota API error (${response.status}).` }; + } + + const json = await response.json(); + const data = json?.data && typeof json.data === "object" ? json.data : {}; + const limits = Array.isArray(data.limits) ? data.limits : []; + const quotas = {}; + + for (const limit of limits) { + if (!limit || limit.type !== "TOKENS_LIMIT") continue; + const usedPercent = Number(limit.percentage) || 0; + const resetMs = Number(limit.nextResetTime) || 0; + const remaining = Math.max(0, 100 - usedPercent); + + quotas["session"] = { + used: usedPercent, + total: 100, + remaining, + remainingPercentage: remaining, + resetAt: resetMs > 0 ? new Date(resetMs).toISOString() : null, + unlimited: false, + }; + } + + const levelRaw = typeof data.level === "string" ? data.level : ""; + const plan = levelRaw + ? levelRaw.charAt(0).toUpperCase() + levelRaw.slice(1).toLowerCase() + : "Unknown"; + + return { plan, quotas }; + } catch (error) { + return { message: `GLM error: ${error.message}` }; + } +} + +// ── MiniMax helpers ────────────────────────────────────────────────────── +function isMiniMaxTextQuotaModel(modelName) { + const normalized = (modelName || "").trim().toLowerCase(); + return normalized.startsWith("minimax-m") || normalized.startsWith("coding-plan"); +} + +function getMiniMaxField(model, snakeKey, camelKey) { + if (!model || typeof model !== "object") return null; + return model[snakeKey] ?? model[camelKey] ?? null; +} + +function getMiniMaxSessionTotal(model) { + return Math.max(0, Number(getMiniMaxField(model, "current_interval_total_count", "currentIntervalTotalCount")) || 0); +} + +function getMiniMaxWeeklyTotal(model) { + return Math.max(0, Number(getMiniMaxField(model, "current_weekly_total_count", "currentWeeklyTotalCount")) || 0); +} + +function pickMiniMaxRepresentativeModel(models, getTotal) { + const withQuota = models.filter((m) => getTotal(m) > 0); + const pool = withQuota.length > 0 ? withQuota : models; + if (pool.length === 0) return null; + return pool.reduce((best, current) => (getTotal(current) > getTotal(best) ? current : best)); +} + +function getMiniMaxResetAt(model, capturedAtMs, remainsSnake, remainsCamel, endSnake, endCamel) { + const remainsMs = Number(getMiniMaxField(model, remainsSnake, remainsCamel)) || 0; + if (remainsMs > 0) return new Date(capturedAtMs + remainsMs).toISOString(); + return parseResetTime(getMiniMaxField(model, endSnake, endCamel)); +} + +function buildMiniMaxQuota(total, count, resetAt, countMeansRemaining) { + const safeTotal = Math.max(0, total); + const used = countMeansRemaining ? Math.max(safeTotal - count, 0) : Math.min(Math.max(0, count), safeTotal); + const remaining = Math.max(safeTotal - used, 0); + return { + used, + total: safeTotal, + remaining, + remainingPercentage: safeTotal > 0 ? Math.max(0, Math.min(100, (remaining / safeTotal) * 100)) : 0, + resetAt, + unlimited: false, + }; +} + +/** + * MiniMax Token Plan / Coding Plan usage + */ +async function getMiniMaxUsage(apiKey, provider, proxyOptions = null) { + if (!apiKey) { + return { message: "MiniMax API key not available." }; + } + + const usageUrls = MINIMAX_USAGE_URLS[provider] || []; + let lastErrorMessage = ""; + + for (let index = 0; index < usageUrls.length; index += 1) { + const usageUrl = usageUrls[index]; + const canFallback = index < usageUrls.length - 1; + + try { + const response = await proxyAwareFetch(usageUrl, { + method: "GET", + headers: { + Authorization: `Bearer ${apiKey}`, + Accept: "application/json", + "Content-Type": "application/json", + }, + }, proxyOptions); + + const rawText = await response.text(); + let payload = {}; + if (rawText) { + try { payload = JSON.parse(rawText); } catch { payload = {}; } + } + + const baseResp = (payload?.base_resp ?? payload?.baseResp) || {}; + const apiStatusCode = Number(baseResp.status_code ?? baseResp.statusCode) || 0; + const apiStatusMessage = String(baseResp.status_msg ?? baseResp.statusMsg ?? "").trim(); + const combined = `${apiStatusMessage} ${rawText}`.trim(); + const authLike = /token plan|coding plan|invalid api key|invalid key|unauthorized|inactive/i; + + if (response.status === 401 || response.status === 403 || apiStatusCode === 1004 || authLike.test(combined)) { + return { message: "MiniMax API key invalid or inactive. Use an active Token/Coding Plan key." }; + } + + if (!response.ok) { + lastErrorMessage = `MiniMax usage endpoint error (${response.status})`; + if ((response.status === 404 || response.status === 405 || response.status >= 500) && canFallback) continue; + return { message: `MiniMax connected. ${lastErrorMessage}` }; + } + + if (apiStatusCode !== 0) { + return { message: `MiniMax connected. ${apiStatusMessage || "Upstream quota API error"}` }; + } + + const modelRemains = payload?.model_remains ?? payload?.modelRemains; + const allModels = Array.isArray(modelRemains) ? modelRemains : []; + const textModels = allModels.filter((m) => isMiniMaxTextQuotaModel(String(getMiniMaxField(m, "model_name", "modelName")))); + + if (textModels.length === 0) { + return { message: "MiniMax connected. No text quota data was returned." }; + } + + const capturedAtMs = Date.now(); + const countMeansRemaining = usageUrl.includes("/coding_plan/remains"); + const quotas = {}; + + const sessionModel = pickMiniMaxRepresentativeModel(textModels, getMiniMaxSessionTotal); + if (sessionModel) { + const total = getMiniMaxSessionTotal(sessionModel); + const count = Math.max(0, Number(getMiniMaxField(sessionModel, "current_interval_usage_count", "currentIntervalUsageCount")) || 0); + quotas["session (5h)"] = buildMiniMaxQuota( + total, count, + getMiniMaxResetAt(sessionModel, capturedAtMs, "remains_time", "remainsTime", "end_time", "endTime"), + countMeansRemaining + ); + } + + const weeklyModel = pickMiniMaxRepresentativeModel(textModels, getMiniMaxWeeklyTotal); + if (weeklyModel && getMiniMaxWeeklyTotal(weeklyModel) > 0) { + const total = getMiniMaxWeeklyTotal(weeklyModel); + const count = Math.max(0, Number(getMiniMaxField(weeklyModel, "current_weekly_usage_count", "currentWeeklyUsageCount")) || 0); + quotas["weekly (7d)"] = buildMiniMaxQuota( + total, count, + getMiniMaxResetAt(weeklyModel, capturedAtMs, "weekly_remains_time", "weeklyRemainsTime", "weekly_end_time", "weeklyEndTime"), + countMeansRemaining + ); + } + + if (Object.keys(quotas).length === 0) { + return { message: "MiniMax connected. Unable to extract quota usage." }; + } + + return { quotas }; + } catch (error) { + lastErrorMessage = error.message; + if (!canFallback) break; + } + } + + return { message: lastErrorMessage ? `MiniMax connected. Unable to fetch usage: ${lastErrorMessage}` : "MiniMax connected. Unable to fetch usage." }; +} diff --git a/open-sse/utils/reasoningContentInjector.js b/open-sse/utils/reasoningContentInjector.js index 80cd9315..0f28496a 100644 --- a/open-sse/utils/reasoningContentInjector.js +++ b/open-sse/utils/reasoningContentInjector.js @@ -16,8 +16,10 @@ const MODEL_RULES = [ ]; function shouldInject(message, scope) { - if (message?.role !== "assistant" || "reasoning_content" in message) return false; - if (scope === "toolCalls") return Array.isArray(message.tool_calls); + if (message?.role !== "assistant") return false; + const rc = message.reasoning_content; + if (typeof rc === "string" && rc.length > 0) return false; + if (scope === "toolCalls") return Array.isArray(message.tool_calls) && message.tool_calls.length > 0; return true; } diff --git a/package.json b/package.json index 948996be..6a9d691f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "9router-app", - "version": "0.4.16", + "version": "0.4.17", "description": "9Router web dashboard", "private": true, "scripts": { diff --git a/public/providers/alicode-intl.png b/public/providers/alicode-intl.png index 21c3ef3df575a3dd0a19ef8d384dee023f8421d7..9bee7d5b4d42f85a5ff6302b4fb6a9f14a40387c 100644 GIT binary patch literal 3546 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 b3L8axIA2ev8@u`F?_C8oG&5+_bB_NHeLQQu literal 4859 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 b3L8axIA2ev8@u`F?_C8oG&5+_bB_NHeLQQu literal 4859 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 I#>n;gze)e!4FCWD literal 2924 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 diff --git a/public/providers/cloudflare-ai.png b/public/providers/cloudflare-ai.png index d2e8519a627bcd391b0347c9bad63e1b0931b3ab..26cda8cb822d12244d37097e54edd197f9a45a01 100644 GIT binary patch literal 3947 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 L)>bN0v_StKP2Ng{ literal 24109 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 literal 0 HcmV?d00001 diff --git a/public/providers/nebius.png b/public/providers/nebius.png index 5a9586ed4508a04d9c500c92710ee9a42df40505..c4ebd3cb327118fa46569613172f23787c8d658c 100644 GIT binary patch literal 3837 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 literal 4287 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 R?l+HdSerYTVXu29{s)(I`jY?v diff --git a/public/providers/ollama-local.png b/public/providers/ollama-local.png index 8cd2cf1ed8043caf62e8b069330889c0cf0f5a3b..302b1b182cd991ad5fa562d34483c095e189c573 100644 GIT binary patch literal 5637 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 Q{Qsz-zKLFyEIbd! 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 Q{Qsz-zKLFyEIbd! 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 ToAG}7`&X!`hElCmwh8|q>%ggv literal 0 HcmV?d00001 diff --git a/public/providers/stability-ai.png b/public/providers/stability-ai.png new file mode 100644 index 0000000000000000000000000000000000000000..31cf71c7724396fde773d1f8fb98897d33e39867 GIT binary patch literal 24455 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 Th%>_900000NkvXXu0mjf+s&r6 literal 0 HcmV?d00001 diff --git a/public/providers/topaz.png b/public/providers/topaz.png new file mode 100644 index 0000000000000000000000000000000000000000..3f86008e4d05603a81c10cd06c6e1f0d8a80d652 GIT binary patch literal 1134 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1SEZ8zRdwrjKx9jP7LeL$-D$|Tv8)E(|mmy zw18|52FCVG1{RPKAeI7R1_tH@j10^`nh_+nfC($q4{yt9DiPl(ptG^qLH&8cEcw4) z3M|4F$3D;9xBTs7&AsN|tKV17+mn0n@YW6YbM`%4svK~|b@HFt3`|GvGqWf-_&CV; zGYcrFDfBI8OmAjKufHzc>vrar*mXM_8;Po9aeallL%)iQL=()d zW}m&5|6SBQ$9!sI^q#oF%2(b$@-wmyHU8w_VDPGyVqD3|{!CecLE~#C%Mvx28T}0m z3$82|oG_~(!H$WkA!xpv10{-o|M#&dQa<^pF1Ag_?WTV-GtZLce_3z*YyKgs+wL;U z;8&deo&NYM$2iY1<#0PKzg$^gkx_lg?AhKA3j%+a6@PyDdt&yWMgM{ zYfDb`1Dyl=HoWKKvy+j{J+krY!S~y@?~ThZFE3xc`kH-C>ZWwFweshmbZlmbzIuMg z-W+eeXPd%ShtAzrs(1X^w_^|AzrHi=OZi=XrX%|Vh)8TWqj^s~^B%bulRk&Bxo4i+ zt(3#>vHkYe_-&&57ruJ+>eT6_%KF~}TmPnAE?;3Qb@J)=T-|vyo>u2e`W5Fjti3SL zIBh-8^jXh!fBu)A@Z4(iUTv0+s|v(t0i3Ra=bR4KKTPXBO))f3vwQ@~>z=NDF6*2U FngE7O(NO>Z literal 0 HcmV?d00001 diff --git a/public/providers/vertex-partner.png b/public/providers/vertex-partner.png index 00ee1a40a90a400fe017f1a90cf6f3360f77d6a7..892af458a9ca8de4bfc51d661f882b3599e51d11 100644 GIT binary patch literal 8908 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�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 SF86;^Aqq08(&dt7A^!vMoz;o} literal 10060 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�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 SF86;^Aqq08(&dt7A^!vMoz;o} literal 10060 zcmc(_c|25a_&0vfnZY1?S;J5g*^(u)j9rT*St?;7ODdE#>ru8+)}lfv(PG~fW=dI; zHTznGlzogbnCIy8di`F{@B94o{P)c3%sKaRy|4Sa-q(Gf``qW;_smU=*jNNv003+! zjrA=6fRH2vuxRAckbAHh05mW^V`*^a>P>v)s(mB9u#KAhhF;J{#YdBGKcSbj(~v5c z4Dy>+dT~3wsEw)5=qdI1Oh=47gLv=Gbn{^G(|vSF*N?>Yx|3({&96gHkws39Up}NDM;0St?Xu_$S%*x2)v+; zhUheYx@#ViI2E^A*t&_J{t|34~iR%+O;-<;{MZ`gbivQXwY}@>oM*Lkz3`T@Y+Ng+dVJo$&6EOp68u4@& zj+_e+9$Ghcsf#2ReM6YsB>@5MR_!{7@biziHrkc+T~l=;)|}FJ&xm1&ux=z-I|^ZM z*I(<0bR_YQfn75Ha{wU2ayX@tbtBeX(h-s=?^#z3>kqqrBkeu*WWa6+C5oMBT}zrQ|^~j z171@?^C{->=`SeTvz+t4PaMFmm;DopI#8;RS3f9ll9OGaEh+G7ik zX9dM%$TE9)@Dqzqt3_`xpA-$JfZe z>UgitckPL0@0=dFTz)QmRcb^c{{qYNmxST~J#mFsyn`FHS~2$4gSo=XH%;_UzA!)d z94!-lUOt{&jUrI8~DVHfttB-7%@2Ok1gXBwi7z|Ptqqg@OPW#4o^U>hfBXP-EW+0_f!Q+aO1bzx8I@?EXM!lDJDN^4Q)XE)gbC7Ak@VH|O0h=7^`#Gel&CZ@os5bgBwjdI90S zk!|!NKybGT0V6l1r@}rMnaNs$tOFACg@-ItbjK%hz+0$|gEZhK2o^4`Xajcg>^v(K z^~9i^7*w$aWL`{-^Q1^>0`eTVlpq54C;<&x4ijOYFuYGHX-50V0~Y+X=s&NU3}UE;fQ7$Xb< zEN+4KXdBoR3%7cP_Ys-I0q;93AZSCls$VD|V*sZ5lmmAf-iw1sb7B4{Y9niF6E3J?CTE~|UF!a)o)@qo7Zs*+DG$9^z@H{HAc zc-7{65zV+WgQ0qE%3*z*QUYg1%q$xpjmThNA-FtFbW6~O_I~;U+i_bT$|H?RKlPMm zAtE*QwS{5VIh6z863EGCrz}6M9Jtunzo7YBwooEO?=9^~WTcgu5g0%{$+@gzGp2i2 zIoiEVIr;Pcg?_PDCAj$X}D1-{!ePx;n06SJ;z1+bwAXhLaRKjEzb z2NdT!^iZ?qfxy?(opBu}^}%^C5O`j`@};uFs?tQ~K&587}m9ty9-ObDIwiZ1yT7QVLsR1oDtlo0qLb6o9gD6j^g{LUCLuj>WJ zGdjb1&mJwqkMUv|Zp#KMX!Csl3~4SY%5Hp9=!w^UQFt`Ds8H!HrEV)Z)!1lxFumsQ>vOC}Ob5j1sVt9(~9kylfVqLk;Md zP3*(f@>k!@c^0yj@cl^dZ2w)6P>Vny9VK)t){_GeHudm!cTF>A<|YeXF~JY=rWXZf zr2^3auUf{TJvb4?advI#Fcoz;*A6Pw>#_sjQ@hrd0)SC?4bFu`QJ`q59pXwlHKYoF zRlC+^4IZ+^frLuG&NlmV)$IGxpt$wVOHZbQUML8h@>J=lL&uq*0l(Aw$4rR(Nemzj z@yhM6)AtC2o@*azb5tP%PQYkYn7zDFc~@$UMHqH0X^h{RLdP1T~VuE6y z(T9JDs@ElXBcbbcF1k=RTl7@&)^Il{Cg_k%E^fwgVqmLpPwqH)V62)PW}Y+^ooNXZ zVC9WccT0t1u^?5t(QZuTCbw(f8b#DoeenKWk3xs9P6K2vltSoSryWn_$7g7_?9|$Y z8=T;XlGTir!uVTsz-d<^UkbZC1_w^rzIsfzk)hGqO`rjFJx&;ZxI4_w{QCuK5t0dA zDqKnr3lTDgf*dfPnr>9A(hY`0lU(vfDfdVL7|$n%)aj zSx1jmBLL-<+_YOM@(JFic70TbYtu~PtQ<~cnd-&yWAHb{02V+nGVA>Bm&2^E)2-B% z$TyK>jHntWESfbsxN)C#vqf0JGEoh$V?wRLg5VC4jt6s zL78Jh z_7QK1d1~v7nLAW9r5j?waC{|8L0Rh3?67x8r``l~d#U4we|rxDQ9{HNb)5+%DPB0gu_I(_4BR z-Xl!BecsfoQ@8qN4Gi-`t(XYhge8&%`>nlh4Gou0{kHn}Dw}1o%s}3>^R)ed1qO6G z08sD3|8rkm8`Do^LXFFgom_wHnaRC*q;ww)=)?k;Z$ivv?gYc4i&{iZqB_-|tV!am zf0R;x2n(`~L}h5@S^UYJFB`%4Rr^##P3r7mWkZ+O(nSn z7<9@2SP&mWwfb-q_@yyQi48XX=URE{zvif4g$5StO0E5N^Z;nm^D_u3srrE0p!#) zjybhBa61E>WE9neIheDFH!$HDU0TX~%g6`RmtsKDMx5uRc#RjF;GhKY4JEGR=lRsN zF22W~RzI>|lv_!S6`NEH#p_%q-yiKJidU9VwVNru!;)aWA#f(m_gJ&`>;@hYgRB>eM zwGQ-ARmSU23ooFDbU8uVEDznHJLA~ZKg*(aEnP(QrXAJ?m5wpQPJ99o4K_`#|2hBplc9!Z<+ z)?`6p-^}B`bR~;F+|wD>@q8zk3k(0y{Xge_QjA}woA&&z={NVGiRytVpV6A<5q^2= zp4MFO#dl2G7EMBauSx?!PKS_{wEOIZJV%gjO!kC@Z6V=U+P zLZmKzC#wzM3tn&MH~Q?9J30fmfKxppE)Egmz_Pb8Htu;o7O>YbPKLMx^YzNHq(UWS z;Pyf&{T&7{ypIj^T-9VbA?eWZRrIEU%iB6ooh_O^avlZb&h?Q+r}!lcahs`M2n)xa zitjn@x~^4qNGr6xX6%?SFT|O6`SX>pJK*?Lk1i|!GIsAanwEvL^5SWI`bV2E-&mr0 zHPIPp7_p7ZXo59Hx*5Od0riw)j=ZMLrOY8A7okHkWmx!B@6zvXbiyeHf?yB-2UT}+ zq*g~LXUQ?8_jfjJAw2J>OMb;4!$c{37~OS`lfHdt+$brK^W?I>@+R~n-WEkN!PVDH zfzN+4jfFREC!sqT06|%aMXBRlunX}`&o z)H_WAL5%s%OJXaU$UW=^0miyR4HMLnLzZ{Go#FtafBaKQysBs_mJG-WwTd%$>~kJT z5*NEJa8w+ z(Dl6?qHPOZSDx-PUOsUT0tucEHZ%koa6%A#Sv~8${m%QU%j&3mYU;~+J&yt2UkmsB zsusu*)ud;Z*0#*{Lcd*(K8GdCRrfSAe+uQ&L6I)J-Uc0|Z`%|=W)I4(afRW1Vb93w z&7-RV)wvb4i57k2?)5pbNIAJ_4P57kWqrVAaY%U8)@oH;UPSV&wuE_a!eKNJJ6c~S zrd(LYAjpXOAX35p`B@}`UdSmD`gs4XkhwZnMBfCC@xN#2 z?lK*G=QXlkcXvKm$XHk9E2sI(cs%-0|K(2O!5EfGy=ISZ-KjT$+X=%pvDOw3-lHgh zrynX#!U1W(dDGNYEdhD5fIzol8GmO!n-1s&@bR(5`Lvz-I;;+`M8OG~MS=26p%sUa z90Vu)Ow|e*+3PoVTnr040*&)xwOiX`b>j~8(T8PTp#qi+@q1H$1J3`k_8_@`m-8SG zS`I_S0r;-OYynAsl?$DWsEPgs;h)#GM!M1hi(hPm^OZX@-$x}l`q6)Rp7huR5#jqb zr-VWxi00Ri0p8pGF^~0yg+8gmKWGd}v%lv5F5mAl1RL@!vdiUdKOy6}ZK&1VHzs$X zk_`;Ced6IQM(3=DqNHwAn1~-4!hpKQgu~X5<+yy7x#Vrv#vwEq?JLGq8tHteum%{Y z2FVXXaM@;i_UO|TrX%$Zc;{1_JC0}&Rjx9-`eri}RdlwyKRf?BxZ>^abDhF}EWkX3 z2=hBxe?(!j=&_ki@jf-VVVlwR`%ml6@*aI|Fah2!@|hdAk2AD^*EOZiSBo~N`8R!% z4|niQfcr>QrIcoPaz3)?d{uP$&jYpViLl8fXiYi~Y3n8)Qaulmmfd%5pwN7Zk~dpC4lZ>~2*t#Aa?=KH~`soIQCPQiquLd!m5n?=_~XD|2inDo^l;Tkyyy z)n^=dzgl~5H-{)$y-zSkcVEbeJc%C|X6Q1DWsrv(Qc3Xy?{G{d_+d3JPnwm@QsLyV zNzTl@&ObSXiK;?#V=vUbu6KaDqVX0DS+>Wo8kWU8WsB0Icp-X5`tgcUBBJO%`lf~5 zr$F6hc$|Lt?sE68cPyIW6O2EEUQb$)1g1@V(yGVxmTxl_O(3j*M|T|1KhM1v7(Vt| zKp1R@cy*r_Hll7rhsKUpdtT9!2sV&a2v(Wcw`VirtfaT}$EG60_nZgWa|B%r_1UKW z=!PQzXfUvG>eOH&?Cx^l5v=K>W5rIL=xu9Njld)O|0=S8tIx0h5jI8GIehw)JwXWH zaYG|myaWQy40W)5cOffLXq6mq6apNo6Lb^@Wm()n@-T}Vy zQ2L1&E8xbX@Mv(s4pG*8zQEno_PJcw-B8*$AHv89Eo3D%!@U)|v0vK(Asv?!zPKK4 zVzi`5&;3pbOvz8`a90)K2gcTCA5l8OQ2mofhz{V*`LTCu7qWXolFIPuzdoBaLVv8q?g7=}GC(;kf~ zdV!P4t#Qs$Cek(}5`gg%(&x9vp%kP?9g{m8e? ztb`X9i%zPm{S<#m56C?7u5j>gnY6Wryt+J{{ReE>F(fnRpNcl|N17Kc)QW}8q<$(} z?^E4wR0kgJ%1i~UUQV9fDa;x2CILrVF53b}3(+*lkZ*)#q&o4g5{+fy%0&j)G@jl$ zKniKfvsn-F(KkxdbUqCngS(Z2Z^4Xyd-|`*e(+!er^ydq#9`c5U*~v_F;!6PhEWPC zZIWt!2YA(7eWRl?3iK&)={v_l%-2jNy!O8rKgH4B**tHJz`Gd9^bfIvt_GT z!8cboso#F1ofADHjehA0EP$}u_pLM4);`{yQ1SH;C}*k#tc~~M>-O<~=)4a6Ag!V<)q&7he2hA&~t ztqf(1Jjk!#9`5B+SF)*dt^~OD_N=27UlZ9c8h4I%R@P*Uf)`Vl_f!4{?A}Dvm-Z0GZoR0&lIxwR0!PHl}pd%k}7yWgR zWY^p?wvW%F*+c7xbKS8mso@uCQA26kDf-K2FeTqZ+Y8apDh|qcFvz1imMo((`wzl{ z9vZf;LpP>Sji}NncT~dG{wA9Z_jS9mE&B5TCa|I`4;Gfr#7#=NpE(|Pq;0>JQ8FBO z>?srfiX?rjfBHPwJ&lDt_@qntO8_ux?r>5W{T+OdK`9nagzkiv? z({w6fN8X#hWw*V~X^X)!g8-X1Hr`P^Y?tgsV{zx}+`YbyUp2Yc*7vHMp^NesLE2md$s&Bw=yE!uZ} z-ut_FWh!0N>dj`V#+)(c;?657z4~l?%jg zgKe2RDRl>8*ig8sDywSd*Xpsx1=DD%Cp|Ot$`91jVUe9d>77_OQMn+ea*bkD*`Gy0nSI+SmMxPp{BkfXzsNPg*?nk!*&eZiG|;8#P|TWztlp!bHEOMXN}{M+vxHI z_kBYB;dF6xVtz&s@p>_-BW!V)D+$88b0AiJa-;ns{^H(Qv*Eu!$6EZ|r3Vsyz~P4^VQ31@qlXmvuZGq^ad?Z0&WltoMSv~fxhgoptV?eVuE;~vL@U>PBl}w8 zIU#s2#}6X*L6I;CJ^L~-quv(U;CLSzs@iKE8o>>&`3oCjLx;Fk@P z$=qZW0N6q6$7wKrusvBT@YNt6+MB7bI4D|~29U*mlHc%1A6JNQXWa=ij%IIAHXYyJ z>!5->I{)}OBZ*T7eygUfpK9Gv)s1Vlt(iNCws%sZ2n&LJS{Dg-I=!3&c-o`didmD( z{26w(iU#!_Vc?t_<@JjDbwadaRX6r3xSnh-+`<}w81K(4?~XKR&b2(biY=Tb>-tX{ z8AJGH{cvVoy@CUg?GDS zUaL657+~NjRlC#c;4bPriXwKcjqUFlC zOD`5%jy|bcr)86->EF-a0d6OA64U!VcI=#j45`LB>q0q?Mg0K&bz*vzV(lTX(671` z4yT{h-(ZE!52!gfSDTU6uc*lps5~QYw1oh!*Z7;Ov{FN7DAy}@;sGjOXxtwj_n8w@ zfb-fx(T2;?N=E)IrkZi;#pZwg`$g^m68F`EGq3j;1?QY&b!$1Qe87TMQ9L(11~`p= zv79^75TfKTYFp~?JW?i%@f*h%Z{Z{mqnzYz8O7(W^q1pLi#=^$$<`oEMF$K>bQ^y| z8fYpCrZcUd1YB*I6GdCa0zh|OKj2IxZ=me>R>JnWyd_O@=$NIM_bi0J$ehnJS(2tb z7Sz~q;v=c9ErVry};b!N5}S(0J5*KFnLil=C2_pHe(1IH?q*17D$B9^T!z1MTLw}A1o zz)lrPB+#`ho2)9LNxXNRd|MTh zR=*DgpD~#Z6AB=xE}r+g?)D__(WfX8+X>F$-^UK7)mtHBumMG(@A$_V>8Um8yA!hq z*9!Ik=;74(2aQ1K8hS?U5$!7sa9QG(?e>~>Z+uv??{suI@G9V;&V+De1%;*hOh(5-zNEGf{@VKwIe`qK59(~DyPF-Z3DWYFH@s~*Bi=3BDUGQmPLf&0y&Fj~H4@6hf z^}ff&_eCXqu4s`-g(Z}kAp#RsDT#jWKuw`1D=n41W@6 z_Is)<#|Xj+EnzFP3t?$*DU46E zLpTD|QgFb}vX#}NYPblyluV1TCy5tOz)9=S*H|DX^tPI~io8*bo+oOSuV!-Jr=QX= zKZtA!fd2081weX$8psJqSUf$UJ(^0^t{+`ASlYeC4P4j`Df&GgeQy6<6b{&BEm6-nFmTB?Sag2mr<Y=wvIs>;8VtRi|AgeojbE)<7QF52H;Q8 zsnBbXf8;eeX0>_B#~y@v;+DrB%Bg3e}|Gt!jYn&`SsUqSpGzDicnc3zbm5 zcWFs_;^c9%c1_xjGtI&5P>>Q^&RZS~K1ucCYM{Nj1cybK*|64BFfW9Q?Th8tpW?>g zc@5HkQDW5o;=vROcO+VsUckc);SzuAFHdX#X4C;W-R%l;;36jmuh{;xg%0ij)1m z=JLXN10{99mDJTgTz}U@)#fc1uOCJ_(Us-(g|lO2=(D3$s@5x(ubD}AXFeLzV&lr& zP8v5~_0Mq&d+B4PyPjn!sYPiC6_iv$kOo(YrON|$_ckj9PpF8Kg^Stw%=bbZirrtAAdO9dts>@UW09ti5WrK6X{54AQ^SVvZ zs`ngVo(8D~Vx&4j#Z-i&T{zrYzWs&@^8j}V8KmTu708A8l4j0_io_GR4&G6S?AT6C0 z0Ok~R<$Di(VcTZvi5#8Y!H=dD6yTQR9Dr1mRMbfNDsw0(r>lY?*K^(k8K~9y4c)tD zV*BdHC0T(`6z5i1+r=~5ru7{?X|L4fL?u4;YawG7NUkIA<1F*#{sbj=Wo+yi-!A%G z|G6#s;`H#N7Xi0pjJK;Axizs+`9DWZi+?FC87IPs3zVA zN4^9GV$+2A#m^pz`fyxExCK*qSH>2jh0Y{jkwSBwl3H`K|W- z^mDd&Pmk`}#2^5qA>1J8dE%E1cLy-`Mel*I#)EwL#VnYcfnt)B)7!@iI<(+DvjHL5 zTw(*JJ^q@lrFN$B!kIq&YVmJHgDqle==^N^uxS8(N{8^39BI6%kj$fZOt%k1Mu#vF zQ*tz<2eZ%V-QwOyG{kf=CsGnzqBWt8W6D?hU9$uDSUnkwBvN+{`QvC*BckU!6OZc2 zkp@LUsJ?~$@TT*=SFaDGMvcN90G2$quD|<&1Yt%Ec!iRtE(Hz8X~+uT9l-Uk4^bs8 z1eQLY4H&m3J;L>djsE_N!Q>*@;l&($q80IqaQ%&2xJ8Yl!H<7RVDzI;O@BY|AScf} zLfYu@njk)%Qw^rS9W9r2r98ZDIwOoy(0V30JP#pzT1<`P!fT7Pcah+i&6R}@uX^)0 z@Qy&aivIC&%|ZcFV;5^kXHP)Jo(#OE6pUuL>;RPSOfmiy zr(TD&Ws9$8BqN3;ckSMm+yOZzn~m6U$jvFVJ=F|*OY7r%BU(%g@32syVQ~aH@v%_! zXy5jAGelEYH%$AsCB!$4X9;-_92{Al`Dn?%ve zWq52#vX6;qh`_hkMhyc>sW0Z^_33tJw4DfOBt5-mdENnzp<=6k7AxfI!K!jgrW>uq z-hp`=<;hSa3~Jb{@14P8f6tD+{yO{1@1tROvO>u(n+wJWX_1aubO#w! znnM2gx>{%a`6}kVs=&7_qQ$t6$#-f!RIZJB!~)E-Vx>s@wpzrjf6R9}h$l5KYqd3J z$M*0fcU_kPhHs(*Q>vKxsE2 z!RO``s&w=5Uh|j{cnVT3xjTw-m=wuEm`#)lAYg-uoLl{DHfvAU@;UJAX?om^-R=xU zyyp|Cgze)cUNxEHCnd|*A@jb)>2a-HXibYx74eA|JVUMzDQ%Jwh4>wEDV=4=aN9dD zVO=)k=TDdglNsngQ(&5DC9Mw}7mX1{Nq$>{S5($|Xh9YhXiSd7HV+>SQPyoU!zg#R0{no;!Y{X(MmBna%bChmATFXSAAVK(3g%kI#C=(nuxMjM4RbK# zN&U2W!umS1V&%Vf$|3`Sbk1g$Byn(4rxj)q>?&#c-*F9`m9opEwbfXa9-Pc zSje99=3Ts?PyL{RJLk$uzLU;P@ua*VUF}T)BFM>V&6Wj6B?|@{#P%7reE$jxrOnAG z`9|+(o$D;moV7y{2*1OgObX=B-P- zHC|&E@#|0Tn?HR>Qau_iT|5#|GcbDpJxOF@wE=82wd=R)CM?;9p@J`2?FGN-Gued&^oQ?fmXufWRt8Nz}8{8IWO*B@GDxL=%& zH%=0DtFp@R&2RstNio7RUZ@A3OvaKMTK}4ww^NZ4BeSW@$-WGHLq13g&q!;xr?4ty z4av|En?>G05$mKFgGig;v%a~6$I>Fku>PfleGQHJ>|EQ*74aOeVSr(w>0BqwiiRjS zx^>qa>X?Op?|d2)$0)z@^W8hi4Eq3_7pU^%6?~;Ic92gun5>|f3Y5t7 zb#y-rpRUob^2u{63wz8M;k)c7Wv;Neo_T;_@9CO{xv$-u4>au?YVV=IC|Y#toUu1K z=I^}q_Un|VDv7`1+OhAHc`9}B3#$?HKD!QNdHuGCYM_nGp34HiUW=Y0sHs_;Pyc|` zVeb_$rub*C5&e6CQ|oZ%6$gw&MUOMdLd3j%3Nl+I98>jpE$;C8?5<1_mb&j!m-0|8 z!!glvPa53!`Q4l`B0~SVECy!2+Ua{<{4FVP-H!%gaL^%4HHvw5(Z|)98F=%m5Eg=bze4sw0mRNvLOgPiV;Xm)%-Xn9O*q zv6Af@Y3j9z+g`p|s9L5-M%13?SPwM^}UQPV(c4_MP|+?|7QqU3HoR3s$~~rck@<@ zyOKH{)`zEzMVsGo0eZIuYBJXqDD%mG8{#Li{T{}eza>NUgh53Qx{XpYCvx}n?DFdI zB`x*ym%vJQs#+tp_&0fqrc`-K_ix9yhY$9DwecPeUmRAOOA$ zyEw1h-=HKmgfD^4bF367|2U?Zi6)5iYL`h>_s~HPVWA+J@0K`h*nTz0CNTI>{&c7t8oMu(pbj(5AsGP?~31OM9h-a*beWhn*-PN8CEjImN-M-1;@3?6nN8xU0B>9QIg^b<3`%GteG=<$ak|? zdG9-GJwK!o_+pG0;}J1eKDoC?<#wV^2lC;>=6ZTic1;RKDoo2pPWLwMj@>{hX~3l% z>ipB67X6aH^9vMSMKF1qw14FQ1BDMnR+ft3>_K9SdNatUIuvG@#CYQm#_+kCz{`ug z%r_wI+8^+vCY&A(uq$W^IJ78(ucF>qNLsr~oQT@5P4*j5Eh<|SWcZ_?$U8=T*HL|Ah@>5Bl93(PWes;t;Fm`0%SfL-#EldXG; z%iYoTg_LxzmwPqMJp4&8E>DBIw6%KohZ1(2=BH|euNvtN^v=#py$fEYz^s1g5abxy zZ_(DCO2~FLija_X9k`TIFo(NI^-+RqfYRPY|wcw_o~Pg&LFYT1&VmmdwF8!2 z22(^`K$*M?t5`u4@oe}Z(bc!r##I>2LVtcO&11-R8io}t5|tFLx^xs#FXvGb@t2sz zyjIsvzjISwuclGJfUNhdQXQgh!T1?x2CoJxFgMfKm{pBtd%Out&HAK#tAFWkY*=Ge zY-z*!wVy`Y5}xh83A>pYz)-h_+?cKHhg>XB3nw*Ma#I4e=**m}hFwx5l=7ze`L-vI zOVrX0Tw6rFKE+oY4sX_osGi|-3w|v=g?{qzdNHiQ=wV+3VoYf0zngu3-E$(y6M48dP>#MyGw=4bZ|9EBKRQ=%!lBK6o5^plJ zyOMOc7s)~IB3;4c&}>TKC)f}@o4YgF?^2ZpcmE_#K!skt%@1i0PQ^{HPl;ByBsT@X zjn)HP1C(lYPtXb1x+*_>GFeOtjOe;hJF7CX9w$7*xw8xri;aVqS{i-g&vmIk{A zzO#F3_>GRmsNSesK4cvwP;lXMMsPyp0FC`PRW-oeL6Pbq?5bC@v4@Aoad~PUn-as!{yN=;kd6VpCXqB;HJ?G zL|UCO`t(t%hiD1HTPiNn(d3&M@zZdf7xa#8di_$qV+LNuZ2Ul z2eu6mZmyb1iy3xS^YrvD#;CyNryrc3z)s#?B}RVyWhu^Bs&!=(vqDoiNwUoseg( zD<%y9eqIzjI6*tNmYNZG4K``LbaVQB!~rBhL^y;B^ug7l@8(jbQi*L_UIn2{^%q}g z+Tv&M`WTxy@v<9Sxoz^Qk-s@M)fKKT9=J<^Umvw+o9*tLRt^@9Gq>9m4zQ#!2%^Yj@L(%|-Oxt<)G3)EvYuG=0IVSX5Bl2NI z@^xD!x6Q|80enC8Ze#sg75ZBDWb?OM%6WK~91dR(f8?4I-1$U7dFH)5-xlUWwr+F) z)_g?n_0OeGGscOcdLR^8H+1{pX97|Fg(U@YZh~HTD*m#chOPwo18A}i7AC@iZG479Ny00j4)y06D+PV}c5ZjG#s`?GTnTuUem~}GLA{ry2 z12db>GZ1v%PxA-P2pbNbwuk~W#n5w_KEhTKPxFEqR zkkcVYV#(rvwb~``6DMzBXD$jHGV-|pV zjbfrcv!GzYs>#_DWlkHgl8|HL>iU}#!HHN|Hc(X52DP%Knk5i2O}-Ggpi8KNP0tOO zoK-ZogWpb!zRot2HM2OeLpz2Y#U2Y^Yd~Gv?d*L9d}o-(Qgh>P(XM_sRTNP>3p+6F zYz|)+T#yQ|deYhTru0XlVq52Vm_OK-j8*;2^@bcXZ{3@Vby&JEe6(ES z;~%`JdBKZiRc-0g7c|aqYhWfl=_VJzXYP&>*3k1bt7=LACKKsw!SCAe2klUPOrD9) zqowBTq$)~b+963X7X^$0B<#Dn!K-?n4YK^M_KZSHvCKZp=(O(rclj<1Nz|2L%6xBS zLr5mv9mB$e>$w$WRs&ttHUCbnV5zj|J+_KMVjxO{?~!6*_csyfLjLD&ben?5>#C^R zm<#KP-EFTA*moASC6c1D&1oDSw30W-^;evw+ zr1AF+Se%n-H;LUp>f}+flVP=?Tjh?Ux{;oOw38Mk(bXk5v6BHiU!(T=aMBkGmpa4~ zCUFN_<1tWayk=1*zAsxK!=F&PTNvaco%=+TvAFE`vl#S}wO3c3_$`y2(BZZf%Qr^7 zemA-xi0A2P>5i=gKK1ucirMcAEh5aagytF##FOz><^AlGJ2j_E6Bc(H256~2fF{4_ywiHA&LW5#mJtXO4Q%) OYjqVJ<&yiBq5lQ6wqpqZ literal 41730 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 z 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 case "opencode": return ; + case "cowork": + return ( + + ); case "droid": return ; case "openclaw": diff --git a/src/app/(dashboard)/dashboard/cli-tools/components/CoworkToolCard.js b/src/app/(dashboard)/dashboard/cli-tools/components/CoworkToolCard.js new file mode 100644 index 00000000..833cf817 --- /dev/null +++ b/src/app/(dashboard)/dashboard/cli-tools/components/CoworkToolCard.js @@ -0,0 +1,401 @@ +"use client"; + +import { useState, useEffect, useMemo } from "react"; +import { Card, Button, ModelSelectModal, ManualConfigModal } from "@/shared/components"; +import Image from "next/image"; + +const ENDPOINT = "/api/cli-tools/cowork-settings"; + +const isLocalhostUrl = (url) => /localhost|127\.0\.0\.1|0\.0\.0\.0/i.test(url || ""); + +const stripV1 = (url) => (url || "").replace(/\/v1\/?$/, ""); +const ensureV1 = (url) => { + const trimmed = (url || "").replace(/\/+$/, ""); + if (!trimmed) return ""; + return /\/v1$/.test(trimmed) ? trimmed : `${trimmed}/v1`; +}; + +export default function CoworkToolCard({ + tool, + isExpanded, + onToggle, + baseUrl, + apiKeys, + activeProviders, + hasActiveProviders, + cloudEnabled, + cloudUrl, + tunnelEnabled, + tunnelPublicUrl, + tailscaleEnabled, + tailscaleUrl, + initialStatus, +}) { + const [status, setStatus] = useState(initialStatus || null); + const [checking, setChecking] = useState(false); + const [applying, setApplying] = useState(false); + const [restoring, setRestoring] = useState(false); + const [message, setMessage] = useState(null); + const [selectedApiKey, setSelectedApiKey] = useState(""); + const [selectedModels, setSelectedModels] = useState([]); + const [modalOpen, setModalOpen] = useState(false); + const [modelAliases, setModelAliases] = useState({}); + const [showManualConfigModal, setShowManualConfigModal] = useState(false); + const [endpointMode, setEndpointMode] = useState("custom"); + const [customBaseUrl, setCustomBaseUrl] = useState(""); + + const endpointOptions = useMemo(() => { + const opts = []; + if (tunnelEnabled && tunnelPublicUrl) { + opts.push({ value: "tunnel", label: `Tunnel - ${tunnelPublicUrl}`, url: ensureV1(tunnelPublicUrl) }); + } + if (tailscaleEnabled && tailscaleUrl) { + opts.push({ value: "tailscale", label: `Tailscale - ${tailscaleUrl}`, url: ensureV1(tailscaleUrl) }); + } + if (cloudEnabled && cloudUrl) { + opts.push({ value: "cloud", label: `Cloud - ${cloudUrl}`, url: ensureV1(cloudUrl) }); + } + opts.push({ value: "custom", label: "Custom URL (VPS / public host)", url: "" }); + return opts; + }, [tunnelEnabled, tunnelPublicUrl, tailscaleEnabled, tailscaleUrl, cloudEnabled, cloudUrl]); + + useEffect(() => { + if (apiKeys?.length > 0 && !selectedApiKey) { + setSelectedApiKey(apiKeys[0].key); + } + }, [apiKeys, selectedApiKey]); + + useEffect(() => { + if (initialStatus) setStatus(initialStatus); + }, [initialStatus]); + + useEffect(() => { + if (isExpanded && !status) { + checkStatus(); + fetchModelAliases(); + } + if (isExpanded) fetchModelAliases(); + }, [isExpanded]); + + useEffect(() => { + if (status?.cowork?.models?.length) { + setSelectedModels(status.cowork.models); + } + if (status?.cowork?.baseUrl && !customBaseUrl) { + setCustomBaseUrl(stripV1(status.cowork.baseUrl)); + setEndpointMode("custom"); + } + }, [status]); + + // Auto-pick first available preset when expand if user has not set anything + useEffect(() => { + if (!customBaseUrl && endpointOptions[0]?.url) { + setEndpointMode(endpointOptions[0].value); + setCustomBaseUrl(stripV1(endpointOptions[0].url)); + } + }, [endpointOptions]); + + const fetchModelAliases = async () => { + try { + const res = await fetch("/api/models/alias"); + const data = await res.json(); + if (res.ok) setModelAliases(data.aliases || {}); + } catch (error) { + console.log("Error fetching model aliases:", error); + } + }; + + const checkStatus = async () => { + setChecking(true); + try { + const res = await fetch(ENDPOINT); + const data = await res.json(); + setStatus(data); + } catch (error) { + setStatus({ installed: false, error: error.message }); + } finally { + setChecking(false); + } + }; + + const getEffectiveBaseUrl = () => ensureV1(customBaseUrl); + + const getConfigStatus = () => { + if (!status?.installed) return null; + const url = status?.cowork?.baseUrl; + if (!url) return "not_configured"; + if (isLocalhostUrl(url)) return "invalid"; + return status.has9Router ? "configured" : "other"; + }; + + const configStatus = getConfigStatus(); + const hasCustomSelectedApiKey = selectedApiKey && !apiKeys.some((key) => key.key === selectedApiKey); + + const handleEndpointModeChange = (value) => { + setEndpointMode(value); + const opt = endpointOptions.find((o) => o.value === value); + if (opt?.url) { + setCustomBaseUrl(stripV1(opt.url)); + } else { + setCustomBaseUrl(""); + } + }; + + const handleApply = async () => { + setMessage(null); + const effectiveUrl = getEffectiveBaseUrl(); + + if (isLocalhostUrl(effectiveUrl)) { + setMessage({ type: "error", text: "Localhost is not allowed. Enable Tunnel/Tailscale or use VPS." }); + return; + } + if (selectedModels.length === 0) { + setMessage({ type: "error", text: "Please select at least one model" }); + return; + } + + setApplying(true); + try { + const keyToUse = selectedApiKey?.trim() + || (apiKeys?.length > 0 ? apiKeys[0].key : null) + || (!cloudEnabled ? "sk_9router" : null); + + const res = await fetch(ENDPOINT, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + baseUrl: effectiveUrl, + apiKey: keyToUse, + models: selectedModels, + }), + }); + const data = await res.json(); + if (res.ok) { + setMessage({ type: "success", text: "Settings applied. Quit & reopen Claude Desktop to load." }); + checkStatus(); + } else { + setMessage({ type: "error", text: data.error || "Failed to apply settings" }); + } + } catch (error) { + setMessage({ type: "error", text: error.message }); + } finally { + setApplying(false); + } + }; + + const handleReset = async () => { + setRestoring(true); + setMessage(null); + try { + const res = await fetch(ENDPOINT, { method: "DELETE" }); + const data = await res.json(); + if (res.ok) { + setMessage({ type: "success", text: "Settings reset successfully" }); + setSelectedModels([]); + checkStatus(); + } else { + setMessage({ type: "error", text: data.error || "Failed to reset" }); + } + } catch (error) { + setMessage({ type: "error", text: error.message }); + } finally { + setRestoring(false); + } + }; + + const getManualConfigs = () => { + const keyToUse = (selectedApiKey && selectedApiKey.trim()) + ? selectedApiKey + : (!cloudEnabled ? "sk_9router" : ""); + + const modelsToShow = selectedModels.length > 0 ? selectedModels : ["provider/model-id"]; + const cfg = { + inferenceProvider: "gateway", + inferenceGatewayBaseUrl: getEffectiveBaseUrl() || "https://your-public-host/v1", + inferenceGatewayApiKey: keyToUse, + inferenceModels: modelsToShow.map((name) => ({ name })), + }; + + return [{ + filename: "~/Library/Application Support/Claude-3p/configLibrary/.json", + content: JSON.stringify(cfg, null, 2), + }]; + }; + + return ( + +
+
+
+ {tool.name} { e.target.style.display = "none"; }} /> +
+
+
+

{tool.name}

+ {configStatus === "configured" && Connected} + {configStatus === "not_configured" && Not configured} + {configStatus === "invalid" && Localhost (invalid)} + {configStatus === "other" && Other} +
+

{tool.description}

+
+
+ expand_more +
+ + {isExpanded && ( +
+
+ info + Claude Cowork runs in a sandboxed VM and cannot reach localhost. Use Tunnel, Tailscale, or VPS public URL. +
+ + {checking && ( +
+ progress_activity + Checking Claude Cowork... +
+ )} + + {!checking && status && !status.installed && ( +
+
+ warning +
+

Claude Desktop (Cowork mode) not detected

+

Open Claude Desktop → Help → Troubleshooting → Enable Developer mode → Configure third-party inference, then return here.

+
+
+
+ +
+
+ )} + + {!checking && status?.installed && ( + <> +
+ {status?.cowork?.baseUrl && ( +
+ Current + arrow_forward + + {status.cowork.baseUrl} + +
+ )} + +
+ Endpoint Mode + arrow_forward + +
+ +
+ Base URL + arrow_forward + setCustomBaseUrl(stripV1(e.target.value))} + placeholder="https://your-host.com/v1" + className="w-full min-w-0 px-2 py-2 bg-surface rounded border border-border text-xs focus:outline-none focus:ring-1 focus:ring-primary/50 sm:py-1.5" + /> +
+ +
+ API Key + arrow_forward + {apiKeys.length > 0 || selectedApiKey ? ( + + ) : ( + + {cloudEnabled ? "No API keys - Create one in Keys page" : "sk_9router (default)"} + + )} +
+ +
+ Models + arrow_forward +
+
+ {selectedModels.length === 0 ? ( + No models selected + ) : ( + selectedModels.map((m) => ( + + {m} + + + )) + )} +
+ +
+
+
+ + {message && ( +
+ {message.type === "success" ? "check_circle" : "error"} + {message.text} +
+ )} + +
+ + + +
+ + )} +
+ )} + + setModalOpen(false)} + onSelect={(model) => { + if (!selectedModels.includes(model.value)) { + setSelectedModels([...selectedModels, model.value]); + } + setModalOpen(false); + }} + selectedModel={null} + activeProviders={activeProviders} + modelAliases={modelAliases} + title="Add Model for Claude Cowork" + /> + + setShowManualConfigModal(false)} + title="Claude Cowork - Manual Configuration" + configs={getManualConfigs()} + /> +
+ ); +} diff --git a/src/app/(dashboard)/dashboard/cli-tools/components/index.js b/src/app/(dashboard)/dashboard/cli-tools/components/index.js index 4500800d..06b45ccc 100644 --- a/src/app/(dashboard)/dashboard/cli-tools/components/index.js +++ b/src/app/(dashboard)/dashboard/cli-tools/components/index.js @@ -6,6 +6,7 @@ export { default as HermesToolCard } from "./HermesToolCard"; export { default as DefaultToolCard } from "./DefaultToolCard"; export { default as AntigravityToolCard } from "./AntigravityToolCard"; export { default as OpenCodeToolCard } from "./OpenCodeToolCard"; +export { default as CoworkToolCard } from "./CoworkToolCard"; export { default as CopilotToolCard } from "./CopilotToolCard"; export { default as MitmServerCard } from "./MitmServerCard"; export { default as MitmToolCard } from "./MitmToolCard"; diff --git a/src/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page.js b/src/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page.js index cded5093..36605632 100644 --- a/src/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page.js +++ b/src/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page.js @@ -12,6 +12,7 @@ import ConnectionsCard from "@/app/(dashboard)/dashboard/providers/components/Co import ModelsCard from "@/app/(dashboard)/dashboard/providers/components/ModelsCard"; import { TTS_PROVIDER_CONFIG } from "@/shared/constants/ttsProviders"; import { getTtsVoicesForModel } from "open-sse/config/ttsModels.js"; +import { GOOGLE_TTS_LANGUAGES } from "open-sse/config/googleTtsLanguages.js"; // Shared row layout — defined outside components to avoid re-mount on re-render function Row({ label, children }) { @@ -92,13 +93,6 @@ const KIND_EXAMPLE_CONFIG = { extraBody: { prompt: "Describe this image in detail" }, defaultResponse: `{\n "text": "A cat sitting on a windowsill...",\n "model": "..."\n}`, }, - stt: { - inputLabel: "Audio URL", - inputPlaceholder: "https://example.com/audio.mp3", - defaultInput: "", - bodyKey: "url", - defaultResponse: `{\n "text": "Hello world...",\n "model": "..."\n}`, - }, video: { inputLabel: "Prompt", inputPlaceholder: "A serene lake at sunset", @@ -394,6 +388,8 @@ function TtsExampleCard({ providerId }) { const [modalSearch, setModalSearch] = useState(""); const [modalError, setModalError] = useState(""); const [byLang, setByLang] = useState({}); + // Language hint (e.g. Gemini): controls the spoken language without affecting voice selection + const [languageHint, setLanguageHint] = useState(""); useEffect(() => { setLocalEndpoint(window.location.origin); @@ -514,10 +510,15 @@ function TtsExampleCard({ providerId }) { return ""; })(); + const ttsBody = (() => { + const b = { model: modelFull, input }; + if (config.hasLanguageHint && languageHint) b.language = languageHint; + return b; + })(); const curlSnippet = `curl -X POST ${endpoint}/v1/audio/speech${responseFormat === "json" ? "?response_format=json" : ""} \\ -H "Content-Type: application/json" \\ -H "Authorization: Bearer ${apiKey || "YOUR_KEY"}" \\ - -d '{"model": "${modelFull}", "input": "${input}"}' \\ + -d '${JSON.stringify(ttsBody)}' \\ ${responseFormat === "json" ? "" : "--output speech.mp3"}`; const handleRun = async () => { @@ -534,7 +535,7 @@ function TtsExampleCard({ providerId }) { const res = await fetch(url, { method: "POST", headers, - body: JSON.stringify({ model: modelFull, input: input.trim() }), + body: JSON.stringify({ ...ttsBody, input: input.trim() }), }); setLatency(Date.now() - start); if (!res.ok) { @@ -608,6 +609,22 @@ function TtsExampleCard({ providerId }) { )} + {/* Language hint dropdown (Gemini) — sends body.language to guide pronunciation */} + {config.hasLanguageHint && ( + + + + )} + {/* Language row + Browse button (edge-tts, local-device, elevenlabs) */} {config.hasBrowseButton && ( @@ -886,7 +903,7 @@ function GenericExampleCard({ providerId, kind }) { // Get models for this kind (e.g., type="image") const kindModels = getModelsByProviderId(providerId).filter((m) => m.type === kind); // Kinds that need a model identifier in the request (image/video/music) - const KIND_NEEDS_MODEL = new Set(["image", "video", "music", "stt", "imageToText"]); + const KIND_NEEDS_MODEL = new Set(["image", "video", "music", "imageToText"]); const needsModel = KIND_NEEDS_MODEL.has(kind); const allowManualModel = needsModel && kindModels.length === 0; const [selectedModel, setSelectedModel] = useState(kindModels[0]?.id ?? ""); @@ -1344,6 +1361,288 @@ function GenericExampleCard({ providerId, kind }) { ); } +// ─── STT Example Card ──────────────────────────────────────────────────────── +function SttExampleCard({ providerId }) { + const providerAlias = getProviderAlias(providerId); + const builtinSttModels = getModelsByProviderId(providerId).filter((m) => m.type === "stt"); + const [customSttModels, setCustomSttModels] = useState([]); + const sttModels = [...builtinSttModels, ...customSttModels]; + + const [selectedModel, setSelectedModel] = useState(builtinSttModels[0]?.id ?? ""); + const selectedModelObj = sttModels.find((m) => m.id === selectedModel); + const allowedParams = Array.isArray(selectedModelObj?.params) ? selectedModelObj.params : []; + + const [audioFile, setAudioFile] = useState(null); + const [language, setLanguage] = useState(""); + const [prompt, setPrompt] = useState(""); + const [responseFormat, setResponseFormat] = useState("json"); + const [temperature, setTemperature] = useState(""); + const [apiKey, setApiKey] = useState(""); + const [useTunnel, setUseTunnel] = useState(false); + const [localEndpoint, setLocalEndpoint] = useState(""); + const [tunnelEndpoint, setTunnelEndpoint] = useState(""); + const [result, setResult] = useState(null); + const [latency, setLatency] = useState(null); + const [running, setRunning] = useState(false); + const [error, setError] = useState(""); + const { copied: copiedCurl, copy: copyCurl } = useCopyToClipboard(); + const { copied: copiedRes, copy: copyRes } = useCopyToClipboard(); + + useEffect(() => { + setLocalEndpoint(window.location.origin); + fetch("/api/keys") + .then((r) => r.json()) + .then((d) => { setApiKey((d.keys || []).find((k) => k.isActive !== false)?.key || ""); }) + .catch(() => {}); + fetch("/api/tunnel/status") + .then((r) => r.json()) + .then((d) => { if (d.publicUrl) setTunnelEndpoint(d.publicUrl); }) + .catch(() => {}); + const loadCustom = () => { + fetch("/api/models/custom", { cache: "no-store" }) + .then((r) => r.json()) + .then((d) => { + const list = (d.models || []).filter((m) => m.type === "stt" && m.providerAlias === providerAlias); + setCustomSttModels(list); + }) + .catch(() => {}); + }; + loadCustom(); + window.addEventListener("focus", loadCustom); + window.addEventListener("customModelChanged", loadCustom); + return () => { + window.removeEventListener("focus", loadCustom); + window.removeEventListener("customModelChanged", loadCustom); + }; + }, [providerAlias]); + + const endpoint = useTunnel ? tunnelEndpoint : localEndpoint; + const modelFull = selectedModel ? `${providerAlias}/${selectedModel}` : ""; + + const curlSnippet = `curl -X POST ${endpoint}/v1/audio/transcriptions \\ + -H "Authorization: Bearer ${apiKey || "YOUR_KEY"}" \\ + -F "file=@${audioFile?.name || "audio.mp3"}" \\ + -F "model=${modelFull}"${allowedParams.includes("language") && language ? ` \\\n -F "language=${language}"` : ""}${allowedParams.includes("response_format") ? ` \\\n -F "response_format=${responseFormat}"` : ""}${allowedParams.includes("temperature") && temperature ? ` \\\n -F "temperature=${temperature}"` : ""}${allowedParams.includes("prompt") && prompt ? ` \\\n -F "prompt=${prompt}"` : ""}`; + + const handleRun = async () => { + if (!audioFile || !modelFull) return; + setRunning(true); + setError(""); + setResult(null); + const start = Date.now(); + try { + const fd = new FormData(); + fd.append("file", audioFile); + fd.append("model", modelFull); + if (allowedParams.includes("language") && language) fd.append("language", language); + if (allowedParams.includes("response_format")) fd.append("response_format", responseFormat); + if (allowedParams.includes("temperature") && temperature) fd.append("temperature", temperature); + if (allowedParams.includes("prompt") && prompt) fd.append("prompt", prompt); + + const headers = {}; + if (apiKey) headers["Authorization"] = `Bearer ${apiKey}`; + const res = await fetch("/api/v1/audio/transcriptions", { method: "POST", headers, body: fd }); + setLatency(Date.now() - start); + const ct = res.headers.get("content-type") || ""; + const data = ct.includes("application/json") ? await res.json() : await res.text(); + if (!res.ok) { + setError(data?.error?.message || data?.error || data || `HTTP ${res.status}`); + return; + } + setResult(data); + } catch (e) { + setError(e.message || "Network error"); + } finally { + setRunning(false); + } + }; + + const resultStr = typeof result === "string" ? result : (result ? JSON.stringify(result, null, 2) : `{\n "text": "Hello world..."\n}`); + + return ( + +

Example

+
+ {/* Model */} + {sttModels.length > 0 ? ( + + + + ) : ( + + setSelectedModel(e.target.value)} + placeholder="Enter model id" + className="w-full px-3 py-1.5 text-sm border border-border rounded-lg bg-background focus:outline-none focus:border-primary font-mono" + /> + + )} + + {/* Endpoint */} + +
+ + {endpoint}/v1/audio/transcriptions + + {tunnelEndpoint && ( + + )} +
+
+ + {/* API Key */} + + + {apiKey ? `${apiKey.slice(0, 8)}${"\u2022".repeat(Math.min(20, apiKey.length - 8))}` : No key configured} + + + + {/* Audio file */} + +
+ setAudioFile(e.target.files?.[0] || null)} + className="w-full text-xs text-text-muted file:mr-2 file:py-1 file:px-2.5 file:rounded-lg file:border file:border-border file:bg-background file:text-text-main hover:file:bg-sidebar file:cursor-pointer" + /> + {audioFile && ( + + {audioFile.name} · {(audioFile.size / 1024).toFixed(1)} KB + + )} +
+
+ + {/* Language (if model supports) */} + {allowedParams.includes("language") && ( + + setLanguage(e.target.value)} + placeholder="e.g. en, vi, ja (auto-detect if empty)" + className="w-full px-3 py-1.5 text-sm border border-border rounded-lg bg-background focus:outline-none focus:border-primary font-mono" + /> + + )} + + {/* Prompt (if model supports) */} + {allowedParams.includes("prompt") && ( + + setPrompt(e.target.value)} + placeholder="optional context to improve accuracy" + className="w-full px-3 py-1.5 text-sm border border-border rounded-lg bg-background focus:outline-none focus:border-primary" + /> + + )} + + {/* Temperature (if model supports) */} + {allowedParams.includes("temperature") && ( + + setTemperature(e.target.value)} + placeholder="0 - 1 (default 0)" + className="w-full px-3 py-1.5 text-sm border border-border rounded-lg bg-background focus:outline-none focus:border-primary" + /> + + )} + + {/* Response format (if model supports) */} + {allowedParams.includes("response_format") && ( + + + + )} + + {/* Curl + Run */} +
+
+ Request +
+ + +
+
+
{curlSnippet}
+
+ + {error &&

{error}

} + + {/* Response */} +
+
+ + Response {result && latency && ⚡ {latency}ms} + + {result && ( + + )} +
+
+            {resultStr}
+          
+
+
+
+ ); +} + // MediaProviderDetailPage export default function MediaProviderDetailPage() { const { kind, id } = useParams(); @@ -1502,11 +1801,12 @@ export default function MediaProviderDetailPage() { )} {/* Provider Info — config-driven, supports searchConfig, fetchConfig, ttsConfig, embeddingConfig, searchViaChat */} - {!isCustom && (provider.searchConfig || provider.fetchConfig || provider.ttsConfig || provider.embeddingConfig || provider.searchViaChat) && ( + {!isCustom && (provider.searchConfig || provider.fetchConfig || provider.ttsConfig || provider.sttConfig || provider.embeddingConfig || provider.searchViaChat) && ( )} {kind === "tts" && } + {kind === "stt" && !isCustom && } {!isCustom && KIND_EXAMPLE_CONFIG[kind] && } {isCustom && ( diff --git a/src/app/(dashboard)/dashboard/providers/[id]/AddCustomModelModal.js b/src/app/(dashboard)/dashboard/providers/[id]/AddCustomModelModal.js index 6e8ca2f4..d0bf1659 100644 --- a/src/app/(dashboard)/dashboard/providers/[id]/AddCustomModelModal.js +++ b/src/app/(dashboard)/dashboard/providers/[id]/AddCustomModelModal.js @@ -15,15 +15,22 @@ export default function AddCustomModelModal({ isOpen, providerAlias, providerDis if (isOpen) { setModelId(""); setTestStatus(null); setTestError(""); } }, [isOpen]); + // Strip provider's own alias prefix (e.g. "cc/model" -> "model" for cc provider) + const stripAlias = (id) => { + const prefix = `${providerAlias}/`; + return id.startsWith(prefix) ? id.slice(prefix.length) : id; + }; + const handleTest = async () => { - if (!modelId.trim()) return; + const cleanId = stripAlias(modelId.trim()); + if (!cleanId) return; setTestStatus("testing"); setTestError(""); try { const res = await fetch("/api/models/test", { method: "POST", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ model: `${providerAlias}/${modelId.trim()}` }), + body: JSON.stringify({ model: `${providerAlias}/${cleanId}` }), }); const data = await res.json(); setTestStatus(data.ok ? "ok" : "error"); @@ -35,10 +42,11 @@ export default function AddCustomModelModal({ isOpen, providerAlias, providerDis }; const handleSave = async () => { - if (!modelId.trim() || saving) return; + const cleanId = stripAlias(modelId.trim()); + if (!cleanId || saving) return; setSaving(true); try { - await onSave(modelId.trim()); + await onSave(cleanId); } finally { setSaving(false); } @@ -74,7 +82,7 @@ export default function AddCustomModelModal({ isOpen, providerAlias, providerDis

- Sent to provider as: {modelId.trim() || "model-id"} + Sent to provider as: {stripAlias(modelId.trim()) || "model-id"}

diff --git a/src/app/(dashboard)/dashboard/providers/[id]/ModelRow.js b/src/app/(dashboard)/dashboard/providers/[id]/ModelRow.js index 25d62c5f..207fe012 100644 --- a/src/app/(dashboard)/dashboard/providers/[id]/ModelRow.js +++ b/src/app/(dashboard)/dashboard/providers/[id]/ModelRow.js @@ -1,6 +1,6 @@ import PropTypes from "prop-types"; -export default function ModelRow({ model, fullModel, alias, copied, onCopy, testStatus, isCustom, isFree, onDeleteAlias, onTest, isTesting }) { +export default function ModelRow({ model, fullModel, alias, copied, onCopy, testStatus, isCustom, isFree, onDeleteAlias, onTest, isTesting, onDisable }) { const borderColor = testStatus === "ok" ? "border-green-500/40" : testStatus === "error" @@ -55,7 +55,7 @@ export default function ModelRow({ model, fullModel, alias, copied, onCopy, test {copied === `model-${model.id}` ? "Copied!" : "Copy"} - {isCustom && ( + {isCustom ? ( - )} + ) : onDisable ? ( + + ) : null} ); @@ -83,4 +91,5 @@ ModelRow.propTypes = { onDeleteAlias: PropTypes.func, onTest: PropTypes.func, isTesting: PropTypes.bool, + onDisable: PropTypes.func, }; diff --git a/src/app/(dashboard)/dashboard/providers/[id]/page.js b/src/app/(dashboard)/dashboard/providers/[id]/page.js index f74cf1e0..ad6f884a 100644 --- a/src/app/(dashboard)/dashboard/providers/[id]/page.js +++ b/src/app/(dashboard)/dashboard/providers/[id]/page.js @@ -46,6 +46,7 @@ export default function ProviderDetailPage() { const [thinkingMode, setThinkingMode] = useState("auto"); const [suggestedModels, setSuggestedModels] = useState([]); const [kiloFreeModels, setKiloFreeModels] = useState([]); + const [disabledModelIds, setDisabledModelIds] = useState([]); const { copied, copy } = useCopyToClipboard(); const providerInfo = providerNode @@ -74,6 +75,62 @@ export default function ProviderDetailPage() { ? (providerNode?.prefix || providerId) : providerAlias; + const fetchDisabledModels = useCallback(async () => { + try { + const res = await fetch(`/api/models/disabled?providerAlias=${encodeURIComponent(providerStorageAlias)}`, { cache: "no-store" }); + const data = await res.json(); + if (res.ok) setDisabledModelIds(data.ids || []); + } catch (error) { + console.log("Error fetching disabled models:", error); + } + }, [providerStorageAlias]); + + const handleDisableModel = async (modelId) => { + try { + const res = await fetch("/api/models/disabled", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ providerAlias: providerStorageAlias, ids: [modelId] }), + }); + if (res.ok) await fetchDisabledModels(); + } catch (error) { + console.log("Error disabling model:", error); + } + }; + + const handleEnableModel = async (modelId) => { + try { + const res = await fetch(`/api/models/disabled?providerAlias=${encodeURIComponent(providerStorageAlias)}&id=${encodeURIComponent(modelId)}`, { method: "DELETE" }); + if (res.ok) await fetchDisabledModels(); + } catch (error) { + console.log("Error enabling model:", error); + } + }; + + const handleDisableAll = async (ids) => { + if (!ids.length) return; + if (!confirm(`Disable all ${ids.length} model(s)?`)) return; + try { + const res = await fetch("/api/models/disabled", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ providerAlias: providerStorageAlias, ids }), + }); + if (res.ok) await fetchDisabledModels(); + } catch (error) { + console.log("Error disabling all models:", error); + } + }; + + const handleEnableAll = async () => { + try { + const res = await fetch(`/api/models/disabled?providerAlias=${encodeURIComponent(providerStorageAlias)}`, { method: "DELETE" }); + if (res.ok) await fetchDisabledModels(); + } catch (error) { + console.log("Error enabling all models:", error); + } + }; + // Define callbacks BEFORE the useEffect that uses them const fetchAliases = useCallback(async () => { try { @@ -237,7 +294,8 @@ export default function ProviderDetailPage() { useEffect(() => { fetchConnections(); fetchAliases(); - }, [fetchConnections, fetchAliases]); + fetchDisabledModels(); + }, [fetchConnections, fetchAliases, fetchDisabledModels]); // Fetch suggested models from provider's public API (if configured) useEffect(() => { @@ -587,10 +645,13 @@ export default function ProviderDetailPage() { } // Combine hardcoded models with Kilo free models (deduplicated) // Exclude non-llm models (embedding, tts, etc.) — they have dedicated pages under media-providers - const displayModels = [ + const allModels = [ ...models, ...kiloFreeModels.filter((fm) => !models.some((m) => m.id === fm.id)), ].filter((m) => !m.type || m.type === "llm"); + const disabledSet = new Set(disabledModelIds); + const displayModels = allModels.filter((m) => !disabledSet.has(m.id)); + const disabledDisplayModels = allModels.filter((m) => disabledSet.has(m.id)); // Custom models added by user (stored as aliases: modelId → providerAlias/modelId) const customModels = Object.entries(modelAliases) .filter(([alias, fullModel]) => { @@ -610,6 +671,25 @@ export default function ProviderDetailPage() { return (
+ {/* Custom models first */} + {customModels.map((model) => ( + {}} + onDeleteAlias={() => handleDeleteAlias(model.alias)} + testStatus={modelTestResults[model.id]} + onTest={connections.length > 0 || isFreeNoAuth ? () => handleTestModel(model.id) : undefined} + isTesting={testingModelId === model.id} + isCustom + isFree={false} + /> + ))} + {displayModels.map((model) => { const fullModel = `${providerStorageAlias}/${model.id}`; const oldFormatModel = `${providerId}/${model.id}`; @@ -630,33 +710,15 @@ export default function ProviderDetailPage() { onTest={connections.length > 0 || isFreeNoAuth ? () => handleTestModel(model.id) : undefined} isTesting={testingModelId === model.id} isFree={model.isFree} + onDisable={() => handleDisableModel(model.id)} /> ); })} - {/* Custom models inline */} - {customModels.map((model) => ( - {}} - onDeleteAlias={() => handleDeleteAlias(model.alias)} - testStatus={modelTestResults[model.id]} - onTest={connections.length > 0 || isFreeNoAuth ? () => handleTestModel(model.id) : undefined} - isTesting={testingModelId === model.id} - isCustom - isFree={false} - /> - ))} - {/* Add model button — inline, same style as model chips */}
); })()} + + {/* Disabled models — restorable */} + {disabledDisplayModels.length > 0 && ( +
+

Disabled models ({disabledDisplayModels.length}):

+
+ {disabledDisplayModels.map((m) => ( + + ))} +
+
+ )} ); }; @@ -969,6 +1051,27 @@ export default function ProviderDetailPage() {

{"Available Models"}

+ {!isCompatible && (() => { + const allIds = [ + ...models, + ...kiloFreeModels.filter((fm) => !models.some((m) => m.id === fm.id)), + ].filter((m) => !m.type || m.type === "llm").map((m) => m.id); + const activeIds = allIds.filter((id) => !disabledModelIds.includes(id)); + return ( +
+ {disabledModelIds.length > 0 && ( + + )} + {activeIds.length > 0 && ( + + )} +
+ ); + })()} {!!modelsTestError && (

{modelsTestError}

diff --git a/src/app/(dashboard)/dashboard/providers/components/ModelsCard.js b/src/app/(dashboard)/dashboard/providers/components/ModelsCard.js index 14f4f28f..f55d001f 100644 --- a/src/app/(dashboard)/dashboard/providers/components/ModelsCard.js +++ b/src/app/(dashboard)/dashboard/providers/components/ModelsCard.js @@ -165,7 +165,10 @@ export default function ModelsCard({ providerId, kindFilter, providerAliasOverri headers: { "Content-Type": "application/json" }, body: JSON.stringify({ providerAlias, id: modelId, type: effectiveType }), }); - if (res.ok) await fetchData(); + if (res.ok) { + await fetchData(); + window.dispatchEvent(new CustomEvent("customModelChanged")); + } } catch (e) { console.log("add custom model error:", e); } }; @@ -173,7 +176,10 @@ export default function ModelsCard({ providerId, kindFilter, providerAliasOverri try { const params = new URLSearchParams({ providerAlias, id: modelId, type: effectiveType }); const res = await fetch(`/api/models/custom?${params}`, { method: "DELETE" }); - if (res.ok) await fetchData(); + if (res.ok) { + await fetchData(); + window.dispatchEvent(new CustomEvent("customModelChanged")); + } } catch (e) { console.log("delete custom model error:", e); } }; diff --git a/src/app/(dashboard)/dashboard/providers/page.js b/src/app/(dashboard)/dashboard/providers/page.js index 70ef4f98..0940cb91 100644 --- a/src/app/(dashboard)/dashboard/providers/page.js +++ b/src/app/(dashboard)/dashboard/providers/page.js @@ -24,6 +24,7 @@ import { import Link from "next/link"; import { getErrorCode, getRelativeTime } from "@/shared/utils"; import { useNotificationStore } from "@/store/notificationStore"; +import { useHeaderSearchStore } from "@/store/headerSearchStore"; import ModelAvailabilityBadge from "./components/ModelAvailabilityBadge"; function getStatusDisplay(connected, error, errorCode) { @@ -103,6 +104,18 @@ export default function ProvidersPage() { const [testingMode, setTestingMode] = useState(null); const [testResults, setTestResults] = useState(null); const notify = useNotificationStore(); + const searchQuery = useHeaderSearchStore((s) => s.query); + const registerSearch = useHeaderSearchStore((s) => s.register); + const unregisterSearch = useHeaderSearchStore((s) => s.unregister); + + useEffect(() => { + registerSearch("Search providers..."); + return () => unregisterSearch(); + }, [registerSearch, unregisterSearch]); + + const matchSearch = (name) => + !searchQuery.trim() || + name.toLowerCase().includes(searchQuery.trim().toLowerCase()); useEffect(() => { const fetchData = async () => { @@ -224,7 +237,8 @@ export default function ProvidersPage() { color: "#10A37F", textIcon: "OC", apiType: node.apiType, - })); + })) + .filter((p) => matchSearch(p.name)); const anthropicCompatibleProviders = providerNodes .filter((node) => node.type === "anthropic-compatible") @@ -233,7 +247,22 @@ export default function ProvidersPage() { name: node.name || "Anthropic Compatible", color: "#D97757", textIcon: "AC", - })); + })) + .filter((p) => matchSearch(p.name)); + + const oauthEntries = Object.entries(OAUTH_PROVIDERS).filter(([, info]) => + matchSearch(info.name), + ); + const freeEntries = Object.entries(FREE_PROVIDERS).filter(([, info]) => + matchSearch(info.name), + ); + const freeTierEntries = Object.entries(FREE_TIER_PROVIDERS).filter( + ([, info]) => matchSearch(info.name), + ); + const apikeyEntries = Object.entries(APIKEY_PROVIDERS).filter( + ([, info]) => + (info.serviceKinds ?? ["llm"]).includes("llm") && matchSearch(info.name), + ); if (loading) { return ( @@ -244,9 +273,27 @@ export default function ProvidersPage() { ); } + const hasAnyResult = + oauthEntries.length > 0 || + freeEntries.length > 0 || + freeTierEntries.length > 0 || + apikeyEntries.length > 0 || + compatibleProviders.length > 0 || + anthropicCompatibleProviders.length > 0; + return (
+ {!hasAnyResult && ( +
+ + search_off + +

No providers match your search

+
+ )} + {/* OAuth Providers */} + {oauthEntries.length > 0 && (

@@ -275,7 +322,7 @@ export default function ProvidersPage() {

- {Object.entries(OAUTH_PROVIDERS).map(([key, info]) => ( + {oauthEntries.map(([key, info]) => (
+ )} {/* Free Tier Providers */} + {(freeEntries.length > 0 || freeTierEntries.length > 0) && (

@@ -314,7 +363,7 @@ export default function ProvidersPage() {

- {Object.entries(FREE_PROVIDERS).map(([key, info]) => ( + {freeEntries.map(([key, info]) => ( handleToggleProvider(key, "oauth", active)} /> ))} - {Object.entries(FREE_TIER_PROVIDERS).map(([key, info]) => ( + {freeTierEntries.map(([key, info]) => (
+ )} {/* API Key Providers — fixed list */} + {apikeyEntries.length > 0 && (

@@ -363,20 +414,19 @@ export default function ProvidersPage() {

- {Object.entries(APIKEY_PROVIDERS) - .filter(([, info]) => (info.serviceKinds ?? ["llm"]).includes("llm")) - .map(([key, info]) => ( - handleToggleProvider(key, "apikey", active)} - /> - ))} + {apikeyEntries.map(([key, info]) => ( + handleToggleProvider(key, "apikey", active)} + /> + ))}
+ )} {/* Web Cookie Providers — use browser subscription cookie instead of API key */} {/*
diff --git a/src/app/(dashboard)/dashboard/proxy-pools/page.js b/src/app/(dashboard)/dashboard/proxy-pools/page.js index 383cf562..6eab6b6c 100644 --- a/src/app/(dashboard)/dashboard/proxy-pools/page.js +++ b/src/app/(dashboard)/dashboard/proxy-pools/page.js @@ -41,6 +41,10 @@ export default function ProxyPoolsPage() { const [importing, setImporting] = useState(false); const [deploying, setDeploying] = useState(false); const [testingId, setTestingId] = useState(null); + const [selectedIds, setSelectedIds] = useState([]); + const [healthChecking, setHealthChecking] = useState(false); + const [healthProgress, setHealthProgress] = useState({ current: 0, total: 0 }); + const [bulkBusy, setBulkBusy] = useState(false); const notify = useNotificationStore(); const fetchProxyPools = useCallback(async () => { @@ -162,6 +166,136 @@ export default function ProxyPoolsPage() { } }; + const handleToggleActive = async (pool) => { + const next = !pool.isActive; + setProxyPools((prev) => prev.map((p) => p.id === pool.id ? { ...p, isActive: next } : p)); + try { + const res = await fetch(`/api/proxy-pools/${pool.id}`, { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ isActive: next }), + }); + if (!res.ok) { + setProxyPools((prev) => prev.map((p) => p.id === pool.id ? { ...p, isActive: pool.isActive } : p)); + notify.error("Failed to update active state"); + } + } catch (error) { + console.log("Error toggling active:", error); + setProxyPools((prev) => prev.map((p) => p.id === pool.id ? { ...p, isActive: pool.isActive } : p)); + } + }; + + const allSelected = proxyPools.length > 0 && selectedIds.length === proxyPools.length; + const toggleSelect = (id) => setSelectedIds((prev) => prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]); + const toggleSelectAll = () => setSelectedIds(allSelected ? [] : proxyPools.map((p) => p.id)); + const clearSelection = () => setSelectedIds([]); + + const bulkSetActive = async (isActive) => { + const targets = selectedIds.length > 0 ? selectedIds : proxyPools.map((p) => p.id); + if (targets.length === 0) return; + setBulkBusy(true); + try { + let ok = 0; let failed = 0; + for (const id of targets) { + try { + const res = await fetch(`/api/proxy-pools/${id}`, { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ isActive }), + }); + if (res.ok) ok += 1; else failed += 1; + } catch { failed += 1; } + } + await fetchProxyPools(); + notify.success(`${isActive ? "Activated" : "Deactivated"} ${ok}${failed ? `, failed ${failed}` : ""}`); + } finally { + setBulkBusy(false); + } + }; + + const bulkDelete = async () => { + if (selectedIds.length === 0) return; + if (!confirm(`Delete ${selectedIds.length} proxy pool(s)?`)) return; + setBulkBusy(true); + try { + let ok = 0; let blocked = 0; let failed = 0; + for (const id of selectedIds) { + try { + const res = await fetch(`/api/proxy-pools/${id}`, { method: "DELETE" }); + if (res.ok) ok += 1; + else if (res.status === 409) blocked += 1; + else failed += 1; + } catch { failed += 1; } + } + await fetchProxyPools(); + clearSelection(); + notify.success(`Deleted ${ok}${blocked ? `, ${blocked} bound` : ""}${failed ? `, ${failed} failed` : ""}`); + } finally { + setBulkBusy(false); + } + }; + + const handleHealthCheck = async () => { + const targets = selectedIds.length > 0 + ? proxyPools.filter((p) => selectedIds.includes(p.id)) + : proxyPools; + if (targets.length === 0) return; + setHealthChecking(true); + setHealthProgress({ current: 0, total: targets.length }); + let alive = 0; const deadIds = []; + let done = 0; + const CONCURRENCY = 10; + const queue = [...targets]; + + const worker = async () => { + while (queue.length > 0) { + const pool = queue.shift(); + if (!pool) break; + try { + const res = await fetch(`/api/proxy-pools/${pool.id}/test`, { method: "POST" }); + const data = await res.json(); + if (res.ok && data.ok) alive += 1; else deadIds.push(pool.id); + } catch { + deadIds.push(pool.id); + } finally { + done += 1; + setHealthProgress({ current: done, total: targets.length }); + } + } + }; + + await Promise.all(Array.from({ length: Math.min(CONCURRENCY, targets.length) }, worker)); + await fetchProxyPools(); + setHealthChecking(false); + setHealthProgress({ current: 0, total: 0 }); + + if (deadIds.length > 0 && confirm(`Alive: ${alive}, Dead: ${deadIds.length}.\n\nDisable ${deadIds.length} dead proxies?`)) { + setBulkBusy(true); + try { + for (const id of deadIds) { + try { + await fetch(`/api/proxy-pools/${id}`, { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ isActive: false }), + }); + } catch {} + } + await fetchProxyPools(); + notify.success(`Disabled ${deadIds.length} dead proxies`); + } finally { + setBulkBusy(false); + } + } else { + notify.success(`Health check done. Alive: ${alive}, Dead: ${deadIds.length}`); + } + }; + + // Cleanup selectedIds when pools change + useEffect(() => { + setSelectedIds((prev) => prev.filter((id) => proxyPools.some((p) => p.id === id))); + }, [proxyPools]); + const openBatchImportModal = () => { setBatchImportText(""); setShowBatchImportModal(true); @@ -354,13 +488,57 @@ export default function ProxyPoolsPage() {
-
-
- Total: {proxyPools.length} - Active: {activeCount} -
+
+ {proxyPools.length > 0 && ( + + )} + Total: {proxyPools.length} + Active: {activeCount}
+ {(selectedIds.length > 0 || healthChecking) && ( +
+ checklist + + {selectedIds.length > 0 ? `${selectedIds.length} selected` : "All pools"} + +
+ + {selectedIds.length > 0 && ( + <> + + + + + + )} +
+
+ )} + {proxyPools.length === 0 ? (

No proxy pool entries yet

@@ -372,8 +550,15 @@ export default function ProxyPoolsPage() { ) : (
{proxyPools.map((pool) => ( -
-
+
+
+ toggleSelect(pool.id)} + className="mt-1 size-4 shrink-0 rounded border-black/20 dark:border-white/20" + /> +

{pool.name}

@@ -397,9 +582,16 @@ export default function ProxyPoolsPage() { Last tested: {formatDateTime(pool.lastTestedAt)} {pool.lastError ? ` · ${pool.lastError}` : ""}

+
-
+
+ handleToggleActive(pool)} + title={pool.isActive ? "Disable" : "Enable"} + /> + )} +
+ ); +} + Header.propTypes = { onMenuClick: PropTypes.func, showMenuButton: PropTypes.bool, diff --git a/src/shared/components/ModelSelectModal.js b/src/shared/components/ModelSelectModal.js index 065cff92..051b30d8 100644 --- a/src/shared/components/ModelSelectModal.js +++ b/src/shared/components/ModelSelectModal.js @@ -40,6 +40,7 @@ export default function ModelSelectModal({ const [combos, setCombos] = useState([]); const [providerNodes, setProviderNodes] = useState([]); const [customModels, setCustomModels] = useState([]); + const [disabledModels, setDisabledModels] = useState({}); const fetchCombos = async () => { try { @@ -89,6 +90,22 @@ export default function ModelSelectModal({ if (isOpen) fetchCustomModels(); }, [isOpen]); + const fetchDisabledModels = async () => { + try { + const res = await fetch("/api/models/disabled"); + if (!res.ok) throw new Error(`Failed to fetch disabled models: ${res.status}`); + const data = await res.json(); + setDisabledModels(data.disabled || {}); + } catch (error) { + console.error("Error fetching disabled models:", error); + setDisabledModels({}); + } + }; + + useEffect(() => { + if (isOpen) fetchDisabledModels(); + }, [isOpen]); + const allProviders = useMemo(() => ({ ...OAUTH_PROVIDERS, ...FREE_PROVIDERS, ...FREE_TIER_PROVIDERS, ...APIKEY_PROVIDERS }), []); // Group models by provider with priority order @@ -104,7 +121,9 @@ export default function ModelSelectModal({ // Filter a models[] array by kindFilter (keep only matching m.type) const filterByKind = (models) => { - if (!kindFilter || !TYPED_KINDS.has(kindFilter)) return models; + // No kindFilter → LLM context: keep only LLM models (no type or type === "llm") + if (!kindFilter) return models.filter((m) => m.isPlaceholder || !m.type || m.type === "llm"); + if (!TYPED_KINDS.has(kindFilter)) return models; return models.filter((m) => m.isPlaceholder || m.type === kindFilter); }; @@ -239,11 +258,18 @@ export default function ModelSelectModal({ .filter((m) => m.providerAlias === alias && !hardcodedIds.has(m.id) && !customAliasIds.has(m.id)) .map((m) => ({ id: m.id, name: m.name || m.id, value: `${alias}/${m.id}`, isCustom: true })); - let allModels = filterByKind([ + const merged = [ ...hardcodedModels.map((m) => ({ id: m.id, name: m.name, value: `${alias}/${m.id}`, type: m.type })), ...customAliasModels, ...customRegisteredModels, - ]); + ]; + // Dedupe by value (alias may equal hardcoded id, causing React key collision) + const seen = new Set(); + let allModels = filterByKind(merged.filter((m) => { + if (seen.has(m.value)) return false; + seen.add(m.value); + return true; + })); // Provider-as-model fallback: providers that support the kind but have no hardcoded models // can still be picked (value = providerAlias). Skips embedding (always needs model). @@ -265,8 +291,20 @@ export default function ModelSelectModal({ } }); + // Filter out disabled models per provider (disabled keyed by storage alias OR providerId) + Object.entries(groups).forEach(([providerId, group]) => { + const aliasKey = getProviderAlias(providerId); + const disabledIds = new Set([ + ...(disabledModels[aliasKey] || []), + ...(disabledModels[providerId] || []), + ]); + if (disabledIds.size === 0) return; + group.models = group.models.filter((m) => !disabledIds.has(m.id)); + if (group.models.length === 0) delete groups[providerId]; + }); + return groups; - }, [filteredActiveProviders, modelAliases, allProviders, providerNodes, customModels, kindFilter]); + }, [filteredActiveProviders, modelAliases, allProviders, providerNodes, customModels, disabledModels, kindFilter, activeProviders]); // Filter combos by search query (and hide combos when kindFilter is set — combos are LLM-only by design) const filteredCombos = useMemo(() => { diff --git a/src/shared/components/OAuthModal.js b/src/shared/components/OAuthModal.js index caf69841..d6bc3e85 100644 --- a/src/shared/components/OAuthModal.js +++ b/src/shared/components/OAuthModal.js @@ -173,24 +173,13 @@ export default function OAuthModal({ isOpen, provider, providerInfo, onSuccess, // Authorization code flow - build redirect URI (some providers require fixed ports) const appPort = window.location.port || (window.location.protocol === "https:" ? "443" : "80"); let redirectUri; - let codexProxyActive = false; - if (provider === "codex") { - // Try to start proxy on fixed port 1455 → redirect callback to app port - try { - const proxyRes = await fetch(`/api/oauth/codex/start-proxy?app_port=${appPort}`); - const proxyData = await proxyRes.json(); - codexProxyActive = proxyData.success; - } catch { - codexProxyActive = false; - } - // Always use fixed port 1455 as redirect_uri (Codex requirement) redirectUri = "http://localhost:1455/auth/callback"; } else { redirectUri = `http://localhost:${appPort}/callback`; } - // Build authorize URL, optionally passing provider-specific metadata (e.g. gitlab clientId) + // Build authorize URL first to get codeVerifier/state for codex server-side mode const authorizeUrl = new URL(`/api/oauth/${provider}/authorize`, window.location.origin); authorizeUrl.searchParams.set("redirect_uri", redirectUri); if (oauthMeta) { @@ -200,10 +189,29 @@ export default function OAuthModal({ isOpen, provider, providerInfo, onSuccess, const data = await res.json(); if (!res.ok) throw new Error(data.error); - setAuthData({ ...data, redirectUri }); + // Codex: start proxy with server-side session (auto-exchange) + fallback to channels + let codexProxyActive = false; + let codexServerSide = false; + if (provider === "codex") { + try { + const proxyUrl = new URL(`/api/oauth/codex/start-proxy`, window.location.origin); + proxyUrl.searchParams.set("app_port", appPort); + proxyUrl.searchParams.set("state", data.state); + proxyUrl.searchParams.set("code_verifier", data.codeVerifier); + proxyUrl.searchParams.set("redirect_uri", redirectUri); + const proxyRes = await fetch(proxyUrl.toString()); + const proxyData = await proxyRes.json(); + codexProxyActive = proxyData.success; + codexServerSide = !!proxyData.serverSide; + } catch { + codexProxyActive = false; + } + } + + setAuthData({ ...data, redirectUri, codexServerSide }); if (provider === "codex" && codexProxyActive) { - // Proxy active: callback will redirect to app port automatically + // Proxy active: callback will be handled server-side (auto-exchange) or via channels (fallback) setStep("waiting"); popupRef.current = window.open(data.authUrl, "oauth_popup", "width=600,height=700"); if (!popupRef.current) { @@ -247,6 +255,49 @@ export default function OAuthModal({ isOpen, provider, providerInfo, onSuccess, } }, [isOpen, provider, startOAuthFlow]); + // Codex server-side mode: poll status (proxy auto-exchanges + saves DB) + useEffect(() => { + if (!authData?.codexServerSide || !authData?.state) return; + if (callbackProcessedRef.current) return; + let cancelled = false; + const POLL_INTERVAL_MS = 1500; + const MAX_ATTEMPTS = 200; // ~5 minutes + let attempts = 0; + + const tick = async () => { + if (cancelled || callbackProcessedRef.current) return; + attempts += 1; + try { + const res = await fetch(`/api/oauth/codex/poll-status?state=${encodeURIComponent(authData.state)}`); + const data = await res.json(); + if (cancelled || callbackProcessedRef.current) return; + if (data.status === "done") { + callbackProcessedRef.current = true; + setStep("success"); + onSuccess?.(); + return; + } + if (data.status === "error") { + callbackProcessedRef.current = true; + setError(data.error || "Authentication failed"); + setStep("error"); + return; + } + } catch { + // Network error, keep polling + } + if (attempts >= MAX_ATTEMPTS) { + callbackProcessedRef.current = true; + setError("Authentication timeout"); + setStep("error"); + return; + } + setTimeout(tick, POLL_INTERVAL_MS); + }; + setTimeout(tick, POLL_INTERVAL_MS); + return () => { cancelled = true; }; + }, [authData, onSuccess]); + // Listen for OAuth callback via multiple methods useEffect(() => { if (!authData) return; diff --git a/src/shared/components/Sidebar.js b/src/shared/components/Sidebar.js index 55481b03..918d3582 100644 --- a/src/shared/components/Sidebar.js +++ b/src/shared/components/Sidebar.js @@ -12,7 +12,7 @@ import Button from "./Button"; import { ConfirmModal } from "./Modal"; // const VISIBLE_MEDIA_KINDS = ["embedding", "image", "imageToText", "tts", "stt", "webSearch", "webFetch", "video", "music"]; -const VISIBLE_MEDIA_KINDS = ["embedding", "image", "tts"]; +const VISIBLE_MEDIA_KINDS = ["embedding", "image", "tts", "stt"]; // Combined entry: webSearch + webFetch share one page at /dashboard/media-providers/web const COMBINED_WEB_ITEM = { id: "web", label: "Web Fetch & Search", icon: "travel_explore", href: "/dashboard/media-providers/web" }; diff --git a/src/shared/constants/cliTools.js b/src/shared/constants/cliTools.js index 8ff1f114..71d6e395 100644 --- a/src/shared/constants/cliTools.js +++ b/src/shared/constants/cliTools.js @@ -114,6 +114,22 @@ export const CLI_TOOLS = { description: "OpenCode AI Terminal Assistant", configType: "custom", }, + cowork: { + id: "cowork", + name: "Claude Cowork", + image: "/providers/claude.png", + color: "#D97757", + description: "Claude Desktop Cowork (third-party inference)", + configType: "custom", + }, + hermes: { + id: "hermes", + name: "Hermes Agent", + image: "/providers/hermes.png", + color: "#8B5CF6", + description: "Nous Research self-improving AI agent", + configType: "custom", + }, droid: { id: "droid", name: "Factory Droid", @@ -212,14 +228,6 @@ export const CLI_TOOLS = { }`, }, }, - hermes: { - id: "hermes", - name: "Hermes Agent", - image: "/providers/hermes.png", - color: "#8B5CF6", - description: "Nous Research self-improving AI agent", - configType: "custom", - }, // HIDDEN: gemini-cli // "gemini-cli": { // id: "gemini-cli", diff --git a/src/shared/constants/providers.js b/src/shared/constants/providers.js index 14c02f04..4423ad94 100644 --- a/src/shared/constants/providers.js +++ b/src/shared/constants/providers.js @@ -3,7 +3,7 @@ // Free Providers (kiro first, iflow last) export const FREE_PROVIDERS = { kiro: { id: "kiro", alias: "kr", name: "Kiro AI", icon: "psychology_alt", color: "#FF6B35", website: "https://kiro.dev", notice: { signupUrl: "https://kiro.dev" } }, - qwen: { id: "qwen", alias: "qw", name: "Qwen Code", icon: "psychology", color: "#10B981", deprecated: true, deprecationNotice: "Qwen OAuth free tier was discontinued by Alibaba on 2026-04-15. New connections will not work.", website: "https://chat.qwen.ai", notice: { signupUrl: "https://chat.qwen.ai" }, serviceKinds: ["llm", "tts", "stt"], ttsConfig: { baseUrl: "http://localhost:8000/v1/audio/speech", authType: "none", authHeader: "none", format: "openai", models: [{ id: "qwen3-tts", name: "Qwen3 TTS" }] } }, + qwen: { id: "qwen", alias: "qw", name: "Qwen Code", icon: "psychology", color: "#10B981", mediaPriority: 999, deprecated: true, deprecationNotice: "Qwen OAuth free tier was discontinued by Alibaba on 2026-04-15. New connections will not work.", website: "https://chat.qwen.ai", notice: { signupUrl: "https://chat.qwen.ai" }, serviceKinds: ["llm", "tts"], ttsConfig: { baseUrl: "http://localhost:8000/v1/audio/speech", authType: "none", authHeader: "none", format: "openai", models: [{ id: "qwen3-tts", name: "Qwen3 TTS" }] } }, "gemini-cli": { id: "gemini-cli", alias: "gc", name: "Gemini CLI", icon: "terminal", color: "#4285F4", deprecated: true, deprecationNotice: "Gemini CLI is designed exclusively for Gemini CLI. Using it with other tools (OpenClaw, Claude, Codex...) may result in account restrictions or bans.", website: "https://github.com/google-gemini/gemini-cli", notice: { signupUrl: "https://github.com/google-gemini/gemini-cli" } }, // gitlab: { id: "gitlab", alias: "gl", name: "GitLab Duo", icon: "code", color: "#FC6D26" }, // codebuddy: { id: "codebuddy", alias: "cb", name: "CodeBuddy", icon: "smart_toy", color: "#006EFF" }, @@ -15,10 +15,10 @@ export const FREE_PROVIDERS = { // Free Tier Providers (has free access but may require account/API key) export const FREE_TIER_PROVIDERS = { openrouter: { id: "openrouter", alias: "openrouter", name: "OpenRouter", icon: "router", color: "#F97316", textIcon: "OR", website: "https://openrouter.ai", notice: { text: "Free tier: 27+ free models, no credit card needed, 200 req/day. After $10 credit: 1,000 req/day.", apiKeyUrl: "https://openrouter.ai/settings/keys" }, modelsFetcher: { url: "https://openrouter.ai/api/v1/models", type: "openrouter-free" }, passthroughModels: true, serviceKinds: ["llm", "embedding", "tts", "imageToText"], embeddingConfig: { baseUrl: "https://openrouter.ai/api/v1/embeddings", authType: "apikey", authHeader: "bearer", models: [{ id: "openai/text-embedding-3-small", name: "Text Embedding 3 Small (OpenRouter)", dimensions: 1536 }, { id: "openai/text-embedding-3-large", name: "Text Embedding 3 Large (OpenRouter)", dimensions: 3072 }, { id: "openai/text-embedding-ada-002", name: "Text Embedding Ada 002 (OpenRouter)", dimensions: 1536 }] } }, - nvidia: { id: "nvidia", alias: "nvidia", name: "NVIDIA NIM", icon: "developer_board", color: "#76B900", textIcon: "NV", website: "https://developer.nvidia.com/nim", notice: { text: "Free access for NVIDIA Developer Program members (prototyping & testing).", apiKeyUrl: "https://build.nvidia.com/settings/api-keys" }, serviceKinds: ["llm", "tts", "embedding", "stt"], ttsConfig: { baseUrl: "https://integrate.api.nvidia.com/v1/audio/speech", authType: "apikey", authHeader: "bearer", format: "nvidia-tts", models: [{ id: "fastpitch", name: "FastPitch" }, { id: "tacotron2", name: "Tacotron2" }] }, embeddingConfig: { baseUrl: "https://integrate.api.nvidia.com/v1/embeddings", authType: "apikey", authHeader: "bearer", models: [{ id: "nvidia/nv-embedqa-e5-v5", name: "NV EmbedQA E5 v5", dimensions: 1024 }] } }, + nvidia: { id: "nvidia", alias: "nvidia", name: "NVIDIA NIM", icon: "developer_board", color: "#76B900", textIcon: "NV", website: "https://developer.nvidia.com/nim", notice: { text: "Free access for NVIDIA Developer Program members (prototyping & testing).", apiKeyUrl: "https://build.nvidia.com/settings/api-keys" }, serviceKinds: ["llm", "tts", "embedding"], ttsConfig: { baseUrl: "https://integrate.api.nvidia.com/v1/audio/speech", authType: "apikey", authHeader: "bearer", format: "nvidia-tts", models: [{ id: "fastpitch", name: "FastPitch" }, { id: "tacotron2", name: "Tacotron2" }] }, embeddingConfig: { baseUrl: "https://integrate.api.nvidia.com/v1/embeddings", authType: "apikey", authHeader: "bearer", models: [{ id: "nvidia/nv-embedqa-e5-v5", name: "NV EmbedQA E5 v5", dimensions: 1024 }] } }, ollama: { id: "ollama", alias: "ollama", name: "Ollama Cloud", icon: "cloud", color: "#ffffffff", textIcon: "OL", website: "https://ollama.com", notice: { text: "Free tier: light usage, 1 cloud model at a time (limits reset every 5h & 7d). Pro $20/mo · Max $100/mo.", apiKeyUrl: "https://ollama.com/settings/keys" } }, vertex: { id: "vertex", alias: "vx", name: "Vertex AI", icon: "cloud", color: "#4285F4", textIcon: "VX", website: "https://cloud.google.com/vertex-ai", notice: { text: "New Google Cloud accounts get $300 free credits. Requires GCP project + Service Account with Vertex AI API enabled.", apiKeyUrl: "https://console.cloud.google.com/iam-admin/serviceaccounts" } }, - gemini: { id: "gemini", alias: "gemini", name: "Gemini", icon: "diamond", color: "#4285F4", textIcon: "GE", website: "https://ai.google.dev", notice: { apiKeyUrl: "https://aistudio.google.com/app/apikey" }, serviceKinds: ["llm", "embedding", "image", "imageToText", "webSearch"], searchViaChat: { defaultModel: "gemini-2.5-flash", pricingUrl: "https://ai.google.dev/pricing", freeTier: "Free tier: 15 RPM, 1M tokens/day on gemini-2.5-flash via AI Studio." }, embeddingConfig: { baseUrl: "https://generativelanguage.googleapis.com/v1beta/models", authType: "apikey", authHeader: "key", models: [{ id: "text-embedding-004", name: "Text Embedding 004", dimensions: 768 }, { id: "embedding-001", name: "Embedding 001", dimensions: 768 }] } }, + gemini: { id: "gemini", alias: "gemini", name: "Gemini", icon: "diamond", color: "#4285F4", textIcon: "GE", mediaPriority: 1, website: "https://ai.google.dev", notice: { apiKeyUrl: "https://aistudio.google.com/app/apikey" }, serviceKinds: ["llm", "embedding", "image", "imageToText", "webSearch", "tts", "stt"], sttConfig: { baseUrl: "https://generativelanguage.googleapis.com/v1beta/models", authType: "apikey", authHeader: "key", format: "gemini-stt", models: [{ id: "gemini-2.5-pro", name: "Gemini 2.5 Pro (Best)" }, { id: "gemini-2.5-flash", name: "Gemini 2.5 Flash" }, { id: "gemini-2.5-flash-lite", name: "Gemini 2.5 Flash Lite (Cheapest)" }, { id: "gemini-2.0-flash", name: "Gemini 2.0 Flash" }] }, searchViaChat: { defaultModel: "gemini-2.5-flash", pricingUrl: "https://ai.google.dev/pricing", freeTier: "Free tier: 15 RPM, 1M tokens/day on gemini-2.5-flash via AI Studio." }, embeddingConfig: { baseUrl: "https://generativelanguage.googleapis.com/v1beta/models", authType: "apikey", authHeader: "key", models: [{ id: "text-embedding-004", name: "Text Embedding 004", dimensions: 768 }, { id: "embedding-001", name: "Embedding 001", dimensions: 768 }] }, ttsConfig: { baseUrl: "https://generativelanguage.googleapis.com/v1beta/models", authType: "apikey", authHeader: "key", format: "gemini-tts", models: [{ id: "gemini-2.5-flash-preview-tts", name: "Gemini 2.5 Flash TTS" }, { id: "gemini-2.5-pro-preview-tts", name: "Gemini 2.5 Pro TTS" }] } }, "cloudflare-ai": { id: "cloudflare-ai", alias: "cf", name: "Cloudflare", icon: "cloud", color: "#F38020", textIcon: "CF", website: "https://developers.cloudflare.com/workers-ai/", notice: { text: "Workers AI free tier. Requires a Cloudflare API token and Account ID.", apiKeyUrl: "https://dash.cloudflare.com/profile/api-tokens" }, serviceKinds: ["llm"], hasProviderSpecificData: true }, byteplus: { id: "byteplus", alias: "bpm", name: "BytePlus ModelArk", icon: "cloud", color: "#2563EB", textIcon: "BP", website: "https://console.byteplus.com/ark", notice: { text: "Free credits for new accounts. Access to Seed 2.0, Kimi K2 Thinking, GLM 4.7, GPT-OSS-120B models.", apiKeyUrl: "https://console.byteplus.com/ark/region:ark+ap-southeast-1/apiKey" }, serviceKinds: ["llm"] }, }; @@ -63,13 +63,13 @@ export const APIKEY_PROVIDERS = { "alicode-intl": { id: "alicode-intl", alias: "alicode-intl", name: "Alibaba Intl", icon: "cloud", color: "#FF6A00", textIcon: "ALi", website: "https://modelstudio.console.alibabacloud.com", notice: { apiKeyUrl: "https://modelstudio.console.alibabacloud.com/?apiKey=1" } }, "xiaomi-mimo": { id: "xiaomi-mimo", alias: "mimo", name: "Xiaomi MiMo", icon: "smart_toy", color: "#FF6900", textIcon: "XM", website: "https://xiaomimimo.com", notice: { apiKeyUrl: "https://xiaomimimo.com" } }, "volcengine-ark": { id: "volcengine-ark", alias: "ark", name: "Volcengine Ark", icon: "cloud", color: "#1677FF", textIcon: "ARK", website: "https://ark.cn-beijing.volces.com", notice: { apiKeyUrl: "https://console.volcengine.com/ark/region:ark+cn-beijing/apiKey" } }, - openai: { id: "openai", alias: "openai", name: "OpenAI", icon: "auto_awesome", color: "#10A37F", textIcon: "OA", website: "https://platform.openai.com", notice: { apiKeyUrl: "https://platform.openai.com/api-keys" }, serviceKinds: ["llm", "embedding", "tts", "image", "imageToText", "webSearch"], thinkingConfig: THINKING_CONFIG.effort, searchViaChat: { defaultModel: "gpt-4o-mini", pricingUrl: "https://openai.com/api/pricing" }, ttsConfig: { baseUrl: "https://api.openai.com/v1/audio/speech", authType: "apikey", authHeader: "bearer", format: "openai", models: [{ id: "tts-1", name: "TTS-1" }, { id: "tts-1-hd", name: "TTS-1 HD" }, { id: "gpt-4o-mini-tts", name: "GPT-4o Mini TTS" }] }, embeddingConfig: { baseUrl: "https://api.openai.com/v1/embeddings", authType: "apikey", authHeader: "bearer", models: [{ id: "text-embedding-3-small", name: "Text Embedding 3 Small", dimensions: 1536 }, { id: "text-embedding-3-large", name: "Text Embedding 3 Large", dimensions: 3072 }, { id: "text-embedding-ada-002", name: "Text Embedding Ada 002", dimensions: 1536 }] } }, + openai: { id: "openai", alias: "openai", name: "OpenAI", icon: "auto_awesome", color: "#10A37F", textIcon: "OA", website: "https://platform.openai.com", notice: { apiKeyUrl: "https://platform.openai.com/api-keys" }, serviceKinds: ["llm", "embedding", "tts", "stt", "image", "imageToText", "webSearch"], thinkingConfig: THINKING_CONFIG.effort, searchViaChat: { defaultModel: "gpt-4o-mini", pricingUrl: "https://openai.com/api/pricing" }, ttsConfig: { baseUrl: "https://api.openai.com/v1/audio/speech", authType: "apikey", authHeader: "bearer", format: "openai", models: [{ id: "tts-1", name: "TTS-1" }, { id: "tts-1-hd", name: "TTS-1 HD" }, { id: "gpt-4o-mini-tts", name: "GPT-4o Mini TTS" }] }, sttConfig: { baseUrl: "https://api.openai.com/v1/audio/transcriptions", authType: "apikey", authHeader: "bearer", format: "openai", models: [{ id: "whisper-1", name: "Whisper 1" }, { id: "gpt-4o-transcribe", name: "GPT-4o Transcribe" }, { id: "gpt-4o-mini-transcribe", name: "GPT-4o Mini Transcribe" }] }, embeddingConfig: { baseUrl: "https://api.openai.com/v1/embeddings", authType: "apikey", authHeader: "bearer", models: [{ id: "text-embedding-3-small", name: "Text Embedding 3 Small", dimensions: 1536 }, { id: "text-embedding-3-large", name: "Text Embedding 3 Large", dimensions: 3072 }, { id: "text-embedding-ada-002", name: "Text Embedding Ada 002", dimensions: 1536 }] } }, anthropic: { id: "anthropic", alias: "anthropic", name: "Anthropic", icon: "smart_toy", color: "#D97757", textIcon: "AN", website: "https://console.anthropic.com", notice: { apiKeyUrl: "https://console.anthropic.com/settings/keys" }, serviceKinds: ["llm", "imageToText"] }, "opencode-go": { id: "opencode-go", alias: "ocg", name: "OpenCode Go", icon: "terminal", color: "#E87040", textIcon: "OC", website: "https://opencode.ai/auth", notice: { text: "OpenCode Go subscription: $5/mo (then $10/mo). Access to Kimi, GLM, Qwen, MiMo, MiniMax models.", apiKeyUrl: "https://opencode.ai/auth" } }, azure: { id: "azure", alias: "azure", name: "Azure OpenAI", icon: "cloud", color: "#0078D4", textIcon: "AZ", website: "https://azure.microsoft.com/en-us/products/ai-services/openai-service", notice: { apiKeyUrl: "https://portal.azure.com/#view/Microsoft_Azure_ProjectOxford/CognitiveServicesHub/~/OpenAI" }, hasProviderSpecificData: true }, deepseek: { id: "deepseek", alias: "ds", name: "DeepSeek", icon: "bolt", color: "#4D6BFE", textIcon: "DS", website: "https://deepseek.com", notice: { apiKeyUrl: "https://platform.deepseek.com/api_keys" } }, - groq: { id: "groq", alias: "groq", name: "Groq", icon: "speed", color: "#F55036", textIcon: "GQ", website: "https://groq.com", notice: { apiKeyUrl: "https://console.groq.com/keys" }, serviceKinds: ["llm", "imageToText"] }, + groq: { id: "groq", alias: "groq", name: "Groq", icon: "speed", color: "#F55036", textIcon: "GQ", website: "https://groq.com", notice: { apiKeyUrl: "https://console.groq.com/keys" }, serviceKinds: ["llm", "imageToText", "stt"], sttConfig: { baseUrl: "https://api.groq.com/openai/v1/audio/transcriptions", authType: "apikey", authHeader: "bearer", format: "openai", models: [{ id: "whisper-large-v3", name: "Whisper Large v3" }, { id: "whisper-large-v3-turbo", name: "Whisper Large v3 Turbo" }, { id: "distil-whisper-large-v3-en", name: "Distil Whisper Large v3 EN" }] } }, xai: { id: "xai", alias: "xai", name: "xAI (Grok)", icon: "auto_awesome", color: "#1DA1F2", textIcon: "XA", website: "https://x.ai", notice: { apiKeyUrl: "https://console.x.ai" }, serviceKinds: ["llm", "imageToText", "webSearch"], searchViaChat: { defaultModel: "grok-4.20-reasoning", pricingUrl: "https://x.ai/api#pricing" } }, mistral: { id: "mistral", alias: "mistral", name: "Mistral", icon: "air", color: "#FF7000", textIcon: "MI", website: "https://mistral.ai", notice: { apiKeyUrl: "https://console.mistral.ai/api-keys" }, serviceKinds: ["llm", "imageToText", "embedding"], embeddingConfig: { baseUrl: "https://api.mistral.ai/v1/embeddings", authType: "apikey", authHeader: "bearer", models: [{ id: "mistral-embed", name: "Mistral Embed", dimensions: 1024 }] } }, perplexity: { id: "perplexity", alias: "pplx", name: "Perplexity", icon: "search", color: "#20808D", textIcon: "PP", website: "https://www.perplexity.ai", notice: { apiKeyUrl: "https://www.perplexity.ai/settings/api" }, serviceKinds: ["llm", "webSearch"], searchConfig: { baseUrl: "https://api.perplexity.ai/search", method: "POST", authType: "apikey", authHeader: "bearer", costPerQuery: 0.005, freeMonthlyQuota: 0, searchTypes: ["web"], defaultMaxResults: 5, maxMaxResults: 20, timeoutMs: 10000, cacheTTLMs: 300000 } }, @@ -80,22 +80,22 @@ export const APIKEY_PROVIDERS = { nebius: { id: "nebius", alias: "nebius", name: "Nebius AI", icon: "cloud", color: "#6C5CE7", textIcon: "NB", website: "https://nebius.com", notice: { apiKeyUrl: "https://studio.nebius.com/settings/api-keys" }, serviceKinds: ["llm", "embedding"], embeddingConfig: { baseUrl: "https://api.tokenfactory.nebius.com/v1/embeddings", authType: "apikey", authHeader: "bearer", models: [{ id: "Qwen/Qwen3-Embedding-8B", name: "Qwen3 Embedding 8B", dimensions: 4096 }] } }, siliconflow: { id: "siliconflow", alias: "siliconflow", name: "SiliconFlow", icon: "cloud_queue", color: "#5B6EF5", textIcon: "SF", website: "https://cloud.siliconflow.com", notice: { apiKeyUrl: "https://cloud.siliconflow.com/account/ak" } }, hyperbolic: { id: "hyperbolic", alias: "hyp", name: "Hyperbolic", icon: "bolt", color: "#00D4FF", textIcon: "HY", website: "https://hyperbolic.xyz", notice: { apiKeyUrl: "https://app.hyperbolic.xyz/settings" }, serviceKinds: ["llm", "tts"], ttsConfig: { baseUrl: "https://api.hyperbolic.xyz/v1/audio/generation", authType: "apikey", authHeader: "bearer", format: "hyperbolic", models: [{ id: "melo-tts", name: "Melo TTS" }] } }, - deepgram: { id: "deepgram", alias: "dg", name: "Deepgram", icon: "mic", color: "#13EF93", textIcon: "DG", website: "https://deepgram.com", notice: { text: "$200 free credit on signup (no card required). Aura-1: $0.015/1k chars, Aura-2: $0.030/1k chars (Pay-As-You-Go).", apiKeyUrl: "https://console.deepgram.com/api-keys" }, serviceKinds: ["stt", "imageToText", "tts"], ttsConfig: { baseUrl: "https://api.deepgram.com/v1/speak", authType: "apikey", authHeader: "token", format: "deepgram", models: [] } }, - assemblyai: { id: "assemblyai", alias: "aai", name: "AssemblyAI", icon: "record_voice_over", color: "#0062FF", textIcon: "AA", website: "https://assemblyai.com", notice: { apiKeyUrl: "https://www.assemblyai.com/app/api-keys" }, serviceKinds: ["stt"] }, + deepgram: { id: "deepgram", alias: "dg", name: "Deepgram", icon: "mic", color: "#13EF93", textIcon: "DG", website: "https://deepgram.com", notice: { text: "$200 free credit on signup (no card required). Aura-1: $0.015/1k chars, Aura-2: $0.030/1k chars (Pay-As-You-Go).", apiKeyUrl: "https://console.deepgram.com/api-keys" }, serviceKinds: ["stt", "imageToText", "tts"], ttsConfig: { baseUrl: "https://api.deepgram.com/v1/speak", authType: "apikey", authHeader: "token", format: "deepgram", models: [] }, sttConfig: { baseUrl: "https://api.deepgram.com/v1/listen", authType: "apikey", authHeader: "token", format: "deepgram", models: [{ id: "nova-3", name: "Nova 3" }, { id: "nova-2", name: "Nova 2" }, { id: "whisper-large", name: "Whisper Large" }] } }, + assemblyai: { id: "assemblyai", alias: "aai", name: "AssemblyAI", icon: "record_voice_over", color: "#0062FF", textIcon: "AA", website: "https://assemblyai.com", notice: { apiKeyUrl: "https://www.assemblyai.com/app/api-keys" }, serviceKinds: ["stt"], sttConfig: { baseUrl: "https://api.assemblyai.com/v2/transcript", authType: "apikey", authHeader: "bearer", format: "assemblyai", async: true, models: [{ id: "universal-3-pro", name: "Universal 3 Pro" }, { id: "universal-2", name: "Universal 2" }] } }, nanobanana: { id: "nanobanana", alias: "nb", name: "NanoBanana API", icon: "extension", color: "#FFD700", textIcon: "🍌", website: "https://nanobananaapi.ai", notice: { text: "3rd-party proxy for Google Nano Banana (Gemini 2.5/3 Flash Image). For official, use Gemini provider.", apiKeyUrl: "https://nanobananaapi.ai/dashboard" }, serviceKinds: ["image"] }, elevenlabs: { id: "elevenlabs", alias: "el", name: "ElevenLabs", icon: "record_voice_over", color: "#6C47FF", textIcon: "EL", website: "https://elevenlabs.io", notice: { apiKeyUrl: "https://elevenlabs.io/app/settings/api-keys" }, serviceKinds: ["tts"], ttsConfig: { baseUrl: "https://api.elevenlabs.io/v1/text-to-speech", authType: "apikey", authHeader: "xi-api-key", format: "elevenlabs", models: [{ id: "eleven_multilingual_v2", name: "Eleven Multilingual v2" }, { id: "eleven_turbo_v2_5", name: "Eleven Turbo v2.5" }] } }, cartesia: { id: "cartesia", alias: "cartesia", name: "Cartesia", icon: "spatial_audio", color: "#FF4F8B", textIcon: "CA", website: "https://cartesia.ai", notice: { apiKeyUrl: "https://play.cartesia.ai/keys" }, serviceKinds: ["tts"], hidden: true, ttsConfig: { baseUrl: "https://api.cartesia.ai/tts/bytes", authType: "apikey", authHeader: "x-api-key", format: "cartesia", models: [{ id: "sonic-2", name: "Sonic 2" }, { id: "sonic-3", name: "Sonic 3" }] } }, playht: { id: "playht", alias: "playht", name: "PlayHT", icon: "play_circle", color: "#00B4D8", textIcon: "PH", website: "https://play.ht", notice: { apiKeyUrl: "https://play.ht/studio/api-access" }, serviceKinds: ["tts"], hidden: true, ttsConfig: { baseUrl: "https://api.play.ht/api/v2/tts/stream", authType: "apikey", authHeader: "playht", format: "playht", models: [{ id: "PlayDialog", name: "PlayDialog" }, { id: "Play3.0-mini", name: "Play 3.0 Mini" }] } }, - "local-device": { id: "local-device", alias: "local-device", name: "Local Device", icon: "speaker", color: "#64748B", textIcon: "LD", serviceKinds: ["tts"], noAuth: true, ttsConfig: { baseUrl: "local-device", authType: "none", authHeader: "none", format: "local-device", models: [] } }, - "google-tts": { id: "google-tts", alias: "google-tts", name: "Google TTS", icon: "record_voice_over", color: "#4285F4", textIcon: "GT", serviceKinds: ["tts"], noAuth: true, ttsConfig: { baseUrl: "google-tts", authType: "none", authHeader: "none", format: "google-tts", models: [] } }, - "edge-tts": { id: "edge-tts", alias: "edge-tts", name: "Edge TTS", icon: "record_voice_over", color: "#0078D4", textIcon: "ET", serviceKinds: ["tts"], noAuth: true, ttsConfig: { baseUrl: "edge-tts", authType: "none", authHeader: "none", format: "edge-tts", models: [] } }, + "local-device": { id: "local-device", alias: "local-device", name: "Local Device", icon: "speaker", color: "#64748B", textIcon: "LD", mediaPriority: 5, serviceKinds: ["tts"], noAuth: true, ttsConfig: { baseUrl: "local-device", authType: "none", authHeader: "none", format: "local-device", models: [] } }, + "google-tts": { id: "google-tts", alias: "google-tts", name: "Google TTS", icon: "record_voice_over", color: "#4285F4", textIcon: "GT", mediaPriority: 5, serviceKinds: ["tts"], noAuth: true, ttsConfig: { baseUrl: "google-tts", authType: "none", authHeader: "none", format: "google-tts", models: [] } }, + "edge-tts": { id: "edge-tts", alias: "edge-tts", name: "Edge TTS", icon: "record_voice_over", color: "#0078D4", textIcon: "ET", mediaPriority: 5, serviceKinds: ["tts"], noAuth: true, ttsConfig: { baseUrl: "edge-tts", authType: "none", authHeader: "none", format: "edge-tts", models: [] } }, coqui: { id: "coqui", alias: "coqui", name: "Coqui TTS", icon: "record_voice_over", color: "#10B981", textIcon: "CQ", website: "https://github.com/coqui-ai/TTS", serviceKinds: ["tts"], hidden: true, noAuth: true, ttsConfig: { baseUrl: "http://localhost:5002/api/tts", authType: "none", authHeader: "none", format: "coqui", models: [{ id: "tts_models/en/ljspeech/tacotron2-DDC", name: "Tacotron2 DDC (LJSpeech)" }] } }, tortoise: { id: "tortoise", alias: "tortoise", name: "Tortoise TTS", icon: "record_voice_over", color: "#7C3AED", textIcon: "TT", website: "https://github.com/neonbjb/tortoise-tts", serviceKinds: ["tts"], hidden: true, noAuth: true, ttsConfig: { baseUrl: "http://localhost:5000/api/tts", authType: "none", authHeader: "none", format: "tortoise", models: [{ id: "tortoise-v2", name: "Tortoise v2" }] } }, inworld: { id: "inworld", alias: "inworld", name: "Inworld TTS", icon: "record_voice_over", color: "#FF6B6B", textIcon: "IW", website: "https://inworld.ai", notice: { text: "Free tier: 40 minutes/month TTS. Paid: TTS-1.5 Mini $0.01/min ($15/1M chars), TTS-1.5 Max $0.025/min ($30/1M chars). 270+ voices, 15 languages.", apiKeyUrl: "https://platform.inworld.ai/api-keys" }, serviceKinds: ["tts"], ttsConfig: { baseUrl: "https://api.inworld.ai/tts/v1/voice", authType: "apikey", authHeader: "basic", format: "inworld", models: [{ id: "inworld-tts-1.5-mini", name: "Inworld TTS 1.5 Mini ($0.01/min)" }, { id: "inworld-tts-1.5-max", name: "Inworld TTS 1.5 Max ($0.025/min)" }] } }, "voyage-ai": { id: "voyage-ai", alias: "voyage", name: "Voyage AI", icon: "data_array", color: "#0EA5E9", textIcon: "VG", website: "https://www.voyageai.com", notice: { apiKeyUrl: "https://dash.voyageai.com/api-keys" }, serviceKinds: ["embedding"], embeddingConfig: { baseUrl: "https://api.voyageai.com/v1/embeddings", authType: "apikey", authHeader: "bearer", models: [{ id: "voyage-3-large", name: "Voyage 3 Large", dimensions: 1024 }, { id: "voyage-3.5", name: "Voyage 3.5", dimensions: 1024 }, { id: "voyage-3.5-lite", name: "Voyage 3.5 Lite", dimensions: 1024 }, { id: "voyage-code-3", name: "Voyage Code 3", dimensions: 1024 }, { id: "voyage-finance-2", name: "Voyage Finance 2", dimensions: 1024 }, { id: "voyage-law-2", name: "Voyage Law 2", dimensions: 1024 }, { id: "voyage-multilingual-2", name: "Voyage Multilingual 2", dimensions: 1024 }] } }, sdwebui: { id: "sdwebui", alias: "sdwebui", name: "SD WebUI", icon: "brush", color: "#FF7043", textIcon: "SD", website: "https://github.com/AUTOMATIC1111/stable-diffusion-webui", serviceKinds: ["image"] }, comfyui: { id: "comfyui", alias: "comfyui", name: "ComfyUI", icon: "account_tree", color: "#4CAF50", textIcon: "CF", website: "https://github.com/comfyanonymous/ComfyUI", serviceKinds: ["image"] }, - huggingface: { id: "huggingface", alias: "hf", name: "HuggingFace", icon: "face", color: "#FFD21E", textIcon: "HF", website: "https://huggingface.co", notice: { apiKeyUrl: "https://huggingface.co/settings/tokens" }, serviceKinds: ["image", "imageToText", "tts"], hiddenKinds: ["tts"], ttsConfig: { baseUrl: "https://api-inference.huggingface.co/models", authType: "apikey", authHeader: "bearer", format: "huggingface-tts", models: [{ id: "facebook/mms-tts-eng", name: "MMS TTS English" }, { id: "microsoft/speecht5_tts", name: "SpeechT5 TTS" }] } }, + huggingface: { id: "huggingface", alias: "hf", name: "HuggingFace", icon: "face", color: "#FFD21E", textIcon: "HF", website: "https://huggingface.co", notice: { apiKeyUrl: "https://huggingface.co/settings/tokens" }, serviceKinds: ["image", "imageToText", "tts", "stt"], hiddenKinds: ["tts"], ttsConfig: { baseUrl: "https://api-inference.huggingface.co/models", authType: "apikey", authHeader: "bearer", format: "huggingface-tts", models: [{ id: "facebook/mms-tts-eng", name: "MMS TTS English" }, { id: "microsoft/speecht5_tts", name: "SpeechT5 TTS" }] }, sttConfig: { baseUrl: "https://api-inference.huggingface.co/models", authType: "apikey", authHeader: "bearer", format: "huggingface-asr", models: [{ id: "openai/whisper-large-v3", name: "Whisper Large v3 (HF)" }, { id: "openai/whisper-small", name: "Whisper Small (HF)" }] } }, blackbox: { id: "blackbox", alias: "bb", name: "Blackbox AI", icon: "smart_toy", color: "#5B5FEF", textIcon: "BB", website: "https://blackbox.ai", notice: { apiKeyUrl: "https://www.blackbox.ai/api-management" }, serviceKinds: ["llm"] }, chutes: { id: "chutes", alias: "ch", name: "Chutes AI", icon: "water_drop", color: "#ffffffff", textIcon: "CH", website: "https://chutes.ai", notice: { apiKeyUrl: "https://chutes.ai/app/api" } }, "ollama-local": { id: "ollama-local", alias: "ollama-local", name: "Ollama Local", icon: "cloud", color: "#ffffffff", textIcon: "OL", website: "https://ollama.com" }, @@ -133,7 +133,7 @@ export const MEDIA_PROVIDER_KINDS = [ { id: "image", label: "Text to Image", icon: "brush", endpoint: { method: "POST", path: "/v1/images/generations" } }, { id: "imageToText", label: "Image to Text", icon: "image_search", endpoint: { method: "POST", path: "/v1/images/understanding" } }, { id: "tts", label: "Text To Speech", icon: "record_voice_over", endpoint: { method: "POST", path: "/v1/audio/speech" } }, - { id: "stt", label: "STT", icon: "mic", endpoint: { method: "POST", path: "/v1/audio/transcriptions" } }, + { id: "stt", label: "Speech To Text", icon: "mic", endpoint: { method: "POST", path: "/v1/audio/transcriptions" } }, { id: "webSearch", label: "Web Search", icon: "travel_explore", endpoint: { method: "POST", path: "/v1/search" } }, { id: "webFetch", label: "Web Fetch", icon: "language", endpoint: { method: "POST", path: "/v1/web/fetch" } }, { id: "video", label: "Video", icon: "movie", endpoint: { method: "POST", path: "/v1/video/generations" } }, @@ -203,13 +203,15 @@ export const ID_TO_ALIAS = Object.values(AI_PROVIDERS).reduce((acc, p) => { // Helper: Get providers by service kind (e.g. "tts", "embedding", "image") // Providers without serviceKinds default to ["llm"] export function getProvidersByKind(kind) { - return Object.values(AI_PROVIDERS).filter((p) => { - const kinds = p.serviceKinds ?? ["llm"]; - if (!kinds.includes(kind)) return false; - if (p.hidden) return false; // globally hidden - if (p.hiddenKinds?.includes(kind)) return false; // hidden for specific kind - return true; - }); + return Object.values(AI_PROVIDERS) + .filter((p) => { + const kinds = p.serviceKinds ?? ["llm"]; + if (!kinds.includes(kind)) return false; + if (p.hidden) return false; + if (p.hiddenKinds?.includes(kind)) return false; + return true; + }) + .sort((a, b) => (a.mediaPriority ?? 100) - (b.mediaPriority ?? 100)); } // Providers that support usage/quota API @@ -221,4 +223,17 @@ export const USAGE_SUPPORTED_PROVIDERS = [ "codex", "kimi-coding", "ollama", + "gemini-cli", + "glm", + "glm-cn", + "minimax", + "minimax-cn", +]; + +// Subset that uses apikey auth (still surfaced on quota page) +export const USAGE_APIKEY_PROVIDERS = [ + "glm", + "glm-cn", + "minimax", + "minimax-cn", ]; diff --git a/src/shared/constants/skills.js b/src/shared/constants/skills.js index 28f41392..1f758e32 100644 --- a/src/shared/constants/skills.js +++ b/src/shared/constants/skills.js @@ -39,6 +39,13 @@ export const SKILLS = [ endpoint: "/v1/audio/speech", icon: "record_voice_over", }, + { + id: "9router-stt", + name: "Speech-to-Text", + description: "Transcribe audio via OpenAI Whisper, Groq, Gemini, Deepgram, AssemblyAI…", + endpoint: "/v1/audio/transcriptions", + icon: "mic", + }, { id: "9router-embeddings", name: "Embeddings", diff --git a/src/shared/constants/ttsProviders.js b/src/shared/constants/ttsProviders.js index bc2e0324..e59d7f08 100644 --- a/src/shared/constants/ttsProviders.js +++ b/src/shared/constants/ttsProviders.js @@ -109,4 +109,14 @@ export const TTS_PROVIDER_CONFIG = { hasVoiceIdInput: true, voiceSource: "config", }, + "gemini": { + hasLanguageDropdown: false, + hasLanguageHint: true, // sends body.language to guide TTS pronunciation + hasModelSelector: true, + hasBrowseButton: false, + voiceSource: "hardcoded", + modelKey: "gemini-tts-models", + voiceKey: "gemini-tts-voices", + voicesPerModel: true, + }, }; diff --git a/src/sse/handlers/stt.js b/src/sse/handlers/stt.js new file mode 100644 index 00000000..501fcfb1 --- /dev/null +++ b/src/sse/handlers/stt.js @@ -0,0 +1,88 @@ +import { + extractApiKey, isValidApiKey, + getProviderCredentials, markAccountUnavailable, +} from "../services/auth.js"; +import { getSettings } from "@/lib/localDb"; +import { getModelInfo } from "../services/model.js"; +import { handleSttCore } from "open-sse/handlers/sttCore.js"; +import { errorResponse, unavailableResponse } from "open-sse/utils/error.js"; +import { HTTP_STATUS } from "open-sse/config/runtimeConfig.js"; +import { AI_PROVIDERS } from "@/shared/constants/providers"; +import * as log from "../utils/logger.js"; + +// Providers requiring credentials for STT +const CREDENTIALED_PROVIDERS = new Set( + Object.entries(AI_PROVIDERS) + .filter(([, p]) => p.serviceKinds?.includes("stt") && !p.noAuth && p.sttConfig?.authType !== "none") + .map(([id]) => id) +); + +export async function handleStt(request) { + let formData; + try { + formData = await request.formData(); + } catch { + return errorResponse(HTTP_STATUS.BAD_REQUEST, "Invalid multipart form data"); + } + + const modelStr = formData.get("model"); + log.request("POST", `/v1/audio/transcriptions | ${modelStr}`); + + const settings = await getSettings(); + if (settings.requireApiKey) { + const apiKey = extractApiKey(request); + if (!apiKey) return errorResponse(HTTP_STATUS.UNAUTHORIZED, "Missing API key"); + const valid = await isValidApiKey(apiKey); + if (!valid) return errorResponse(HTTP_STATUS.UNAUTHORIZED, "Invalid API key"); + } + + if (!modelStr) return errorResponse(HTTP_STATUS.BAD_REQUEST, "Missing model"); + if (!formData.get("file")) return errorResponse(HTTP_STATUS.BAD_REQUEST, "Missing required field: file"); + + const modelInfo = await getModelInfo(modelStr); + if (!modelInfo.provider) return errorResponse(HTTP_STATUS.BAD_REQUEST, "Invalid model format"); + + const { provider, model } = modelInfo; + log.info("ROUTING", `Provider: ${provider}, Model: ${model}`); + + // noAuth providers + if (!CREDENTIALED_PROVIDERS.has(provider)) { + const result = await handleSttCore({ provider, model, formData }); + if (result.success) return result.response; + return errorResponse(result.status || HTTP_STATUS.BAD_GATEWAY, result.error || "STT failed"); + } + + // Credentialed — fallback loop + const excludeConnectionIds = new Set(); + let lastError = null; + let lastStatus = null; + + while (true) { + const credentials = await getProviderCredentials(provider, excludeConnectionIds, model); + + if (!credentials || credentials.allRateLimited) { + if (credentials?.allRateLimited) { + const msg = lastError || credentials.lastError || "Unavailable"; + const status = lastStatus || Number(credentials.lastErrorCode) || HTTP_STATUS.SERVICE_UNAVAILABLE; + return unavailableResponse(status, `[${provider}/${model}] ${msg}`, credentials.retryAfter, credentials.retryAfterHuman); + } + if (excludeConnectionIds.size === 0) return errorResponse(HTTP_STATUS.BAD_REQUEST, `No credentials for provider: ${provider}`); + return errorResponse(lastStatus || HTTP_STATUS.SERVICE_UNAVAILABLE, lastError || "All accounts unavailable"); + } + + log.info("AUTH", `\x1b[32mUsing ${provider} account: ${credentials.connectionName}\x1b[0m`); + + const result = await handleSttCore({ provider, model, formData, credentials }); + + if (result.success) return result.response; + + const { shouldFallback } = await markAccountUnavailable(credentials.connectionId, result.status, result.error, provider, model); + if (shouldFallback) { + excludeConnectionIds.add(credentials.connectionId); + lastError = result.error; + lastStatus = result.status; + continue; + } + return result.response || errorResponse(result.status, result.error); + } +} diff --git a/src/sse/handlers/tts.js b/src/sse/handlers/tts.js index 443a74f3..828d45b6 100644 --- a/src/sse/handlers/tts.js +++ b/src/sse/handlers/tts.js @@ -29,7 +29,8 @@ export async function handleTts(request) { const url = new URL(request.url); const modelStr = body.model; const responseFormat = url.searchParams.get("response_format") || "mp3"; // mp3 (default) | json - log.request("POST", `${url.pathname} | ${modelStr} | format=${responseFormat}`); + const language = body.language || ""; // Optional language hint (currently used by Gemini) + log.request("POST", `${url.pathname} | ${modelStr} | format=${responseFormat}${language ? ` | lang=${language}` : ""}`); const settings = await getSettings(); if (settings.requireApiKey) { @@ -52,7 +53,7 @@ export async function handleTts(request) { return handleComboChat({ body, models: comboModels, - handleSingleModel: (b, m) => handleSingleModelTts(b, m, responseFormat), + handleSingleModel: (b, m) => handleSingleModelTts(b, m, responseFormat, language), log, comboName: modelStr, comboStrategy, @@ -60,10 +61,10 @@ export async function handleTts(request) { }); } - return handleSingleModelTts(body, modelStr, responseFormat); + return handleSingleModelTts(body, modelStr, responseFormat, language); } -async function handleSingleModelTts(body, modelStr, responseFormat) { +async function handleSingleModelTts(body, modelStr, responseFormat, language) { const modelInfo = await getModelInfo(modelStr); if (!modelInfo.provider) return errorResponse(HTTP_STATUS.BAD_REQUEST, "Invalid model format"); @@ -72,7 +73,7 @@ async function handleSingleModelTts(body, modelStr, responseFormat) { // noAuth providers — no credential needed if (!CREDENTIALED_PROVIDERS.has(provider)) { - const result = await handleTtsCore({ provider, model, input: body.input, responseFormat }); + const result = await handleTtsCore({ provider, model, input: body.input, responseFormat, language }); if (result.success) return result.response; return errorResponse(result.status || HTTP_STATUS.BAD_GATEWAY, result.error || "TTS failed"); } @@ -97,7 +98,7 @@ async function handleSingleModelTts(body, modelStr, responseFormat) { log.info("AUTH", `\x1b[32mUsing ${provider} account: ${credentials.connectionName}\x1b[0m`); - const result = await handleTtsCore({ provider, model, input: body.input, credentials, responseFormat }); + const result = await handleTtsCore({ provider, model, input: body.input, credentials, responseFormat, language }); if (result.success) return result.response; diff --git a/src/store/headerSearchStore.js b/src/store/headerSearchStore.js new file mode 100644 index 00000000..77927873 --- /dev/null +++ b/src/store/headerSearchStore.js @@ -0,0 +1,19 @@ +/** + * Header Search Store — Zustand-based reusable search input in Header. + * Pages register placeholder on mount, read query, unregister on unmount. + */ + +import { create } from "zustand"; + +export const useHeaderSearchStore = create((set) => ({ + query: "", + placeholder: "", + visible: false, + + setQuery: (query) => set({ query }), + + register: (placeholder = "Search...") => + set({ visible: true, placeholder, query: "" }), + + unregister: () => set({ visible: false, placeholder: "", query: "" }), +}));