@fudrouter/fsrouter 0.6.61 → 0.6.63
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/bin/copyJs.js +13 -9
- 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,368 @@
|
|
|
1
|
+
// Claude helper functions for translator
|
|
2
|
+
import { DEFAULT_THINKING_CLAUDE_SIGNATURE } from "../../config/defaultThinkingSignature.js";
|
|
3
|
+
import { ROLE, CLAUDE_BLOCK } from "../schema/index.js";
|
|
4
|
+
import { adjustMaxTokens } from "./maxTokens.js";
|
|
5
|
+
import { applyCloaking } from "../../utils/claudeCloaking.js";
|
|
6
|
+
import { resolveSessionId } from "../../utils/sessionManager.js";
|
|
7
|
+
import { isValidClaudeSignature } from "../../utils/claudeSignature.js";
|
|
8
|
+
import { PROVIDERS } from "../../providers/index.js";
|
|
9
|
+
import { getCapabilitiesForModel } from "../../providers/capabilities.js";
|
|
10
|
+
import { DEFAULT_MAX_TOKENS } from "../../config/runtimeConfig.js";
|
|
11
|
+
|
|
12
|
+
// Check if message has valid non-empty content
|
|
13
|
+
export function hasValidContent(msg) {
|
|
14
|
+
if (typeof msg.content === "string" && msg.content.trim()) return true;
|
|
15
|
+
if (Array.isArray(msg.content)) {
|
|
16
|
+
return msg.content.some(block =>
|
|
17
|
+
(block.type === CLAUDE_BLOCK.TEXT && block.text?.trim()) ||
|
|
18
|
+
block.type === CLAUDE_BLOCK.TOOL_USE ||
|
|
19
|
+
block.type === CLAUDE_BLOCK.TOOL_RESULT
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Fix tool_use/tool_result ordering for Claude API
|
|
26
|
+
// 1. Assistant message with tool_use: remove text AFTER tool_use (Claude doesn't allow)
|
|
27
|
+
// 2. Merge consecutive same-role messages
|
|
28
|
+
export function fixToolUseOrdering(messages) {
|
|
29
|
+
if (messages.length <= 1) return messages;
|
|
30
|
+
|
|
31
|
+
// Pass 1: Fix assistant messages with tool_use - remove text after tool_use
|
|
32
|
+
for (const msg of messages) {
|
|
33
|
+
if (msg.role === ROLE.ASSISTANT && Array.isArray(msg.content)) {
|
|
34
|
+
const hasToolUse = msg.content.some(b => b.type === CLAUDE_BLOCK.TOOL_USE);
|
|
35
|
+
if (hasToolUse) {
|
|
36
|
+
// Keep only: thinking blocks + tool_use blocks (remove text blocks after tool_use)
|
|
37
|
+
const newContent = [];
|
|
38
|
+
let foundToolUse = false;
|
|
39
|
+
|
|
40
|
+
for (const block of msg.content) {
|
|
41
|
+
if (block.type === CLAUDE_BLOCK.TOOL_USE) {
|
|
42
|
+
foundToolUse = true;
|
|
43
|
+
newContent.push(block);
|
|
44
|
+
} else if (block.type === CLAUDE_BLOCK.THINKING || block.type === CLAUDE_BLOCK.REDACTED_THINKING) {
|
|
45
|
+
newContent.push(block);
|
|
46
|
+
} else if (!foundToolUse) {
|
|
47
|
+
// Keep text blocks BEFORE tool_use
|
|
48
|
+
newContent.push(block);
|
|
49
|
+
}
|
|
50
|
+
// Skip text blocks AFTER tool_use
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
msg.content = newContent;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Pass 2: Merge consecutive same-role messages
|
|
59
|
+
const merged = [];
|
|
60
|
+
|
|
61
|
+
for (const msg of messages) {
|
|
62
|
+
const last = merged[merged.length - 1];
|
|
63
|
+
|
|
64
|
+
if (last && last.role === msg.role) {
|
|
65
|
+
// Merge content arrays
|
|
66
|
+
const lastContent = Array.isArray(last.content) ? last.content : [{ type: CLAUDE_BLOCK.TEXT, text: last.content }];
|
|
67
|
+
const msgContent = Array.isArray(msg.content) ? msg.content : [{ type: CLAUDE_BLOCK.TEXT, text: msg.content }];
|
|
68
|
+
|
|
69
|
+
// Put tool_result first, then other content
|
|
70
|
+
const toolResults = [...lastContent.filter(b => b.type === CLAUDE_BLOCK.TOOL_RESULT), ...msgContent.filter(b => b.type === CLAUDE_BLOCK.TOOL_RESULT)];
|
|
71
|
+
const otherContent = [...lastContent.filter(b => b.type !== CLAUDE_BLOCK.TOOL_RESULT), ...msgContent.filter(b => b.type !== CLAUDE_BLOCK.TOOL_RESULT)];
|
|
72
|
+
|
|
73
|
+
last.content = [...toolResults, ...otherContent];
|
|
74
|
+
} else {
|
|
75
|
+
// Ensure content is array
|
|
76
|
+
const content = Array.isArray(msg.content) ? msg.content : [{ type: CLAUDE_BLOCK.TEXT, text: msg.content }];
|
|
77
|
+
merged.push({ role: msg.role, content: [...content] });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return merged;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Models that reject thinking.type "adaptive" + output_config.effort (Opus 4.5+/Sonnet 4.6+ only)
|
|
85
|
+
const ADAPTIVE_THINKING_UNSUPPORTED = /haiku/i;
|
|
86
|
+
|
|
87
|
+
function handlesThinkingBlocks(provider) {
|
|
88
|
+
return provider === "claude" || provider?.startsWith("anthropic-compatible") || provider === "deepseek";
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function buildThinkingPlaceholder(provider) {
|
|
92
|
+
const block = {
|
|
93
|
+
type: CLAUDE_BLOCK.THINKING,
|
|
94
|
+
thinking: ".",
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
// DeepSeek's Anthropic-compatible endpoint requires a thinking block in
|
|
98
|
+
// thinking mode, but it does not need Anthropic's signed-thinking fallback.
|
|
99
|
+
if (provider !== "deepseek") {
|
|
100
|
+
block.signature = DEFAULT_THINKING_CLAUDE_SIGNATURE;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return block;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Normalize a native Claude passthrough body to match Anthropic Messages API spec.
|
|
107
|
+
// Newer Cowork/Claude Code clients emit beta-only shapes that OAuth endpoints reject:
|
|
108
|
+
// 1. thinking.type "adaptive" → unsupported on Haiku
|
|
109
|
+
// 2. output_config.effort → unsupported on Haiku
|
|
110
|
+
// 3. role "system" messages (mid-conversation-system beta) → only top-level system is allowed
|
|
111
|
+
export function normalizeClaudePassthrough(body, model = "") {
|
|
112
|
+
if (!body || typeof body !== "object") return body;
|
|
113
|
+
|
|
114
|
+
// 1. Downgrade adaptive thinking for models that don't support it
|
|
115
|
+
if (body.thinking?.type === "adaptive" && ADAPTIVE_THINKING_UNSUPPORTED.test(model)) {
|
|
116
|
+
body.thinking = { type: "enabled", budget_tokens: 10000 };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// 2. Strip effort param for models that don't support it (keep other output_config fields)
|
|
120
|
+
if (ADAPTIVE_THINKING_UNSUPPORTED.test(model) && body.output_config?.effort != null) {
|
|
121
|
+
delete body.output_config.effort;
|
|
122
|
+
if (Object.keys(body.output_config).length === 0) delete body.output_config;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// 2. Hoist mid-conversation system messages into the top-level system field
|
|
126
|
+
if (Array.isArray(body.messages)) {
|
|
127
|
+
const systemBlocks = [];
|
|
128
|
+
const messages = [];
|
|
129
|
+
for (const msg of body.messages) {
|
|
130
|
+
if (msg.role === ROLE.SYSTEM) {
|
|
131
|
+
const text = typeof msg.content === "string"
|
|
132
|
+
? msg.content
|
|
133
|
+
: Array.isArray(msg.content)
|
|
134
|
+
? msg.content.map(b => (typeof b === "string" ? b : b?.text || "")).join("\n")
|
|
135
|
+
: "";
|
|
136
|
+
if (text.trim()) systemBlocks.push({ type: CLAUDE_BLOCK.TEXT, text });
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
messages.push(msg);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (systemBlocks.length > 0) {
|
|
143
|
+
const existing = Array.isArray(body.system)
|
|
144
|
+
? body.system
|
|
145
|
+
: typeof body.system === "string" && body.system.trim()
|
|
146
|
+
? [{ type: "text", text: body.system }]
|
|
147
|
+
: [];
|
|
148
|
+
body.system = [...existing, ...systemBlocks];
|
|
149
|
+
body.messages = messages;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// 3. Drop thinking blocks whose signature is not Claude's (combo mixes models,
|
|
154
|
+
// so foreign signatures leak into history and Anthropic rejects them).
|
|
155
|
+
const thinkingEnabled = body.thinking?.type === "enabled";
|
|
156
|
+
if (Array.isArray(body.messages)) {
|
|
157
|
+
for (const msg of body.messages) {
|
|
158
|
+
if (msg.role !== ROLE.ASSISTANT || !Array.isArray(msg.content)) continue;
|
|
159
|
+
let hasToolUse = false;
|
|
160
|
+
let hasKeptThinking = false;
|
|
161
|
+
const kept = [];
|
|
162
|
+
for (const block of msg.content) {
|
|
163
|
+
if (block.type === CLAUDE_BLOCK.THINKING || block.type === CLAUDE_BLOCK.REDACTED_THINKING) {
|
|
164
|
+
if (isValidClaudeSignature(block.signature)) {
|
|
165
|
+
hasKeptThinking = true;
|
|
166
|
+
kept.push(block);
|
|
167
|
+
}
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
if (block.type === CLAUDE_BLOCK.TOOL_USE) hasToolUse = true;
|
|
171
|
+
kept.push(block);
|
|
172
|
+
}
|
|
173
|
+
msg.content = kept;
|
|
174
|
+
if (thinkingEnabled && !hasKeptThinking && hasToolUse) {
|
|
175
|
+
msg.content.unshift(buildThinkingPlaceholder("claude"));
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return body;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Prepare request for Claude format endpoints
|
|
184
|
+
// - Cleanup cache_control
|
|
185
|
+
// - Filter empty messages
|
|
186
|
+
// - Add thinking block for Anthropic endpoint (provider === "claude")
|
|
187
|
+
// - Fix tool_use/tool_result ordering
|
|
188
|
+
// - Apply cloaking (billing header + fake user ID) for OAuth tokens
|
|
189
|
+
export function prepareClaudeRequest(body, provider = null, apiKey = null, connectionId = null, rawHeaders = null, sessionId = null) {
|
|
190
|
+
// quirk: MiniMax's Claude-compatible endpoint rejects Anthropic's output_config (400 invalid params)
|
|
191
|
+
if (PROVIDERS[provider]?.quirks?.dropOutputConfig) {
|
|
192
|
+
delete body.output_config;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Clamp max_tokens to the model's real output ceiling. Models whose caps
|
|
196
|
+
// declare a higher maxOutput (e.g. Opus 4.8 / Sonnet 4.6 = 128000) are allowed
|
|
197
|
+
// up to it, so max-effort thinking gets full budget; others fall back to the
|
|
198
|
+
// conservative 64000 default.
|
|
199
|
+
if (body.max_tokens) {
|
|
200
|
+
const ceiling = getCapabilitiesForModel(provider, body.model).maxOutput || DEFAULT_MAX_TOKENS;
|
|
201
|
+
if (body.max_tokens > ceiling) body.max_tokens = ceiling;
|
|
202
|
+
|
|
203
|
+
// Reconcile against thinking budget. applyThinking (thinkingUnified.js) runs
|
|
204
|
+
// AFTER adjustMaxTokens capped max_tokens, and the claude-budget format maps
|
|
205
|
+
// max effort → budget_tokens 128000 — larger than the clamped max_tokens.
|
|
206
|
+
// Anthropic requires max_tokens strictly greater than budget_tokens (else 400).
|
|
207
|
+
// Prefer raising max_tokens to preserve the requested thinking depth; if the
|
|
208
|
+
// budget alone meets/exceeds the ceiling, cap output and shrink the budget so
|
|
209
|
+
// some tokens remain for the answer.
|
|
210
|
+
if (body.thinking?.type === "enabled" && body.thinking.budget_tokens && body.thinking.budget_tokens >= body.max_tokens) {
|
|
211
|
+
body.max_tokens = Math.min(body.thinking.budget_tokens + 1024, ceiling);
|
|
212
|
+
if (body.thinking.budget_tokens >= body.max_tokens) {
|
|
213
|
+
body.thinking.budget_tokens = Math.max(1024, body.max_tokens - 1024);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// 1. System: remove all cache_control, add only to last block with ttl 1h
|
|
219
|
+
if (body.system && Array.isArray(body.system)) {
|
|
220
|
+
body.system = body.system.map((block, i) => {
|
|
221
|
+
const { cache_control, ...rest } = block;
|
|
222
|
+
if (i === body.system.length - 1) {
|
|
223
|
+
return { ...rest, cache_control: { type: "ephemeral", ttl: "1h" } };
|
|
224
|
+
}
|
|
225
|
+
return rest;
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// 2. Messages: process in optimized passes
|
|
230
|
+
if (body.messages && Array.isArray(body.messages)) {
|
|
231
|
+
const len = body.messages.length;
|
|
232
|
+
let filtered = [];
|
|
233
|
+
|
|
234
|
+
// Pass 1: remove cache_control + filter empty messages
|
|
235
|
+
for (let i = 0; i < len; i++) {
|
|
236
|
+
const msg = body.messages[i];
|
|
237
|
+
|
|
238
|
+
// Remove cache_control from content blocks
|
|
239
|
+
if (Array.isArray(msg.content)) {
|
|
240
|
+
for (const block of msg.content) {
|
|
241
|
+
delete block.cache_control;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Keep final assistant even if empty, otherwise check valid content
|
|
246
|
+
const isFinalAssistant = i === len - 1 && msg.role === "assistant";
|
|
247
|
+
if (isFinalAssistant || hasValidContent(msg)) {
|
|
248
|
+
filtered.push(msg);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Pass 1.5: Fix tool_use/tool_result ordering
|
|
253
|
+
// Each tool_use must have tool_result in the NEXT message (not same message with other content)
|
|
254
|
+
filtered = fixToolUseOrdering(filtered);
|
|
255
|
+
|
|
256
|
+
body.messages = filtered;
|
|
257
|
+
|
|
258
|
+
// Check if thinking is enabled AND last message is from user
|
|
259
|
+
const lastMessage = filtered[filtered.length - 1];
|
|
260
|
+
const lastMessageIsUser = lastMessage?.role === "user";
|
|
261
|
+
const thinkingEnabled = body.thinking?.type === "enabled" && lastMessageIsUser;
|
|
262
|
+
|
|
263
|
+
// Pass 2 (reverse): add cache_control to last assistant + handle thinking for Anthropic
|
|
264
|
+
let lastAssistantProcessed = false;
|
|
265
|
+
for (let i = filtered.length - 1; i >= 0; i--) {
|
|
266
|
+
const msg = filtered[i];
|
|
267
|
+
|
|
268
|
+
if (msg.role === "assistant" && Array.isArray(msg.content)) {
|
|
269
|
+
// Add cache_control to last non-thinking block of first (from end) assistant with content
|
|
270
|
+
// thinking/redacted_thinking blocks do not support cache_control
|
|
271
|
+
if (!lastAssistantProcessed && msg.content.length > 0) {
|
|
272
|
+
for (let j = msg.content.length - 1; j >= 0; j--) {
|
|
273
|
+
const block = msg.content[j];
|
|
274
|
+
if (block.type !== CLAUDE_BLOCK.THINKING && block.type !== CLAUDE_BLOCK.REDACTED_THINKING) {
|
|
275
|
+
block.cache_control = { type: "ephemeral" };
|
|
276
|
+
break;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
lastAssistantProcessed = true;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Handle thinking blocks for Anthropic-compatible endpoints.
|
|
283
|
+
if (handlesThinkingBlocks(provider)) {
|
|
284
|
+
let hasToolUse = false;
|
|
285
|
+
let hasKeptThinking = false;
|
|
286
|
+
|
|
287
|
+
// Claude native: preserve valid signatures, drop invalid blocks.
|
|
288
|
+
// anthropic-compatible: replace with default (safe fallback for lenient upstreams).
|
|
289
|
+
// DeepSeek: keep existing thinking as-is; add an unsigned placeholder only if missing.
|
|
290
|
+
const isClaudeNative = provider === "claude";
|
|
291
|
+
const isDeepSeek = provider === "deepseek";
|
|
292
|
+
const kept = [];
|
|
293
|
+
for (const block of msg.content) {
|
|
294
|
+
const isThinking = block.type === CLAUDE_BLOCK.THINKING || block.type === CLAUDE_BLOCK.REDACTED_THINKING;
|
|
295
|
+
if (isThinking) {
|
|
296
|
+
if (isClaudeNative) {
|
|
297
|
+
if (isValidClaudeSignature(block.signature)) {
|
|
298
|
+
hasKeptThinking = true;
|
|
299
|
+
kept.push(block);
|
|
300
|
+
}
|
|
301
|
+
} else if (isDeepSeek) {
|
|
302
|
+
hasKeptThinking = true;
|
|
303
|
+
kept.push(block);
|
|
304
|
+
} else {
|
|
305
|
+
block.signature = DEFAULT_THINKING_CLAUDE_SIGNATURE;
|
|
306
|
+
hasKeptThinking = true;
|
|
307
|
+
kept.push(block);
|
|
308
|
+
}
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
if (block.type === CLAUDE_BLOCK.TOOL_USE) hasToolUse = true;
|
|
312
|
+
kept.push(block);
|
|
313
|
+
}
|
|
314
|
+
msg.content = kept;
|
|
315
|
+
|
|
316
|
+
// Add thinking block if thinking enabled + has tool_use but no thinking
|
|
317
|
+
if (thinkingEnabled && !hasKeptThinking && hasToolUse) {
|
|
318
|
+
msg.content.unshift(buildThinkingPlaceholder(provider));
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// 3. Tools: filter built-in tools for non-Anthropic providers, then handle cache_control
|
|
326
|
+
if (body.tools && Array.isArray(body.tools)) {
|
|
327
|
+
// Strip built-in tools (e.g. web_search_20250305) and normalize to Anthropic-native shape
|
|
328
|
+
// (drop `type` field, fold `function.{name,description,parameters}`) for non-Anthropic providers
|
|
329
|
+
if (provider !== "claude") {
|
|
330
|
+
body.tools = body.tools
|
|
331
|
+
.filter(tool => !tool.type || tool.type === "function")
|
|
332
|
+
.map(tool => {
|
|
333
|
+
if (tool.function) {
|
|
334
|
+
return {
|
|
335
|
+
name: tool.function.name,
|
|
336
|
+
description: tool.function.description,
|
|
337
|
+
input_schema: tool.function.parameters,
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
const { type, ...rest } = tool;
|
|
341
|
+
return rest;
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
body.tools = body.tools.map((tool, i) => {
|
|
346
|
+
const { cache_control, ...rest } = tool;
|
|
347
|
+
if (i === body.tools.length - 1) {
|
|
348
|
+
return { ...rest, cache_control: { type: "ephemeral", ttl: "1h" } };
|
|
349
|
+
}
|
|
350
|
+
return rest;
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
// Remove tools array and tool_choice if empty after filtering
|
|
354
|
+
if (body.tools.length === 0) {
|
|
355
|
+
delete body.tools;
|
|
356
|
+
delete body.tool_choice;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// Apply cloaking for OAuth tokens (billing header + fake user ID)
|
|
361
|
+
// session_id in user_id must match X-Claude-Code-Session-Id for fingerprint consistency
|
|
362
|
+
if ((provider === "claude" || provider?.startsWith("anthropic-compatible")) && apiKey) {
|
|
363
|
+
const sid = sessionId || resolveSessionId({ headers: rawHeaders, body, connectionId, scope: "claude" });
|
|
364
|
+
body = applyCloaking(body, apiKey, sid);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
return body;
|
|
368
|
+
}
|