@fudrouter/fsrouter 0.6.64 → 0.6.66
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/open-sse/AGENTS.md +39 -0
- package/open-sse/config/anthropicHeaders.js +87 -0
- package/open-sse/config/appConstants.js +238 -0
- package/open-sse/config/audioRegistry.js +506 -0
- package/open-sse/config/cliFingerprints.js +304 -0
- package/open-sse/config/codexInstructions.js +119 -0
- package/open-sse/config/codexQuotaScopes.js +42 -0
- package/open-sse/config/constants.js +4 -0
- package/open-sse/config/contextEditing.js +68 -0
- package/open-sse/config/credentialLoader.js +83 -0
- package/open-sse/config/defaultThinkingSignature.js +12 -0
- package/open-sse/config/embeddingRegistry.js +264 -0
- package/open-sse/config/errorConfig.js +96 -0
- package/open-sse/config/freeModelCatalog.data.js +121 -0
- package/open-sse/config/freeModelCatalog.js +90 -0
- package/open-sse/config/freeTierCatalog.js +81 -0
- package/open-sse/config/googleTtsLanguages.js +62 -0
- package/open-sse/config/imageParamDefs.js +360 -0
- package/open-sse/config/imageRegistry.js +493 -0
- package/open-sse/config/kiroConstants.js +268 -0
- package/open-sse/config/mediaConfig.js +27 -0
- package/open-sse/config/mediaServiceKinds.js +71 -0
- package/open-sse/config/models.js +13 -0
- package/open-sse/config/moderationRegistry.js +71 -0
- package/open-sse/config/musicRegistry.js +99 -0
- package/open-sse/config/ocrRegistry.js +61 -0
- package/open-sse/config/ollamaModels.js +19 -0
- package/open-sse/config/providerErrorRules.js +114 -0
- package/open-sse/config/providerFieldStrips.js +35 -0
- package/open-sse/config/providerHeaderProfiles.js +191 -0
- package/open-sse/config/providerModels.js +106 -0
- package/open-sse/config/providerRegistry.js +16 -0
- package/open-sse/config/providers.js +19 -0
- package/open-sse/config/registryUtils.js +106 -0
- package/open-sse/config/rerankRegistry.js +177 -0
- package/open-sse/config/runtimeConfig.js +96 -0
- package/open-sse/config/runway.js +39 -0
- package/open-sse/config/searchRegistry.js +153 -0
- package/open-sse/config/toolCloaking.js +199 -0
- package/open-sse/config/ttsModels.js +129 -0
- package/open-sse/config/videoRegistry.js +207 -0
- package/open-sse/executors/adapta-web.js +435 -0
- package/open-sse/executors/antigravity.js +534 -0
- package/open-sse/executors/antigravityUpstreamError.js +13 -0
- package/open-sse/executors/auggie.js +437 -0
- package/open-sse/executors/azure-openai.js +32 -0
- package/open-sse/executors/azure.js +57 -0
- package/open-sse/executors/base.js +181 -0
- package/open-sse/executors/bedrock.js +633 -0
- package/open-sse/executors/blackbox-web.js +578 -0
- package/open-sse/executors/chatgpt-web.js +2042 -0
- package/open-sse/executors/chipotle.js +357 -0
- package/open-sse/executors/claude-web-with-auto-refresh.js +73 -0
- package/open-sse/executors/claude-web.js +586 -0
- package/open-sse/executors/cliproxyapi.js +296 -0
- package/open-sse/executors/cloudflare-ai.js +46 -0
- package/open-sse/executors/codebuddy-cn.js +40 -0
- package/open-sse/executors/codex.js +1324 -0
- package/open-sse/executors/commandCode.js +558 -0
- package/open-sse/executors/commandcode.js +88 -0
- package/open-sse/executors/copilot-m365-connection.js +176 -0
- package/open-sse/executors/copilot-m365-frames.js +192 -0
- package/open-sse/executors/copilot-m365-web.js +299 -0
- package/open-sse/executors/copilot-web.js +580 -0
- package/open-sse/executors/cursor.js +795 -0
- package/open-sse/executors/deepseek-web-with-auto-refresh.js +150 -0
- package/open-sse/executors/deepseek-web.js +875 -0
- package/open-sse/executors/default.js +430 -0
- package/open-sse/executors/devin-cli.js +351 -0
- package/open-sse/executors/doubao-web.js +550 -0
- package/open-sse/executors/duckduckgo-web.js +629 -0
- package/open-sse/executors/forceResponsesUpstream.js +33 -0
- package/open-sse/executors/gemini-business.js +320 -0
- package/open-sse/executors/gemini-cli.js +89 -0
- package/open-sse/executors/gemini-web.js +297 -0
- package/open-sse/executors/github.js +379 -0
- package/open-sse/executors/gitlab.js +569 -0
- package/open-sse/executors/glm.js +361 -0
- package/open-sse/executors/grok-cli.js +119 -0
- package/open-sse/executors/grok-web.js +345 -0
- package/open-sse/executors/huggingchat.js +467 -0
- package/open-sse/executors/iflow.js +108 -0
- package/open-sse/executors/index.js +78 -0
- package/open-sse/executors/inner-ai.js +527 -0
- package/open-sse/executors/kimchi.js +123 -0
- package/open-sse/executors/kimi-web.js +325 -0
- package/open-sse/executors/kimi.js +97 -0
- package/open-sse/executors/kiro.js +503 -0
- package/open-sse/executors/kiroThinking.js +44 -0
- package/open-sse/executors/lmarena.js +395 -0
- package/open-sse/executors/mimo-free.js +167 -0
- package/open-sse/executors/mimocode.js +392 -0
- package/open-sse/executors/ninerouter.js +155 -0
- package/open-sse/executors/nlpcloud.js +438 -0
- package/open-sse/executors/ollama-local.js +14 -0
- package/open-sse/executors/opencode-go.js +41 -0
- package/open-sse/executors/opencode.js +32 -0
- package/open-sse/executors/perplexity-web.js +581 -0
- package/open-sse/executors/poe-web.js +133 -0
- package/open-sse/executors/pollinations.js +95 -0
- package/open-sse/executors/puter.js +31 -0
- package/open-sse/executors/qoder.js +448 -0
- package/open-sse/executors/qwen-web.js +372 -0
- package/open-sse/executors/qwen.js +129 -0
- package/open-sse/executors/t3-chat-web.js +417 -0
- package/open-sse/executors/theoldllm.js +290 -0
- package/open-sse/executors/trae.js +418 -0
- package/open-sse/executors/v0-vercel-web.js +141 -0
- package/open-sse/executors/venice-web.js +142 -0
- package/open-sse/executors/vertex.js +131 -0
- package/open-sse/executors/vertexMedia.js +236 -0
- package/open-sse/executors/windsurf.js +560 -0
- package/open-sse/executors/xai.js +46 -0
- package/open-sse/executors/xiaomi-tokenplan.js +19 -0
- package/open-sse/executors/yuanbao-web.js +385 -0
- package/open-sse/executors/zed-hosted.js +281 -0
- package/open-sse/executors/zenmux-free.js +247 -0
- package/open-sse/handlers/audioSpeech.js +759 -0
- package/open-sse/handlers/audioTranscription.js +395 -0
- package/open-sse/handlers/audioTranslation.js +181 -0
- package/open-sse/handlers/chatCore/nonStreamingHandler.js +300 -0
- package/open-sse/handlers/chatCore/requestDetail.js +102 -0
- package/open-sse/handlers/chatCore/sseToJsonHandler.js +231 -0
- package/open-sse/handlers/chatCore/streamingHandler.js +95 -0
- package/open-sse/handlers/chatCore.js +404 -0
- package/open-sse/handlers/embeddingProviders/_base.js +4 -0
- package/open-sse/handlers/embeddingProviders/gemini.js +54 -0
- package/open-sse/handlers/embeddingProviders/index.js +23 -0
- package/open-sse/handlers/embeddingProviders/openai.js +39 -0
- package/open-sse/handlers/embeddingProviders/openaiCompatNode.js +13 -0
- package/open-sse/handlers/embeddingsCore.js +126 -0
- package/open-sse/handlers/fetch/index.js +237 -0
- package/open-sse/handlers/imageGenerationCore.js +230 -0
- package/open-sse/handlers/imageProviders/_base.js +31 -0
- package/open-sse/handlers/imageProviders/antigravity.js +73 -0
- package/open-sse/handlers/imageProviders/blackForestLabs.js +63 -0
- package/open-sse/handlers/imageProviders/cloudflareAi.js +207 -0
- package/open-sse/handlers/imageProviders/codex.js +217 -0
- package/open-sse/handlers/imageProviders/comfyui.js +25 -0
- package/open-sse/handlers/imageProviders/falAi.js +62 -0
- package/open-sse/handlers/imageProviders/gemini.js +40 -0
- package/open-sse/handlers/imageProviders/huggingface.js +38 -0
- package/open-sse/handlers/imageProviders/index.js +44 -0
- package/open-sse/handlers/imageProviders/leonardo.js +435 -0
- package/open-sse/handlers/imageProviders/nanobanana.js +79 -0
- package/open-sse/handlers/imageProviders/openai.js +61 -0
- package/open-sse/handlers/imageProviders/runwayml.js +72 -0
- package/open-sse/handlers/imageProviders/sdwebui.js +36 -0
- package/open-sse/handlers/imageProviders/stabilityAi.js +59 -0
- package/open-sse/handlers/imageProviders/weavy.js +222 -0
- package/open-sse/handlers/moderations.js +92 -0
- package/open-sse/handlers/ocr.js +89 -0
- package/open-sse/handlers/rerank.js +223 -0
- package/open-sse/handlers/responseSanitizer/reasoning.js +144 -0
- package/open-sse/handlers/responsesHandler.js +99 -0
- package/open-sse/handlers/search/callers.js +371 -0
- package/open-sse/handlers/search/chatSearch.js +409 -0
- package/open-sse/handlers/search/index.js +201 -0
- package/open-sse/handlers/search/normalizers.js +223 -0
- package/open-sse/handlers/search.js +1056 -0
- package/open-sse/handlers/sseParser.js +469 -0
- package/open-sse/handlers/sttCore.js +193 -0
- package/open-sse/handlers/ttsCore.js +74 -0
- package/open-sse/handlers/ttsProviders/_base.js +39 -0
- package/open-sse/handlers/ttsProviders/edgeTts.js +89 -0
- package/open-sse/handlers/ttsProviders/elevenlabs.js +48 -0
- package/open-sse/handlers/ttsProviders/gemini.js +117 -0
- package/open-sse/handlers/ttsProviders/genericFormats.js +169 -0
- package/open-sse/handlers/ttsProviders/googleTts.js +54 -0
- package/open-sse/handlers/ttsProviders/index.js +50 -0
- package/open-sse/handlers/ttsProviders/localDevice.js +87 -0
- package/open-sse/handlers/ttsProviders/minimax.js +59 -0
- package/open-sse/handlers/ttsProviders/openai.js +30 -0
- package/open-sse/handlers/ttsProviders/openrouter.js +70 -0
- package/open-sse/handlers/usageExtractor.js +93 -0
- package/open-sse/handlers/videoGenerationCore.js +119 -0
- package/open-sse/handlers/videoProviders/index.js +22 -0
- package/open-sse/handlers/videoProviders/leonardo.js +511 -0
- package/open-sse/handlers/videoProviders/weavy.js +198 -0
- package/open-sse/handlers/webFetch.js +200 -0
- package/open-sse/index.js +79 -0
- package/open-sse/mcp-server/audit.js +283 -0
- package/open-sse/mcp-server/catalog.js +184 -0
- package/open-sse/mcp-server/descriptionCompressor.js +175 -0
- package/open-sse/mcp-server/httpAuthContext.js +32 -0
- package/open-sse/mcp-server/httpTransport.js +229 -0
- package/open-sse/mcp-server/index.js +33 -0
- package/open-sse/mcp-server/mcpCallerIdentity.js +21 -0
- package/open-sse/mcp-server/runtimeHeartbeat.js +110 -0
- package/open-sse/mcp-server/schemas/a2a.js +153 -0
- package/open-sse/mcp-server/schemas/audit.js +17 -0
- package/open-sse/mcp-server/schemas/index.js +166 -0
- package/open-sse/mcp-server/schemas/pickFastestModel.js +90 -0
- package/open-sse/mcp-server/schemas/toolDefinition.js +0 -0
- package/open-sse/mcp-server/schemas/toolSearch.js +32 -0
- package/open-sse/mcp-server/schemas/tools.js +1219 -0
- package/open-sse/mcp-server/scopeEnforcement.js +80 -0
- package/open-sse/mcp-server/server.js +1168 -0
- package/open-sse/mcp-server/toolCardinality.js +78 -0
- package/open-sse/mcp-server/toolSearch/catalog.js +66 -0
- package/open-sse/mcp-server/toolSearch/handler.js +20 -0
- package/open-sse/mcp-server/toolSearch/index.js +10 -0
- package/open-sse/mcp-server/toolSearch/register.js +21 -0
- package/open-sse/mcp-server/toolSearch/search.js +55 -0
- package/open-sse/mcp-server/toolSearch/signature.js +67 -0
- package/open-sse/mcp-server/tools/advancedTools.js +893 -0
- package/open-sse/mcp-server/tools/agentSkillTools.js +69 -0
- package/open-sse/mcp-server/tools/compressionTools.js +309 -0
- package/open-sse/mcp-server/tools/gamificationTools.js +134 -0
- package/open-sse/mcp-server/tools/githubSkillTools.js +102 -0
- package/open-sse/mcp-server/tools/memoryTools.js +118 -0
- package/open-sse/mcp-server/tools/notionTools.js +101 -0
- package/open-sse/mcp-server/tools/obsidianTools.js +307 -0
- package/open-sse/mcp-server/tools/pickFastestModel.js +223 -0
- package/open-sse/mcp-server/tools/pluginTools.js +181 -0
- package/open-sse/mcp-server/tools/poolTools.js +139 -0
- package/open-sse/mcp-server/tools/skillTools.js +113 -0
- package/open-sse/package.json +10 -0
- package/open-sse/providers/REGISTRY_TEMPLATE.js +98 -0
- package/open-sse/providers/capabilities.js +293 -0
- package/open-sse/providers/index.js +51 -0
- package/open-sse/providers/models/helpers.js +20 -0
- package/open-sse/providers/models/namePatterns.js +33 -0
- package/open-sse/providers/models/schema.js +40 -0
- package/open-sse/providers/pricing.js +308 -0
- package/open-sse/providers/registry/alicode-intl.js +30 -0
- package/open-sse/providers/registry/alicode.js +31 -0
- package/open-sse/providers/registry/anthropic.js +37 -0
- package/open-sse/providers/registry/antigravity.js +81 -0
- package/open-sse/providers/registry/assemblyai.js +38 -0
- package/open-sse/providers/registry/aws-polly.js +45 -0
- package/open-sse/providers/registry/azure.js +21 -0
- package/open-sse/providers/registry/black-forest-labs.js +32 -0
- package/open-sse/providers/registry/blackbox.js +41 -0
- package/open-sse/providers/registry/brave-search.js +35 -0
- package/open-sse/providers/registry/byteplus.js +35 -0
- package/open-sse/providers/registry/cartesia.js +36 -0
- package/open-sse/providers/registry/cerebras.js +31 -0
- package/open-sse/providers/registry/chutes.js +24 -0
- package/open-sse/providers/registry/claude.js +87 -0
- package/open-sse/providers/registry/cline.js +51 -0
- package/open-sse/providers/registry/clinepass.js +57 -0
- package/open-sse/providers/registry/cloudflare-ai.js +55 -0
- package/open-sse/providers/registry/codebuddy-cn.js +77 -0
- package/open-sse/providers/registry/codex.js +100 -0
- package/open-sse/providers/registry/cohere.js +27 -0
- package/open-sse/providers/registry/comfyui.js +20 -0
- package/open-sse/providers/registry/commandcode.js +43 -0
- package/open-sse/providers/registry/coqui.js +30 -0
- package/open-sse/providers/registry/cursor.js +58 -0
- package/open-sse/providers/registry/deepgram.js +33 -0
- package/open-sse/providers/registry/deepseek.js +51 -0
- package/open-sse/providers/registry/digitalocean.js +92 -0
- package/open-sse/providers/registry/edge-tts.js +24 -0
- package/open-sse/providers/registry/elevenlabs.js +35 -0
- package/open-sse/providers/registry/exa.js +50 -0
- package/open-sse/providers/registry/fal-ai.js +34 -0
- package/open-sse/providers/registry/featherless.js +34 -0
- package/open-sse/providers/registry/firecrawl.js +34 -0
- package/open-sse/providers/registry/fireworks.js +29 -0
- package/open-sse/providers/registry/gemini-cli.js +58 -0
- package/open-sse/providers/registry/gemini.js +83 -0
- package/open-sse/providers/registry/github.js +88 -0
- package/open-sse/providers/registry/gitlab.js +32 -0
- package/open-sse/providers/registry/glm-cn.js +35 -0
- package/open-sse/providers/registry/glm.js +58 -0
- package/open-sse/providers/registry/google-pse.js +35 -0
- package/open-sse/providers/registry/google-tts.js +24 -0
- package/open-sse/providers/registry/grok-cli.js +86 -0
- package/open-sse/providers/registry/grok-web.js +39 -0
- package/open-sse/providers/registry/groq.js +37 -0
- package/open-sse/providers/registry/huggingface.js +34 -0
- package/open-sse/providers/registry/hyperbolic.js +35 -0
- package/open-sse/providers/registry/ibm-bob.js +27 -0
- package/open-sse/providers/registry/iflow.js +52 -0
- package/open-sse/providers/registry/index.js +210 -0
- package/open-sse/providers/registry/inworld.js +36 -0
- package/open-sse/providers/registry/jina-ai.js +42 -0
- package/open-sse/providers/registry/jina-reader.js +34 -0
- package/open-sse/providers/registry/kilocode.js +51 -0
- package/open-sse/providers/registry/kimchi.js +49 -0
- package/open-sse/providers/registry/kimi-coding.js +65 -0
- package/open-sse/providers/registry/kimi.js +56 -0
- package/open-sse/providers/registry/kiro.js +115 -0
- package/open-sse/providers/registry/linkup.js +34 -0
- package/open-sse/providers/registry/local-device.js +24 -0
- package/open-sse/providers/registry/mimo-free.js +24 -0
- package/open-sse/providers/registry/minimax-cn.js +76 -0
- package/open-sse/providers/registry/minimax.js +83 -0
- package/open-sse/providers/registry/mistral.js +34 -0
- package/open-sse/providers/registry/mmf.js +19 -0
- package/open-sse/providers/registry/nanobanana.js +35 -0
- package/open-sse/providers/registry/nebius.js +27 -0
- package/open-sse/providers/registry/nvidia.js +43 -0
- package/open-sse/providers/registry/ollama-local.js +19 -0
- package/open-sse/providers/registry/ollama.js +36 -0
- package/open-sse/providers/registry/openai.js +84 -0
- package/open-sse/providers/registry/opencode-go.js +41 -0
- package/open-sse/providers/registry/opencode.js +25 -0
- package/open-sse/providers/registry/openrouter.js +60 -0
- package/open-sse/providers/registry/perplexity-agent.js +49 -0
- package/open-sse/providers/registry/perplexity-web.js +33 -0
- package/open-sse/providers/registry/perplexity.js +37 -0
- package/open-sse/providers/registry/playht.js +36 -0
- package/open-sse/providers/registry/qoder.js +54 -0
- package/open-sse/providers/registry/qwen.js +33 -0
- package/open-sse/providers/registry/recraft.js +24 -0
- package/open-sse/providers/registry/runwayml.js +30 -0
- package/open-sse/providers/registry/sdwebui.js +20 -0
- package/open-sse/providers/registry/searchapi.js +35 -0
- package/open-sse/providers/registry/searxng.js +35 -0
- package/open-sse/providers/registry/serper.js +35 -0
- package/open-sse/providers/registry/siliconflow.js +39 -0
- package/open-sse/providers/registry/stability-ai.js +31 -0
- package/open-sse/providers/registry/tavily.js +50 -0
- package/open-sse/providers/registry/together.js +31 -0
- package/open-sse/providers/registry/topaz.js +19 -0
- package/open-sse/providers/registry/tortoise.js +30 -0
- package/open-sse/providers/registry/venice.js +56 -0
- package/open-sse/providers/registry/vercel-ai-gateway.js +41 -0
- package/open-sse/providers/registry/vertex-partner.js +29 -0
- package/open-sse/providers/registry/vertex.js +32 -0
- package/open-sse/providers/registry/volcengine-ark.js +35 -0
- package/open-sse/providers/registry/voyage-ai.js +30 -0
- package/open-sse/providers/registry/xai.js +45 -0
- package/open-sse/providers/registry/xiaomi-mimo.js +46 -0
- package/open-sse/providers/registry/xiaomi-tokenplan.js +63 -0
- package/open-sse/providers/registry/youcom.js +35 -0
- package/open-sse/providers/schema.js +76 -0
- package/open-sse/providers/shared.js +74 -0
- package/open-sse/providers/thinkingLevels.js +48 -0
- package/open-sse/rtk/applyFilter.js +15 -0
- package/open-sse/rtk/autodetect.js +111 -0
- package/open-sse/rtk/caveman.js +100 -0
- package/open-sse/rtk/cavemanPrompts.js +78 -0
- package/open-sse/rtk/constants.js +55 -0
- package/open-sse/rtk/filters/buildOutput.js +127 -0
- package/open-sse/rtk/filters/dedupLog.js +44 -0
- package/open-sse/rtk/filters/find.js +50 -0
- package/open-sse/rtk/filters/gitDiff.js +92 -0
- package/open-sse/rtk/filters/gitLog.js +99 -0
- package/open-sse/rtk/filters/gitStatus.js +117 -0
- package/open-sse/rtk/filters/grep.js +48 -0
- package/open-sse/rtk/filters/ls.js +79 -0
- package/open-sse/rtk/filters/readNumbered.js +27 -0
- package/open-sse/rtk/filters/searchList.js +52 -0
- package/open-sse/rtk/filters/smartTruncate.js +15 -0
- package/open-sse/rtk/filters/tree.js +32 -0
- package/open-sse/rtk/headroom.js +215 -0
- package/open-sse/rtk/index.js +155 -0
- package/open-sse/rtk/paleo.js +47 -0
- package/open-sse/rtk/ponytail.js +9 -0
- package/open-sse/rtk/ponytailPrompt.js +52 -0
- package/open-sse/rtk/ponytailPrompts.js +76 -0
- package/open-sse/rtk/pxpipe.js +104 -0
- package/open-sse/rtk/registry.js +38 -0
- package/open-sse/rtk/systemInject.js +98 -0
- package/open-sse/services/accountFallback.js +323 -0
- package/open-sse/services/antigravityHeaders.js +91 -0
- package/open-sse/services/antigravityVersion.js +154 -0
- package/open-sse/services/clinepassModels.js +63 -0
- package/open-sse/services/codexQuotaFetcher.js +312 -0
- package/open-sse/services/codexVerbosity.js +30 -0
- package/open-sse/services/combo/context.js +12 -0
- package/open-sse/services/combo/fingerprintExpansion.js +51 -0
- package/open-sse/services/combo/headroomRanking.js +28 -0
- package/open-sse/services/combo/quotaExhaustionCutoff.js +87 -0
- package/open-sse/services/combo/quotaScoring.js +226 -0
- package/open-sse/services/combo/quotaShareConcurrency.js +25 -0
- package/open-sse/services/combo/quotaShareInflight.js +50 -0
- package/open-sse/services/combo/quotaShareStrategy.js +130 -0
- package/open-sse/services/combo/resolveAutoStrategy.js +231 -0
- package/open-sse/services/combo/responseValidation.js +140 -0
- package/open-sse/services/combo/runtimeUnits.js +195 -0
- package/open-sse/services/combo/sessionStickiness.js +128 -0
- package/open-sse/services/combo/shadowRouting.js +131 -0
- package/open-sse/services/combo/targetExhaustion.js +75 -0
- package/open-sse/services/combo/targetSorters.js +126 -0
- package/open-sse/services/combo/targetTimeoutRunner.js +65 -0
- package/open-sse/services/combo/validateQuality.js +271 -0
- package/open-sse/services/combo.js +571 -0
- package/open-sse/services/comboAgentMiddleware.js +91 -0
- package/open-sse/services/comboConfig.js +153 -0
- package/open-sse/services/comboManifestMetrics.js +10 -0
- package/open-sse/services/comboMetrics.js +278 -0
- package/open-sse/services/compact.js +71 -0
- package/open-sse/services/copilotModels.js +155 -0
- package/open-sse/services/emergencyFallback.js +109 -0
- package/open-sse/services/errorClassifier.js +190 -0
- package/open-sse/services/evalRouting.js +201 -0
- package/open-sse/services/freeWebSearch.js +4 -0
- package/open-sse/services/fusion.js +223 -0
- package/open-sse/services/intentClassifier.js +631 -0
- package/open-sse/services/kimchiModels.js +176 -0
- package/open-sse/services/kiroModels.js +332 -0
- package/open-sse/services/model.js +136 -0
- package/open-sse/services/modelCapabilities.js +5 -0
- package/open-sse/services/modelDeprecation.js +101 -0
- package/open-sse/services/modelFamilyFallback.js +166 -0
- package/open-sse/services/oauthCredentialManager.js +156 -0
- package/open-sse/services/pipeline.js +107 -0
- package/open-sse/services/projectId.js +306 -0
- package/open-sse/services/provider.js +169 -0
- package/open-sse/services/providerCooldownTracker.js +94 -0
- package/open-sse/services/providerDefaultRateLimit.js +11 -0
- package/open-sse/services/proxyAutoSelector.js +24 -0
- package/open-sse/services/qoderModels.js +214 -0
- package/open-sse/services/quotaFetchThrottle.js +103 -0
- package/open-sse/services/quotaMonitor.js +310 -0
- package/open-sse/services/quotaPreflight.js +266 -0
- package/open-sse/services/rateLimitManager/headers.js +56 -0
- package/open-sse/services/rateLimitManager.js +616 -0
- package/open-sse/services/rateLimitSemaphore.js +112 -0
- package/open-sse/services/responsesInputSanitizer.js +99 -0
- package/open-sse/services/slidingWindowLimiter.js +44 -0
- package/open-sse/services/streamRecovery.js +355 -0
- package/open-sse/services/taskAwareRouter.js +227 -0
- package/open-sse/services/taskAwareRouting.js +332 -0
- package/open-sse/services/thinkingBudget.js +247 -0
- package/open-sse/services/tokenRefresh/dedup.js +31 -0
- package/open-sse/services/tokenRefresh/providers.js +624 -0
- package/open-sse/services/tokenRefresh.js +254 -0
- package/open-sse/services/usage/claude.js +147 -0
- package/open-sse/services/usage/codebuddy-cn.js +138 -0
- package/open-sse/services/usage/codex.js +267 -0
- package/open-sse/services/usage/github.js +100 -0
- package/open-sse/services/usage/google.js +241 -0
- package/open-sse/services/usage/grok-cli.js +274 -0
- package/open-sse/services/usage/kiro.js +188 -0
- package/open-sse/services/usage/minimax.js +234 -0
- package/open-sse/services/usage/misc.js +288 -0
- package/open-sse/services/usage/shared.js +70 -0
- package/open-sse/services/usage.js +62 -0
- package/open-sse/services/usageDb.js +2 -0
- package/open-sse/services/webSearchRouting.js +25 -0
- package/open-sse/services/wildcardRouter.js +59 -0
- package/open-sse/shared/clineAuth.js +37 -0
- package/open-sse/shared/machineId.js +19 -0
- package/open-sse/shared/qoder/constants.js +64 -0
- package/open-sse/shared/qoder/cosy.js +175 -0
- package/open-sse/shared/qoder/encoding.js +55 -0
- package/open-sse/transformer/responsesTransformer.js +439 -0
- package/open-sse/transformer/streamToJsonConverter.js +103 -0
- package/open-sse/translator/concerns/chunk.js +11 -0
- package/open-sse/translator/concerns/finishReason.js +63 -0
- package/open-sse/translator/concerns/image.js +124 -0
- package/open-sse/translator/concerns/json.js +5 -0
- package/open-sse/translator/concerns/message.js +7 -0
- package/open-sse/translator/concerns/modality.js +155 -0
- package/open-sse/translator/concerns/paramSupport.js +75 -0
- package/open-sse/translator/concerns/prefetch.js +96 -0
- package/open-sse/translator/concerns/reasoning.js +24 -0
- package/open-sse/translator/concerns/thinking.js +53 -0
- package/open-sse/translator/concerns/thinkingUnified.js +329 -0
- package/open-sse/translator/concerns/toolCall.js +153 -0
- package/open-sse/translator/concerns/usage.js +69 -0
- package/open-sse/translator/formats/claude.js +368 -0
- package/open-sse/translator/formats/gemini.js +380 -0
- package/open-sse/translator/formats/maxTokens.js +34 -0
- package/open-sse/translator/formats/openai.js +134 -0
- package/open-sse/translator/formats/responsesApi.js +141 -0
- package/open-sse/translator/formats.js +36 -0
- package/open-sse/translator/helpers/claudeHelper.js +216 -0
- package/open-sse/translator/helpers/geminiHelper.js +372 -0
- package/open-sse/translator/helpers/imageHelper.js +34 -0
- package/open-sse/translator/helpers/maxTokensHelper.js +27 -0
- package/open-sse/translator/helpers/openaiHelper.js +130 -0
- package/open-sse/translator/helpers/responsesApiHelper.js +139 -0
- package/open-sse/translator/helpers/toolCallHelper.js +148 -0
- package/open-sse/translator/index.js +252 -0
- package/open-sse/translator/request/antigravity-to-openai.js +242 -0
- package/open-sse/translator/request/claude-to-kiro.js +478 -0
- package/open-sse/translator/request/claude-to-openai.js +263 -0
- package/open-sse/translator/request/gemini-to-openai.js +152 -0
- package/open-sse/translator/request/openai-responses.js +385 -0
- package/open-sse/translator/request/openai-to-claude.js +383 -0
- package/open-sse/translator/request/openai-to-commandcode.js +176 -0
- package/open-sse/translator/request/openai-to-cursor.js +185 -0
- package/open-sse/translator/request/openai-to-gemini.js +442 -0
- package/open-sse/translator/request/openai-to-kiro.js +607 -0
- package/open-sse/translator/request/openai-to-kiro.old.js +278 -0
- package/open-sse/translator/request/openai-to-ollama.js +195 -0
- package/open-sse/translator/request/openai-to-vertex.js +42 -0
- package/open-sse/translator/response/claude-to-openai.js +195 -0
- package/open-sse/translator/response/commandcode-to-openai.js +188 -0
- package/open-sse/translator/response/cursor-to-openai.js +30 -0
- package/open-sse/translator/response/gemini-to-openai.js +147 -0
- package/open-sse/translator/response/kiro-to-claude.js +261 -0
- package/open-sse/translator/response/kiro-to-openai.js +160 -0
- package/open-sse/translator/response/ollama-to-openai.js +134 -0
- package/open-sse/translator/response/openai-responses.js +535 -0
- package/open-sse/translator/response/openai-to-antigravity.js +123 -0
- package/open-sse/translator/response/openai-to-claude.js +265 -0
- package/open-sse/translator/schema/blocks.js +43 -0
- package/open-sse/translator/schema/defaults.js +7 -0
- package/open-sse/translator/schema/finishReasons.js +27 -0
- package/open-sse/translator/schema/index.js +8 -0
- package/open-sse/translator/schema/roles.js +16 -0
- package/open-sse/utils/agentGoalPolicy.js +85 -0
- package/open-sse/utils/aiSdkCompat.js +75 -0
- package/open-sse/utils/bypassHandler.js +298 -0
- package/open-sse/utils/cacheControlPolicy.js +189 -0
- package/open-sse/utils/claudeCloaking.js +155 -0
- package/open-sse/utils/claudeHeaderCache.js +70 -0
- package/open-sse/utils/claudeSignature.js +41 -0
- package/open-sse/utils/clientDetector.js +63 -0
- package/open-sse/utils/codebuddySanitizer.js +96 -0
- package/open-sse/utils/composerToolCalls.js +158 -0
- package/open-sse/utils/cors.js +13 -0
- package/open-sse/utils/cursorChecksum.js +149 -0
- package/open-sse/utils/cursorImages.js +224 -0
- package/open-sse/utils/cursorProtobuf.js +904 -0
- package/open-sse/utils/cursorVersionDetector.js +55 -0
- package/open-sse/utils/debugLog.js +14 -0
- package/open-sse/utils/diagnostics.js +143 -0
- package/open-sse/utils/error.js +164 -0
- package/open-sse/utils/estimateSize.js +33 -0
- package/open-sse/utils/finishReason.js +32 -0
- package/open-sse/utils/flattenToolHistory.js +68 -0
- package/open-sse/utils/headers.js +36 -0
- package/open-sse/utils/heapPressure.js +35 -0
- package/open-sse/utils/jsonToSse.js +125 -0
- package/open-sse/utils/keepaliveThreshold.js +40 -0
- package/open-sse/utils/logger.js +104 -0
- package/open-sse/utils/noThinkingAlias.js +74 -0
- package/open-sse/utils/number.js +7 -0
- package/open-sse/utils/ollamaTransform.js +85 -0
- package/open-sse/utils/opencodeHeaders.js +47 -0
- package/open-sse/utils/progressTracker.js +81 -0
- package/open-sse/utils/providerRequestLogging.js +219 -0
- package/open-sse/utils/proxyFetch.js +369 -0
- package/open-sse/utils/reasoningContentInjector.js +79 -0
- package/open-sse/utils/reasoningFields.js +70 -0
- package/open-sse/utils/requestLogger.js +260 -0
- package/open-sse/utils/responsesInputNormalization.js +92 -0
- package/open-sse/utils/responsesStatePolicy.js +52 -0
- package/open-sse/utils/responsesStreamHelpers.js +49 -0
- package/open-sse/utils/sessionManager.js +240 -0
- package/open-sse/utils/sleep.js +6 -0
- package/open-sse/utils/sse.js +14 -0
- package/open-sse/utils/sseConstants.js +23 -0
- package/open-sse/utils/sseHeartbeat.js +104 -0
- package/open-sse/utils/stream.js +517 -0
- package/open-sse/utils/streamFailureFinalization.js +134 -0
- package/open-sse/utils/streamHandler.js +250 -0
- package/open-sse/utils/streamHelpers.js +137 -0
- package/open-sse/utils/textualToolCall.js +104 -0
- package/open-sse/utils/thinkCloseMarker.js +72 -0
- package/open-sse/utils/thinkTagParser.js +146 -0
- package/open-sse/utils/toolCallArguments.js +12 -0
- package/open-sse/utils/toolDeduper.js +49 -0
- package/open-sse/utils/toolSources.js +31 -0
- package/open-sse/utils/upstreamResponseHeaders.js +25 -0
- package/open-sse/utils/urlSanitize.js +15 -0
- package/open-sse/utils/usageTracking.js +347 -0
- package/package.json +1 -1
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import { ERROR_RULES, BACKOFF_CONFIG, TRANSIENT_COOLDOWN_MS } from "../config/errorConfig.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Calculate exponential backoff cooldown for rate limits (429)
|
|
5
|
+
* Level 1: 1s, Level 2: 2s, Level 3: 4s... → max 4 min
|
|
6
|
+
* @param {number} backoffLevel - Current backoff level
|
|
7
|
+
* @returns {number} Cooldown in milliseconds
|
|
8
|
+
*/
|
|
9
|
+
export function getQuotaCooldown(backoffLevel = 0) {
|
|
10
|
+
const level = Math.max(0, backoffLevel - 1);
|
|
11
|
+
const cooldown = BACKOFF_CONFIG.base * Math.pow(2, level);
|
|
12
|
+
return Math.min(cooldown, BACKOFF_CONFIG.max);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Check if error should trigger account fallback (switch to next account)
|
|
17
|
+
* Config-driven: matches ERROR_RULES top-to-bottom (text rules first, then status)
|
|
18
|
+
* @param {number} status - HTTP status code
|
|
19
|
+
* @param {string} errorText - Error message text
|
|
20
|
+
* @param {number} backoffLevel - Current backoff level for exponential backoff
|
|
21
|
+
* @returns {{ shouldFallback: boolean, cooldownMs: number, newBackoffLevel?: number }}
|
|
22
|
+
*/
|
|
23
|
+
export function checkFallbackError(status, errorText, backoffLevel = 0) {
|
|
24
|
+
const lowerError = errorText
|
|
25
|
+
? (typeof errorText === "string" ? errorText : JSON.stringify(errorText)).toLowerCase()
|
|
26
|
+
: "";
|
|
27
|
+
|
|
28
|
+
for (const rule of ERROR_RULES) {
|
|
29
|
+
// Text-based rule: match substring in error message
|
|
30
|
+
if (rule.text && lowerError && lowerError.includes(rule.text)) {
|
|
31
|
+
if (rule.backoff) {
|
|
32
|
+
const newLevel = Math.min(backoffLevel + 1, BACKOFF_CONFIG.maxLevel);
|
|
33
|
+
return { shouldFallback: true, cooldownMs: getQuotaCooldown(newLevel), newBackoffLevel: newLevel };
|
|
34
|
+
}
|
|
35
|
+
return { shouldFallback: true, cooldownMs: rule.cooldownMs };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Status-based rule: match HTTP status code
|
|
39
|
+
if (rule.status && rule.status === status) {
|
|
40
|
+
if (rule.backoff) {
|
|
41
|
+
const newLevel = Math.min(backoffLevel + 1, BACKOFF_CONFIG.maxLevel);
|
|
42
|
+
return { shouldFallback: true, cooldownMs: getQuotaCooldown(newLevel), newBackoffLevel: newLevel };
|
|
43
|
+
}
|
|
44
|
+
return { shouldFallback: true, cooldownMs: rule.cooldownMs };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Default: transient cooldown for any unmatched error
|
|
49
|
+
return { shouldFallback: true, cooldownMs: TRANSIENT_COOLDOWN_MS };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Check if account is currently unavailable (cooldown not expired)
|
|
54
|
+
*/
|
|
55
|
+
export function isAccountUnavailable(unavailableUntil) {
|
|
56
|
+
if (!unavailableUntil) return false;
|
|
57
|
+
return new Date(unavailableUntil).getTime() > Date.now();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Calculate unavailable until timestamp
|
|
62
|
+
*/
|
|
63
|
+
export function getUnavailableUntil(cooldownMs) {
|
|
64
|
+
return new Date(Date.now() + cooldownMs).toISOString();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Get the earliest rateLimitedUntil from a list of accounts
|
|
69
|
+
* @param {Array} accounts - Array of account objects with rateLimitedUntil
|
|
70
|
+
* @returns {string|null} Earliest rateLimitedUntil ISO string, or null
|
|
71
|
+
*/
|
|
72
|
+
export function getEarliestRateLimitedUntil(accounts) {
|
|
73
|
+
let earliest = null;
|
|
74
|
+
const now = Date.now();
|
|
75
|
+
for (const acc of accounts) {
|
|
76
|
+
if (!acc.rateLimitedUntil) continue;
|
|
77
|
+
const until = new Date(acc.rateLimitedUntil).getTime();
|
|
78
|
+
if (until <= now) continue;
|
|
79
|
+
if (!earliest || until < earliest) earliest = until;
|
|
80
|
+
}
|
|
81
|
+
if (!earliest) return null;
|
|
82
|
+
return new Date(earliest).toISOString();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Format rateLimitedUntil to human-readable "reset after Xm Ys"
|
|
87
|
+
* @param {string} rateLimitedUntil - ISO timestamp
|
|
88
|
+
* @returns {string} e.g. "reset after 2m 30s"
|
|
89
|
+
*/
|
|
90
|
+
export function formatRetryAfter(rateLimitedUntil) {
|
|
91
|
+
if (!rateLimitedUntil) return "";
|
|
92
|
+
const diffMs = new Date(rateLimitedUntil).getTime() - Date.now();
|
|
93
|
+
if (diffMs <= 0) return "reset after 0s";
|
|
94
|
+
const totalSec = Math.ceil(diffMs / 1000);
|
|
95
|
+
const h = Math.floor(totalSec / 3600);
|
|
96
|
+
const m = Math.floor((totalSec % 3600) / 60);
|
|
97
|
+
const s = totalSec % 60;
|
|
98
|
+
const parts = [];
|
|
99
|
+
if (h > 0) parts.push(`${h}h`);
|
|
100
|
+
if (m > 0) parts.push(`${m}m`);
|
|
101
|
+
if (s > 0 || parts.length === 0) parts.push(`${s}s`);
|
|
102
|
+
return `reset after ${parts.join(" ")}`;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Prefix for model lock flat fields on connection record */
|
|
106
|
+
export const MODEL_LOCK_PREFIX = "modelLock_";
|
|
107
|
+
|
|
108
|
+
/** Special key used when no model is known (account-level lock) */
|
|
109
|
+
export const MODEL_LOCK_ALL = `${MODEL_LOCK_PREFIX}__all`;
|
|
110
|
+
|
|
111
|
+
/** Build the flat field key for a model lock */
|
|
112
|
+
export function getModelLockKey(model) {
|
|
113
|
+
return model ? `${MODEL_LOCK_PREFIX}${model}` : MODEL_LOCK_ALL;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Check if a model lock on a connection is still active.
|
|
118
|
+
* Reads flat field `modelLock_${model}` (or `modelLock___all` when model=null).
|
|
119
|
+
*/
|
|
120
|
+
export function isModelLockActive(connection, model) {
|
|
121
|
+
const key = getModelLockKey(model);
|
|
122
|
+
const expiry = connection[key] || connection[MODEL_LOCK_ALL];
|
|
123
|
+
if (!expiry) return false;
|
|
124
|
+
return new Date(expiry).getTime() > Date.now();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Get earliest active model lock expiry across all modelLock_* fields.
|
|
129
|
+
* Used for UI cooldown display.
|
|
130
|
+
*/
|
|
131
|
+
export function getEarliestModelLockUntil(connection) {
|
|
132
|
+
if (!connection) return null;
|
|
133
|
+
let earliest = null;
|
|
134
|
+
const now = Date.now();
|
|
135
|
+
for (const [key, val] of Object.entries(connection)) {
|
|
136
|
+
if (!key.startsWith(MODEL_LOCK_PREFIX) || !val) continue;
|
|
137
|
+
const t = new Date(val).getTime();
|
|
138
|
+
if (t <= now) continue;
|
|
139
|
+
if (!earliest || t < earliest) earliest = t;
|
|
140
|
+
}
|
|
141
|
+
return earliest ? new Date(earliest).toISOString() : null;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Build update object to set a model lock on a connection.
|
|
146
|
+
*/
|
|
147
|
+
export function buildModelLockUpdate(model, cooldownMs) {
|
|
148
|
+
const key = getModelLockKey(model);
|
|
149
|
+
return { [key]: new Date(Date.now() + cooldownMs).toISOString() };
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Build update object to clear all model locks on a connection.
|
|
154
|
+
*/
|
|
155
|
+
export function buildClearModelLocksUpdate(connection) {
|
|
156
|
+
const cleared = {};
|
|
157
|
+
for (const key of Object.keys(connection)) {
|
|
158
|
+
if (key.startsWith(MODEL_LOCK_PREFIX)) cleared[key] = null;
|
|
159
|
+
}
|
|
160
|
+
return cleared;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Filter available accounts (not in cooldown)
|
|
165
|
+
*/
|
|
166
|
+
export function filterAvailableAccounts(accounts, excludeId = null) {
|
|
167
|
+
const now = Date.now();
|
|
168
|
+
return accounts.filter(acc => {
|
|
169
|
+
if (excludeId && acc.id === excludeId) return false;
|
|
170
|
+
if (acc.rateLimitedUntil) {
|
|
171
|
+
const until = new Date(acc.rateLimitedUntil).getTime();
|
|
172
|
+
if (until > now) return false;
|
|
173
|
+
}
|
|
174
|
+
return true;
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Reset account state when request succeeds
|
|
180
|
+
* Clears cooldown and resets backoff level to 0
|
|
181
|
+
* @param {object} account - Account object
|
|
182
|
+
* @returns {object} Updated account with reset state
|
|
183
|
+
*/
|
|
184
|
+
export function resetAccountState(account) {
|
|
185
|
+
if (!account) return account;
|
|
186
|
+
return {
|
|
187
|
+
...account,
|
|
188
|
+
rateLimitedUntil: null,
|
|
189
|
+
backoffLevel: 0,
|
|
190
|
+
lastError: null,
|
|
191
|
+
status: "active"
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Apply error state to account
|
|
197
|
+
* @param {object} account - Account object
|
|
198
|
+
* @param {number} status - HTTP status code
|
|
199
|
+
* @param {string} errorText - Error message
|
|
200
|
+
* @returns {object} Updated account with error state
|
|
201
|
+
*/
|
|
202
|
+
export function applyErrorState(account, status, errorText) {
|
|
203
|
+
if (!account) return account;
|
|
204
|
+
|
|
205
|
+
const backoffLevel = account.backoffLevel || 0;
|
|
206
|
+
const { cooldownMs, newBackoffLevel } = checkFallbackError(status, errorText, backoffLevel);
|
|
207
|
+
|
|
208
|
+
return {
|
|
209
|
+
...account,
|
|
210
|
+
rateLimitedUntil: cooldownMs > 0 ? getUnavailableUntil(cooldownMs) : null,
|
|
211
|
+
backoffLevel: newBackoffLevel ?? backoffLevel,
|
|
212
|
+
lastError: { status, message: errorText, timestamp: new Date().toISOString() },
|
|
213
|
+
status: "error"
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// ── Error classification stubs (used by errorClassifier.js) ─────────────────
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Check if error text indicates the account has been deactivated/disabled.
|
|
221
|
+
*/
|
|
222
|
+
export function isAccountDeactivated(text) {
|
|
223
|
+
if (!text || typeof text !== 'string') return false;
|
|
224
|
+
const lower = text.toLowerCase();
|
|
225
|
+
return (
|
|
226
|
+
lower.includes('account disabled') ||
|
|
227
|
+
lower.includes('account_deactivated') ||
|
|
228
|
+
lower.includes('account has been deactivated') ||
|
|
229
|
+
lower.includes('account is no longer active') ||
|
|
230
|
+
lower.includes('organization has been disabled')
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Check if error text indicates credits/billing exhaustion.
|
|
236
|
+
*/
|
|
237
|
+
export function isCreditsExhausted(text) {
|
|
238
|
+
if (!text || typeof text !== 'string') return false;
|
|
239
|
+
const lower = text.toLowerCase();
|
|
240
|
+
return (
|
|
241
|
+
lower.includes('insufficient funds') ||
|
|
242
|
+
lower.includes('insufficient_funds') ||
|
|
243
|
+
lower.includes('credits exhausted') ||
|
|
244
|
+
lower.includes('out of credits') ||
|
|
245
|
+
lower.includes('no credits') ||
|
|
246
|
+
lower.includes('credit limit') ||
|
|
247
|
+
lower.includes('payment required') ||
|
|
248
|
+
lower.includes('spending limit') ||
|
|
249
|
+
lower.includes('quota exceeded') ||
|
|
250
|
+
lower.includes('quota_exceeded') ||
|
|
251
|
+
lower.includes('budget exceeded') ||
|
|
252
|
+
lower.includes('budget_exceeded')
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Check if error text indicates daily quota exhaustion (for 429 responses).
|
|
258
|
+
*/
|
|
259
|
+
export function isDailyQuotaExhausted(text) {
|
|
260
|
+
if (!text || typeof text !== 'string') return false;
|
|
261
|
+
const lower = text.toLowerCase();
|
|
262
|
+
return (
|
|
263
|
+
lower.includes('daily') ||
|
|
264
|
+
lower.includes('per day') ||
|
|
265
|
+
lower.includes('daily limit') ||
|
|
266
|
+
lower.includes('rate limit reached') ||
|
|
267
|
+
lower.includes('daily quota')
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Check if error text indicates an invalid/expired OAuth token.
|
|
273
|
+
*/
|
|
274
|
+
export function isOAuthInvalidToken(text) {
|
|
275
|
+
if (!text || typeof text !== 'string') return false;
|
|
276
|
+
const lower = text.toLowerCase();
|
|
277
|
+
return (
|
|
278
|
+
lower.includes('invalid_token') ||
|
|
279
|
+
lower.includes('invalid token') ||
|
|
280
|
+
lower.includes('token expired') ||
|
|
281
|
+
lower.includes('token has expired') ||
|
|
282
|
+
lower.includes('access token is invalid')
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Parse retry-after from a response body (JSON or string).
|
|
288
|
+
* Returns { retryAfterMs, reason }.
|
|
289
|
+
*/
|
|
290
|
+
export function parseRetryAfterFromBody(responseBody) {
|
|
291
|
+
if (!responseBody) return { retryAfterMs: 0, reason: null };
|
|
292
|
+
const text = typeof responseBody === 'string' ? responseBody : JSON.stringify(responseBody);
|
|
293
|
+
|
|
294
|
+
let retryAfterMs = 0;
|
|
295
|
+
let reason = null;
|
|
296
|
+
|
|
297
|
+
if (typeof responseBody === 'object' && responseBody !== null) {
|
|
298
|
+
const raw = responseBody.retry_after ?? responseBody.retryAfter ?? responseBody.retry_after_seconds;
|
|
299
|
+
if (typeof raw === 'number' && raw > 0) {
|
|
300
|
+
retryAfterMs = raw < 1e12 ? raw * 1000 : raw - Date.now();
|
|
301
|
+
reason = 'retry_after header';
|
|
302
|
+
} else if (typeof raw === 'string') {
|
|
303
|
+
const parsed = Number(raw);
|
|
304
|
+
if (Number.isFinite(parsed) && parsed > 0) {
|
|
305
|
+
retryAfterMs = parsed < 1e12 ? parsed * 1000 : parsed - Date.now();
|
|
306
|
+
reason = 'retry_after header';
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (retryAfterMs === 0) {
|
|
312
|
+
const match = text.match(/retry.*?(\d+)\s*(?:second|minute|hour)/i);
|
|
313
|
+
if (match) {
|
|
314
|
+
const val = Number(match[1]);
|
|
315
|
+
if (text.includes('minute')) retryAfterMs = val * 60 * 1000;
|
|
316
|
+
else if (text.includes('hour')) retryAfterMs = val * 3600 * 1000;
|
|
317
|
+
else retryAfterMs = val * 1000;
|
|
318
|
+
reason = 'body text pattern';
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
return { retryAfterMs, reason };
|
|
323
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { platform, arch } from "os";
|
|
2
|
+
import {
|
|
3
|
+
ANTIGRAVITY_FALLBACK_VERSION,
|
|
4
|
+
getCachedAntigravityVersion,
|
|
5
|
+
resolveAntigravityVersion,
|
|
6
|
+
} from "./antigravityVersion.js";
|
|
7
|
+
|
|
8
|
+
const ANTIGRAVITY_VERSION = ANTIGRAVITY_FALLBACK_VERSION;
|
|
9
|
+
export const ANTIGRAVITY_CHROME_VERSION = "142.0.7444.175";
|
|
10
|
+
export const ANTIGRAVITY_ELECTRON_VERSION = "39.2.3";
|
|
11
|
+
export const ANTIGRAVITY_LOAD_CODE_ASSIST_USER_AGENT = `vscode/1.X.X (Antigravity/${ANTIGRAVITY_FALLBACK_VERSION})`;
|
|
12
|
+
export const ANTIGRAVITY_LOAD_CODE_ASSIST_API_CLIENT = "";
|
|
13
|
+
export const ANTIGRAVITY_NODE_API_CLIENT = "google-api-nodejs-client/10.3.0";
|
|
14
|
+
export const ANTIGRAVITY_CREDIT_PROBE_API_CLIENT = "gl-node/22.21.1";
|
|
15
|
+
export const ANTIGRAVITY_API_CLIENT = ANTIGRAVITY_CREDIT_PROBE_API_CLIENT;
|
|
16
|
+
|
|
17
|
+
function withOptionalBearerAuth(headers, accessToken) {
|
|
18
|
+
if (accessToken) {
|
|
19
|
+
headers.Authorization = `Bearer ${accessToken}`;
|
|
20
|
+
}
|
|
21
|
+
return headers;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function getAntigravityPlatformInfo(platformName = platform()) {
|
|
25
|
+
switch (platformName) {
|
|
26
|
+
case "darwin":
|
|
27
|
+
return "Macintosh; Intel Mac OS X 10_15_7";
|
|
28
|
+
case "win32":
|
|
29
|
+
return "Windows NT 10.0; Win64; x64";
|
|
30
|
+
case "linux":
|
|
31
|
+
default:
|
|
32
|
+
return "X11; Linux x86_64";
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function antigravityUserAgent(version = getCachedAntigravityVersion(), platformName = platform()) {
|
|
37
|
+
return `Antigravity/${version} (${getAntigravityPlatformInfo(platformName)}) Chrome/${ANTIGRAVITY_CHROME_VERSION} Electron/${ANTIGRAVITY_ELECTRON_VERSION}`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export async function resolveAntigravityUserAgent(platformName = platform()) {
|
|
41
|
+
const version = await resolveAntigravityVersion();
|
|
42
|
+
return antigravityUserAgent(version, platformName);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function antigravityNativeOAuthUserAgent() {
|
|
46
|
+
return `vscode/1.X.X (Antigravity/${getCachedAntigravityVersion()})`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function getAntigravityLoadCodeAssistMetadata() {
|
|
50
|
+
return {
|
|
51
|
+
ideType: "ANTIGRAVITY",
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function getAntigravityLoadCodeAssistClientMetadata() {
|
|
56
|
+
return JSON.stringify(getAntigravityLoadCodeAssistMetadata());
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function getAntigravityHeaders(profile, accessToken) {
|
|
60
|
+
switch (profile) {
|
|
61
|
+
case "loadCodeAssist":
|
|
62
|
+
return withOptionalBearerAuth(
|
|
63
|
+
{
|
|
64
|
+
"Content-Type": "application/json",
|
|
65
|
+
"User-Agent": antigravityNativeOAuthUserAgent(),
|
|
66
|
+
},
|
|
67
|
+
accessToken
|
|
68
|
+
);
|
|
69
|
+
case "fetchAvailableModels":
|
|
70
|
+
case "models":
|
|
71
|
+
return withOptionalBearerAuth(
|
|
72
|
+
{
|
|
73
|
+
"Content-Type": "application/json",
|
|
74
|
+
"User-Agent": antigravityUserAgent(),
|
|
75
|
+
},
|
|
76
|
+
accessToken
|
|
77
|
+
);
|
|
78
|
+
default:
|
|
79
|
+
return withOptionalBearerAuth({ "Content-Type": "application/json" }, accessToken);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function getAntigravityCreditProbeApiClientHeader() {
|
|
84
|
+
return ANTIGRAVITY_CREDIT_PROBE_API_CLIENT;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function getAntigravityApiClientHeader() {
|
|
88
|
+
return ANTIGRAVITY_API_CLIENT;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export { ANTIGRAVITY_VERSION };
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
const ANTIGRAVITY_RELEASE_FEED_URL =
|
|
2
|
+
"https://antigravity-auto-updater-974169037036.us-central1.run.app/releases";
|
|
3
|
+
const ANTIGRAVITY_GITHUB_RELEASE_URL =
|
|
4
|
+
"https://api.github.com/repos/antigravityide/antigravity/releases/latest";
|
|
5
|
+
|
|
6
|
+
export const ANTIGRAVITY_VERSION_CACHE_TTL_MS = 6 * 60 * 60 * 1000;
|
|
7
|
+
export const ANTIGRAVITY_VERSION_FETCH_TIMEOUT_MS = 5000;
|
|
8
|
+
// Floor version synced with Antigravity-Manager v4.2.0 KNOWN_STABLE_VERSION.
|
|
9
|
+
export const ANTIGRAVITY_FALLBACK_VERSION = "4.2.0";
|
|
10
|
+
|
|
11
|
+
let versionCache = null;
|
|
12
|
+
let inFlightRequest = null;
|
|
13
|
+
|
|
14
|
+
function normalizeVersion(value) {
|
|
15
|
+
if (typeof value !== "string") return null;
|
|
16
|
+
const trimmed = value.trim().replace(/^v/i, "");
|
|
17
|
+
const match = trimmed.match(/^(\d+\.\d+\.\d+)\b/);
|
|
18
|
+
return match ? match[1] : null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function compareSemver(a, b) {
|
|
22
|
+
const aParts = a.split(".").map((part) => Number.parseInt(part, 10) || 0);
|
|
23
|
+
const bParts = b.split(".").map((part) => Number.parseInt(part, 10) || 0);
|
|
24
|
+
for (let i = 0; i < 3; i += 1) {
|
|
25
|
+
if (aParts[i] !== bParts[i]) return aParts[i] - bParts[i];
|
|
26
|
+
}
|
|
27
|
+
return 0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function pickNewestVersion(...versions) {
|
|
31
|
+
return versions
|
|
32
|
+
.map((version) => normalizeVersion(version))
|
|
33
|
+
.filter((version) => !!version)
|
|
34
|
+
.reduce(
|
|
35
|
+
(best, version) => (compareSemver(version, best) > 0 ? version : best),
|
|
36
|
+
ANTIGRAVITY_FALLBACK_VERSION
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function fetchJsonWithTimeout(fetchImpl, url) {
|
|
41
|
+
const controller = new AbortController();
|
|
42
|
+
const timeoutId = setTimeout(() => controller.abort(), ANTIGRAVITY_VERSION_FETCH_TIMEOUT_MS);
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
const response = await fetchImpl(url, {
|
|
46
|
+
headers: {
|
|
47
|
+
Accept: "application/json",
|
|
48
|
+
"User-Agent": "OmniRoute-AntigravityVersion/1.0",
|
|
49
|
+
},
|
|
50
|
+
signal: controller.signal,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
if (!response.ok) {
|
|
54
|
+
throw new Error(`Version source ${url} returned ${response.status}`);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return response.json();
|
|
58
|
+
} finally {
|
|
59
|
+
clearTimeout(timeoutId);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function parseOfficialReleaseFeed(payload) {
|
|
64
|
+
if (!Array.isArray(payload)) return null;
|
|
65
|
+
|
|
66
|
+
for (const entry of payload) {
|
|
67
|
+
const version = normalizeVersion(entry?.version);
|
|
68
|
+
if (version) return version;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function parseGitHubRelease(payload) {
|
|
75
|
+
if (!payload || typeof payload !== "object") return null;
|
|
76
|
+
|
|
77
|
+
const candidate = payload.tag_name ?? payload.name;
|
|
78
|
+
return normalizeVersion(candidate);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async function fetchLatestAntigravityVersion(fetchImpl) {
|
|
82
|
+
const sources = [
|
|
83
|
+
{
|
|
84
|
+
parse: parseOfficialReleaseFeed,
|
|
85
|
+
url: ANTIGRAVITY_RELEASE_FEED_URL,
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
parse: parseGitHubRelease,
|
|
89
|
+
url: ANTIGRAVITY_GITHUB_RELEASE_URL,
|
|
90
|
+
},
|
|
91
|
+
];
|
|
92
|
+
|
|
93
|
+
for (const source of sources) {
|
|
94
|
+
try {
|
|
95
|
+
const payload = await fetchJsonWithTimeout(fetchImpl, source.url);
|
|
96
|
+
const version = source.parse(payload);
|
|
97
|
+
if (version) return version;
|
|
98
|
+
} catch {
|
|
99
|
+
// Try next
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export async function resolveAntigravityVersion(fetchImpl = fetch) {
|
|
107
|
+
const now = Date.now();
|
|
108
|
+
|
|
109
|
+
if (versionCache && now - versionCache.fetchedAt < ANTIGRAVITY_VERSION_CACHE_TTL_MS) {
|
|
110
|
+
return versionCache.version;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (inFlightRequest) {
|
|
114
|
+
return inFlightRequest;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
inFlightRequest = (async () => {
|
|
118
|
+
const resolved = await fetchLatestAntigravityVersion(fetchImpl);
|
|
119
|
+
const version = resolved
|
|
120
|
+
? pickNewestVersion(resolved, ANTIGRAVITY_FALLBACK_VERSION)
|
|
121
|
+
: pickNewestVersion(versionCache?.version, ANTIGRAVITY_FALLBACK_VERSION);
|
|
122
|
+
|
|
123
|
+
if (resolved) {
|
|
124
|
+
versionCache = {
|
|
125
|
+
fetchedAt: Date.now(),
|
|
126
|
+
version,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return version;
|
|
131
|
+
})();
|
|
132
|
+
|
|
133
|
+
try {
|
|
134
|
+
return await inFlightRequest;
|
|
135
|
+
} finally {
|
|
136
|
+
inFlightRequest = null;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export function getCachedAntigravityVersion() {
|
|
141
|
+
return versionCache?.version || ANTIGRAVITY_FALLBACK_VERSION;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function seedAntigravityVersionCache(version, fetchedAt = Date.now()) {
|
|
145
|
+
versionCache = {
|
|
146
|
+
fetchedAt,
|
|
147
|
+
version,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export function clearAntigravityVersionCache() {
|
|
152
|
+
versionCache = null;
|
|
153
|
+
inFlightRequest = null;
|
|
154
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { buildClineHeaders } from "../shared/clineAuth.js";
|
|
2
|
+
|
|
3
|
+
const CLINEPASS_MODELS_ENDPOINT = "https://api.cline.bot/api/v1/models";
|
|
4
|
+
const FETCH_TIMEOUT_MS = 5000;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Build request headers for the ClinePass /models endpoint (Cline's upstream API).
|
|
8
|
+
* - API keys are sent as plain Bearer tokens.
|
|
9
|
+
* - OAuth access tokens must carry the WorkOS `workos:` prefix (handled by buildClineHeaders).
|
|
10
|
+
*/
|
|
11
|
+
function buildModelListHeaders(token, isApiKey) {
|
|
12
|
+
if (isApiKey) {
|
|
13
|
+
return {
|
|
14
|
+
Accept: "application/json",
|
|
15
|
+
Authorization: `Bearer ${token}`,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
return buildClineHeaders(token, { Accept: "application/json" });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Fetch ClinePass live model catalog from Cline's /models endpoint.
|
|
23
|
+
*
|
|
24
|
+
* @param {object} credentials - Connection credentials ({ accessToken, apiKey })
|
|
25
|
+
* @returns {Promise<{ models: { id: string, name: string }[] } | null>}
|
|
26
|
+
*/
|
|
27
|
+
export async function resolveClinepassModels(credentials) {
|
|
28
|
+
const isApiKey = Boolean(credentials?.apiKey);
|
|
29
|
+
const token = isApiKey ? credentials.apiKey : credentials?.accessToken;
|
|
30
|
+
if (!token) return null;
|
|
31
|
+
|
|
32
|
+
const controller = new AbortController();
|
|
33
|
+
const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
const headers = buildModelListHeaders(token, isApiKey);
|
|
37
|
+
|
|
38
|
+
const response = await fetch(CLINEPASS_MODELS_ENDPOINT, {
|
|
39
|
+
method: "GET",
|
|
40
|
+
headers,
|
|
41
|
+
signal: controller.signal,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
if (!response.ok) return null;
|
|
45
|
+
|
|
46
|
+
const json = await response.json();
|
|
47
|
+
const rawList = Array.isArray(json) ? json : json?.data;
|
|
48
|
+
if (!Array.isArray(rawList)) return null;
|
|
49
|
+
|
|
50
|
+
const models = rawList
|
|
51
|
+
.filter((m) => typeof m?.id === "string" && m.id.startsWith("cline-pass/"))
|
|
52
|
+
.map((m) => ({
|
|
53
|
+
id: m.id,
|
|
54
|
+
name: m.name || m.id,
|
|
55
|
+
}));
|
|
56
|
+
|
|
57
|
+
return models.length ? { models } : null;
|
|
58
|
+
} catch {
|
|
59
|
+
return null;
|
|
60
|
+
} finally {
|
|
61
|
+
clearTimeout(timer);
|
|
62
|
+
}
|
|
63
|
+
}
|