@fudrouter/fsrouter 0.6.72 → 0.6.74
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/dist/lib/headroom/detect.js +97 -7
- package/dist/lib/headroom/process.js +136 -4
- package/dist/open-sse/config/appConstants.js +23 -79
- package/dist/open-sse/config/cliFingerprints.js +1 -1
- package/dist/open-sse/config/errorConfig.js +0 -11
- package/dist/open-sse/config/grokCli.js +10 -0
- package/dist/open-sse/config/kiroConstants.js +99 -46
- package/dist/open-sse/config/runtimeConfig.js +2 -0
- package/dist/open-sse/config/ttsModels.js +2 -0
- package/dist/open-sse/executors/antigravity.js +250 -164
- package/dist/open-sse/executors/base.js +16 -11
- package/dist/open-sse/executors/codex.js +269 -1108
- package/dist/open-sse/executors/commandCode.js +1 -1
- package/dist/open-sse/executors/commandcode.js +10 -4
- package/dist/open-sse/executors/cursor.js +96 -203
- package/dist/open-sse/executors/default.js +146 -244
- package/dist/open-sse/executors/github.js +128 -73
- package/dist/open-sse/executors/grok-cli.js +527 -94
- package/dist/open-sse/executors/grok-web.js +5 -7
- package/dist/open-sse/executors/index.js +12 -0
- package/dist/open-sse/executors/kiro.js +150 -61
- package/dist/open-sse/executors/opencode-go.js +12 -4
- package/dist/open-sse/executors/opencode.js +1 -1
- package/dist/open-sse/executors/perplexity-web.js +20 -96
- package/dist/open-sse/executors/qoder.js +28 -18
- package/dist/open-sse/executors/vertex.js +53 -7
- package/dist/open-sse/executors/xiaomi-tokenplan.js +6 -5
- package/dist/open-sse/handlers/chatCore/nonStreamingHandler.js +97 -85
- package/dist/open-sse/handlers/chatCore/requestDetail.js +32 -8
- package/dist/open-sse/handlers/chatCore/sseToJsonHandler.js +13 -7
- package/dist/open-sse/handlers/chatCore/streamingHandler.js +74 -25
- package/dist/open-sse/handlers/chatCore.js +35 -41
- package/dist/open-sse/handlers/embeddingProviders/index.js +1 -0
- package/dist/open-sse/handlers/embeddingProviders/openai.js +8 -16
- package/dist/open-sse/handlers/imageProviders/blackForestLabs.js +2 -21
- package/dist/open-sse/handlers/imageProviders/cloudflareAi.js +2 -30
- package/dist/open-sse/handlers/imageProviders/codex.js +2 -20
- package/dist/open-sse/handlers/imageProviders/comfyui.js +5 -18
- package/dist/open-sse/handlers/imageProviders/falAi.js +2 -22
- package/dist/open-sse/handlers/imageProviders/gemini.js +2 -16
- package/dist/open-sse/handlers/imageProviders/huggingface.js +2 -17
- package/dist/open-sse/handlers/imageProviders/index.js +3 -4
- package/dist/open-sse/handlers/imageProviders/leonardo.js +1 -1
- package/dist/open-sse/handlers/imageProviders/nanobanana.js +4 -23
- package/dist/open-sse/handlers/imageProviders/openai.js +15 -43
- package/dist/open-sse/handlers/imageProviders/runwayml.js +2 -26
- package/dist/open-sse/handlers/imageProviders/sdwebui.js +4 -20
- package/dist/open-sse/handlers/imageProviders/stabilityAi.js +2 -26
- package/dist/open-sse/handlers/imageProviders/weavy.js +1 -1
- package/dist/open-sse/handlers/search/chatSearch.js +60 -14
- package/dist/open-sse/handlers/ttsProviders/gemini.js +14 -3
- package/dist/open-sse/handlers/ttsProviders/index.js +4 -2
- package/dist/open-sse/handlers/ttsProviders/openai.js +4 -1
- package/dist/open-sse/handlers/ttsProviders/openrouter.js +7 -4
- package/dist/open-sse/handlers/videoCore.js +166 -0
- package/dist/open-sse/handlers/videoProviders/weavy.js +1 -1
- package/dist/open-sse/mcp-server/catalog.js +1 -1
- package/dist/open-sse/mcp-server/server.js +2 -2
- package/dist/open-sse/mcp-server/tools/advancedTools.js +2 -2
- package/dist/open-sse/mcp-server/tools/agentSkillTools.js +1 -1
- package/dist/open-sse/mcp-server/tools/compressionTools.js +4 -4
- package/dist/open-sse/mcp-server/tools/gamificationTools.js +10 -10
- package/dist/open-sse/mcp-server/tools/githubSkillTools.js +1 -1
- package/dist/open-sse/mcp-server/tools/memoryTools.js +3 -3
- package/dist/open-sse/mcp-server/tools/notionTools.js +2 -2
- package/dist/open-sse/mcp-server/tools/obsidianTools.js +2 -2
- package/dist/open-sse/mcp-server/tools/pickFastestModel.js +1 -1
- package/dist/open-sse/mcp-server/tools/pluginTools.js +4 -4
- package/dist/open-sse/mcp-server/tools/skillTools.js +2 -2
- package/dist/open-sse/providers/capabilities.js +24 -4
- package/dist/open-sse/providers/registry/alicode-intl.js +1 -1
- package/dist/open-sse/providers/registry/anthropic.js +1 -8
- package/dist/open-sse/providers/registry/codex.js +0 -9
- package/dist/open-sse/providers/registry/cohere.js +0 -2
- package/dist/open-sse/providers/registry/gemini.js +0 -2
- package/dist/open-sse/providers/registry/github.js +9 -6
- package/dist/open-sse/providers/registry/grok-cli.js +28 -18
- package/dist/open-sse/providers/registry/index.js +74 -80
- package/dist/open-sse/providers/registry/kiro.js +12 -0
- package/dist/open-sse/providers/registry/mistral.js +0 -3
- package/dist/open-sse/providers/registry/openai.js +0 -3
- package/dist/open-sse/providers/registry/perplexity.js +0 -2
- package/dist/open-sse/providers/registry/xai.js +5 -3
- package/dist/open-sse/rtk/autodetect.js +10 -2
- package/dist/open-sse/rtk/caveman.js +2 -93
- package/dist/open-sse/rtk/cavemanPrompts.js +34 -2
- package/dist/open-sse/rtk/constants.js +7 -2
- package/dist/open-sse/rtk/headroom.js +133 -0
- package/dist/open-sse/rtk/ponytail.js +1 -1
- package/dist/open-sse/rtk/registry.js +2 -0
- package/dist/open-sse/services/accountFallback.js +0 -108
- package/dist/open-sse/services/combo/quotaExhaustionCutoff.js +2 -2
- package/dist/open-sse/services/combo/quotaShareStrategy.js +1 -1
- package/dist/open-sse/services/combo/resolveAutoStrategy.js +1 -1
- package/dist/open-sse/services/combo/sessionStickiness.js +1 -1
- package/dist/open-sse/services/combo/targetSorters.js +2 -2
- package/dist/open-sse/services/combo/validateQuality.js +1 -1
- package/dist/open-sse/services/comboConfig.js +1 -1
- package/dist/open-sse/services/emergencyFallback.js +1 -1
- package/dist/open-sse/services/grokCliModels.js +127 -0
- package/dist/open-sse/services/model.js +7 -1
- package/dist/open-sse/services/provider.js +1 -1
- package/dist/open-sse/services/proxyAutoSelector.js +1 -1
- package/dist/open-sse/services/tokenRefresh/providers.js +3 -3
- package/dist/open-sse/services/usage/codex.js +148 -214
- package/dist/open-sse/services/usage/grok-cli.js +61 -7
- package/dist/open-sse/services/usage/misc.js +0 -19
- package/dist/open-sse/services/usage.js +0 -2
- package/dist/open-sse/translator/concerns/paramSupport.js +2 -2
- package/dist/open-sse/translator/concerns/thinkingUnified.js +6 -0
- package/dist/open-sse/translator/index.js +97 -59
- package/dist/open-sse/translator/request/claude-to-kiro.js +67 -40
- package/dist/open-sse/translator/request/openai-responses.js +1 -0
- package/dist/open-sse/translator/request/openai-to-commandcode.js +0 -4
- package/dist/open-sse/translator/request/openai-to-kiro.js +49 -20
- package/dist/open-sse/translator/response/commandcode-to-openai.js +0 -4
- package/dist/open-sse/utils/bypassHandler.js +18 -3
- package/dist/open-sse/utils/claudeCloaking.js +15 -5
- package/dist/open-sse/utils/cursorImages.js +1 -1
- package/dist/open-sse/utils/error.js +0 -17
- package/dist/open-sse/utils/keepaliveThreshold.js +4 -4
- package/dist/open-sse/utils/kiroSessionReplay.js +125 -0
- package/dist/open-sse/utils/noThinkingAlias.js +1 -1
- package/dist/open-sse/utils/proxyFetch.js +0 -1
- package/dist/open-sse/utils/reasoningContentInjector.js +4 -7
- package/dist/open-sse/utils/responsesStatePolicy.js +1 -1
- package/dist/open-sse/utils/responsesStreamHelpers.js +1 -0
- package/dist/open-sse/utils/sessionManager.js +49 -22
- package/dist/open-sse/utils/stream.js +54 -77
- package/dist/open-sse/utils/streamHandler.js +19 -15
- package/dist/open-sse/utils/streamHelpers.js +2 -17
- package/dist/open-sse/utils/usageTracking.js +103 -12
- package/dist/routes/headroom/extras/route.js +58 -0
- package/dist/routes/headroom/restart/route.js +33 -0
- package/open-sse/config/appConstants.js +23 -79
- package/open-sse/config/errorConfig.js +0 -11
- package/open-sse/config/grokCli.js +10 -0
- package/open-sse/config/kiroConstants.js +99 -46
- package/open-sse/config/runtimeConfig.js +2 -0
- package/open-sse/config/ttsModels.js +2 -0
- package/open-sse/executors/antigravity.js +250 -164
- package/open-sse/executors/base.js +16 -11
- package/open-sse/executors/codex.js +269 -1108
- package/open-sse/executors/commandcode.js +10 -4
- package/open-sse/executors/cursor.js +96 -203
- package/open-sse/executors/default.js +146 -244
- package/open-sse/executors/github.js +128 -73
- package/open-sse/executors/grok-cli.js +527 -94
- package/open-sse/executors/grok-web.js +5 -7
- package/open-sse/executors/index.js +12 -0
- package/open-sse/executors/kiro.js +150 -61
- package/open-sse/executors/opencode-go.js +12 -4
- package/open-sse/executors/opencode.js +1 -1
- package/open-sse/executors/perplexity-web.js +20 -96
- package/open-sse/executors/qoder.js +28 -18
- package/open-sse/executors/vertex.js +53 -7
- package/open-sse/executors/xiaomi-tokenplan.js +6 -5
- package/open-sse/handlers/chatCore/nonStreamingHandler.js +97 -85
- package/open-sse/handlers/chatCore/requestDetail.js +32 -8
- package/open-sse/handlers/chatCore/sseToJsonHandler.js +13 -7
- package/open-sse/handlers/chatCore/streamingHandler.js +74 -25
- package/open-sse/handlers/chatCore.js +35 -41
- package/open-sse/handlers/embeddingProviders/index.js +1 -0
- package/open-sse/handlers/embeddingProviders/openai.js +8 -16
- package/open-sse/handlers/imageProviders/blackForestLabs.js +2 -21
- package/open-sse/handlers/imageProviders/cloudflareAi.js +2 -30
- package/open-sse/handlers/imageProviders/codex.js +2 -20
- package/open-sse/handlers/imageProviders/comfyui.js +5 -18
- package/open-sse/handlers/imageProviders/falAi.js +2 -22
- package/open-sse/handlers/imageProviders/gemini.js +2 -16
- package/open-sse/handlers/imageProviders/huggingface.js +2 -17
- package/open-sse/handlers/imageProviders/index.js +3 -4
- package/open-sse/handlers/imageProviders/leonardo.js +1 -1
- package/open-sse/handlers/imageProviders/nanobanana.js +4 -23
- package/open-sse/handlers/imageProviders/openai.js +15 -43
- package/open-sse/handlers/imageProviders/runwayml.js +2 -26
- package/open-sse/handlers/imageProviders/sdwebui.js +4 -20
- package/open-sse/handlers/imageProviders/stabilityAi.js +2 -26
- package/open-sse/handlers/imageProviders/weavy.js +1 -1
- package/open-sse/handlers/search/chatSearch.js +60 -14
- package/open-sse/handlers/ttsProviders/gemini.js +14 -3
- package/open-sse/handlers/ttsProviders/index.js +4 -2
- package/open-sse/handlers/ttsProviders/openai.js +4 -1
- package/open-sse/handlers/ttsProviders/openrouter.js +7 -4
- package/open-sse/handlers/videoCore.js +166 -0
- package/open-sse/handlers/videoProviders/weavy.js +1 -1
- package/open-sse/mcp-server/audit.js +1 -1
- package/open-sse/mcp-server/catalog.js +2 -2
- package/open-sse/mcp-server/descriptionCompressor.js +1 -1
- package/open-sse/mcp-server/mcpCallerIdentity.js +1 -1
- package/open-sse/mcp-server/schemas/tools.js +1 -1
- package/open-sse/mcp-server/server.js +4 -4
- package/open-sse/mcp-server/tools/advancedTools.js +5 -5
- package/open-sse/mcp-server/tools/agentSkillTools.js +1 -1
- package/open-sse/mcp-server/tools/compressionTools.js +4 -4
- package/open-sse/mcp-server/tools/gamificationTools.js +10 -10
- package/open-sse/mcp-server/tools/githubSkillTools.js +1 -1
- package/open-sse/mcp-server/tools/memoryTools.js +3 -3
- package/open-sse/mcp-server/tools/notionTools.js +2 -2
- package/open-sse/mcp-server/tools/obsidianTools.js +2 -2
- package/open-sse/mcp-server/tools/pickFastestModel.js +3 -3
- package/open-sse/mcp-server/tools/pluginTools.js +4 -4
- package/open-sse/mcp-server/tools/skillTools.js +2 -2
- package/open-sse/providers/capabilities.js +24 -4
- package/open-sse/providers/registry/alicode-intl.js +1 -1
- package/open-sse/providers/registry/anthropic.js +1 -8
- package/open-sse/providers/registry/codex.js +0 -9
- package/open-sse/providers/registry/cohere.js +0 -2
- package/open-sse/providers/registry/gemini.js +0 -2
- package/open-sse/providers/registry/github.js +9 -6
- package/open-sse/providers/registry/grok-cli.js +28 -18
- package/open-sse/providers/registry/index.js +74 -80
- package/open-sse/providers/registry/kiro.js +12 -0
- package/open-sse/providers/registry/mistral.js +0 -3
- package/open-sse/providers/registry/openai.js +0 -3
- package/open-sse/providers/registry/perplexity.js +0 -2
- package/open-sse/providers/registry/xai.js +5 -3
- package/open-sse/rtk/autodetect.js +10 -2
- package/open-sse/rtk/caveman.js +2 -93
- package/open-sse/rtk/cavemanPrompts.js +34 -2
- package/open-sse/rtk/constants.js +7 -2
- package/open-sse/rtk/headroom.js +133 -0
- package/open-sse/rtk/ponytail.js +1 -1
- package/open-sse/rtk/registry.js +2 -0
- package/open-sse/services/accountFallback.js +0 -108
- package/open-sse/services/combo/quotaExhaustionCutoff.js +2 -2
- package/open-sse/services/combo/quotaShareStrategy.js +1 -1
- package/open-sse/services/combo/resolveAutoStrategy.js +1 -1
- package/open-sse/services/combo/sessionStickiness.js +1 -1
- package/open-sse/services/combo/shadowRouting.js +1 -1
- package/open-sse/services/combo/targetSorters.js +4 -4
- package/open-sse/services/combo/validateQuality.js +1 -1
- package/open-sse/services/evalRouting.js +1 -1
- package/open-sse/services/grokCliModels.js +127 -0
- package/open-sse/services/model.js +7 -1
- package/open-sse/services/modelCapabilities.js +1 -1
- package/open-sse/services/modelFamilyFallback.js +1 -1
- package/open-sse/services/provider.js +1 -1
- package/open-sse/services/providerCooldownTracker.js +1 -1
- package/open-sse/services/rateLimitManager.js +1 -1
- package/open-sse/services/tokenRefresh/providers.js +3 -3
- package/open-sse/services/usage/codex.js +148 -214
- package/open-sse/services/usage/grok-cli.js +61 -7
- package/open-sse/services/usage/misc.js +0 -19
- package/open-sse/services/usage.js +0 -2
- package/open-sse/translator/concerns/paramSupport.js +2 -2
- package/open-sse/translator/concerns/thinkingUnified.js +6 -0
- package/open-sse/translator/index.js +97 -59
- package/open-sse/translator/request/claude-to-kiro.js +67 -40
- package/open-sse/translator/request/openai-responses.js +1 -0
- package/open-sse/translator/request/openai-to-commandcode.js +0 -4
- package/open-sse/translator/request/openai-to-kiro.js +49 -20
- package/open-sse/translator/response/commandcode-to-openai.js +0 -4
- package/open-sse/utils/bypassHandler.js +18 -3
- package/open-sse/utils/claudeCloaking.js +15 -5
- package/open-sse/utils/error.js +0 -17
- package/open-sse/utils/kiroSessionReplay.js +125 -0
- package/open-sse/utils/logger.js +1 -1
- package/open-sse/utils/proxyFetch.js +0 -1
- package/open-sse/utils/reasoningContentInjector.js +4 -7
- package/open-sse/utils/responsesStreamHelpers.js +1 -0
- package/open-sse/utils/sessionManager.js +49 -22
- package/open-sse/utils/stream.js +54 -77
- package/open-sse/utils/streamHandler.js +19 -15
- package/open-sse/utils/streamHelpers.js +2 -17
- package/open-sse/utils/usageTracking.js +103 -12
- package/package.json +4 -7
- package/public/assets/EndpointPageClient.C2WMTYy0.js +6 -0
- package/public/assets/{Loading.Bj-WGl4k.js → Loading.BHPtQ9vj.js} +1 -1
- package/public/assets/{NoAuthProxyCard.qAv57b-0.js → NoAuthProxyCard.BDcXaWvM.js} +1 -1
- package/public/assets/index.Be3gbrBl.js +89 -0
- package/public/assets/index.COMgQZYj.css +1 -0
- package/public/assets/{page.CbkENBd5.js → page.-lpNgYAw.js} +1 -1
- package/public/assets/{page.CssmrzTT.js → page.11hpNKmq.js} +1 -1
- package/public/assets/{page.C72FTTJr.js → page.B-LxsnqU.js} +1 -1
- package/public/assets/{page.sOFOrxqq.js → page.B-dzeIUC.js} +1 -1
- package/public/assets/{page.CsxWmPoI.js → page.B-nBR75u.js} +1 -1
- package/public/assets/{page.Dx_GRRdT.js → page.B3QqvLep.js} +1 -1
- package/public/assets/{page.DPyOkPVo.js → page.B8xdkCWA.js} +1 -1
- package/public/assets/{page.DUI8kqOY.js → page.BFb7yUd8.js} +1 -1
- package/public/assets/page.BbPPdoas.js +1 -0
- package/public/assets/page.BdS20a1O.js +1 -0
- package/public/assets/{page.DibhF7f-.js → page.BfmI9KYe.js} +1 -1
- package/public/assets/{page.DX4Nno6M.js → page.BgGJovOg.js} +1 -1
- package/public/assets/{page.BnmTC5jG.js → page.C0gBvR4O.js} +1 -1
- package/public/assets/{page.D5gj98Oe.js → page.C6bYizL7.js} +1 -1
- package/public/assets/{page.vla5Mzki.js → page.C8sLEMa6.js} +1 -1
- package/public/assets/{page.CXd_R9yU.js → page.CCNsZBXp.js} +1 -1
- package/public/assets/{page.CQlVGoXg.js → page.CF_YSLwP.js} +1 -1
- package/public/assets/{page.BbO1pspY.js → page.CPTtRDxw.js} +1 -1
- package/public/assets/{page.D1oKew1j.js → page.CdMmlUEm.js} +1 -1
- package/public/assets/{page.DxMDTbSx.js → page.Cged1bOZ.js} +1 -1
- package/public/assets/{page.Cj5h09Zo.js → page.Ch647dVk.js} +1 -1
- package/public/assets/{page.DVIHRbxB.js → page.CpvXDkQF.js} +1 -1
- package/public/assets/{page.i4KDuWcM.js → page.CrBl7f8N.js} +1 -1
- package/public/assets/{page.BSLJ4tx5.js → page.CrP7niA2.js} +1 -1
- package/public/assets/{page.CnTop8Zt.js → page.CvUFZzXr.js} +1 -1
- package/public/assets/{page.O2ddJYoT.js → page.CyUqJPmx.js} +1 -1
- package/public/assets/{page.DBhu4Arl.js → page.D8Rp8fFR.js} +1 -1
- package/public/assets/{page.CPZav1_c.js → page.Df9qtrdG.js} +1 -1
- package/public/assets/{page.Qkkv8roc.js → page.DiL4Gwqe.js} +1 -1
- package/public/assets/{page.BdmJ3yY3.js → page.Dl1apZE2.js} +1 -1
- package/public/assets/{page.1qjqvrwX.js → page.HV0w1d5C.js} +1 -1
- package/public/assets/{page.ChX1NqmC.js → page.N1x4YL8_.js} +1 -1
- package/public/assets/{page.Dh5f0XJC.js → page.P2Ny5veR.js} +1 -1
- package/public/assets/{page.CSs3-gdt.js → page.fOOCr18J.js} +1 -1
- package/public/assets/{page.Ir7KvKcF.js → page.sUIPWIiF.js} +1 -1
- package/public/assets/{page.CzlQTyAL.js → page.tE7PpWYW.js} +1 -1
- package/public/assets/{page.DzZLqI5Q.js → page.uziaGZsT.js} +1 -1
- package/public/index.html +2 -2
- package/public/assets/EndpointPageClient.LyNNvZ4z.js +0 -6
- package/public/assets/index.BuPfZebu.css +0 -1
- package/public/assets/index.CShjRV_B.js +0 -89
- package/public/assets/page.DD_czjjP.js +0 -1
|
@@ -9,10 +9,11 @@ import { createRequestLogger } from "../utils/requestLogger.js";
|
|
|
9
9
|
import { getModelTargetFormat, getModelStrip, getModelUpstreamId, getModelType, PROVIDER_ID_TO_ALIAS } from "../config/providerModels.js";
|
|
10
10
|
import { PROVIDERS } from "../config/providers.js";
|
|
11
11
|
import { createErrorResult, parseUpstreamError, formatProviderError } from "../utils/error.js";
|
|
12
|
-
import { HTTP_STATUS } from "../config/runtimeConfig.js";
|
|
12
|
+
import { HTTP_STATUS, TOKEN_SAVER_HEADER } from "../config/runtimeConfig.js";
|
|
13
13
|
import { handleBypassRequest } from "../utils/bypassHandler.js";
|
|
14
14
|
import { trackPendingRequest, appendRequestLog, saveRequestDetail } from '../../dist/lib/usageDb.js';
|
|
15
15
|
import { getExecutor } from "../executors/index.js";
|
|
16
|
+
import { supportsGrokCliReasoningEffort } from "../config/grokCli.js";
|
|
16
17
|
import { buildRequestDetail, extractRequestConfig } from "./chatCore/requestDetail.js";
|
|
17
18
|
import { handleForcedSSEToJson } from "./chatCore/sseToJsonHandler.js";
|
|
18
19
|
import { handleNonStreamingResponse } from "./chatCore/nonStreamingHandler.js";
|
|
@@ -21,8 +22,8 @@ import { detectClientTool, isNativePassthrough } from "../utils/clientDetector.j
|
|
|
21
22
|
import { dedupeTools } from "../utils/toolDeduper.js";
|
|
22
23
|
import { injectCaveman } from "../rtk/caveman.js";
|
|
23
24
|
import { injectPonytail } from "../rtk/ponytail.js";
|
|
24
|
-
import { compressMessages } from "../rtk/index.js";
|
|
25
|
-
import { compressWithHeadroom, formatHeadroomSizeLog, isHeadroomPhantomSavings } from "../rtk/headroom.js";
|
|
25
|
+
import { compressMessages, formatRtkLog } from "../rtk/index.js";
|
|
26
|
+
import { compressWithHeadroom, formatHeadroomLog, formatHeadroomSizeLog, isHeadroomPhantomSavings } from "../rtk/headroom.js";
|
|
26
27
|
import { compressWithPxpipe } from "../rtk/pxpipe.js";
|
|
27
28
|
import { getCapabilitiesForModel } from "../providers/capabilities.js";
|
|
28
29
|
import { stripUnsupportedModalities } from "../translator/concerns/modality.js";
|
|
@@ -168,7 +169,8 @@ export async function handleChatCore({ body, modelInfo, credentials, log, onCred
|
|
|
168
169
|
const msgN = translatedBody.messages?.length || translatedBody.input?.length || translatedBody.contents?.length || body.messages?.length || body.input?.length || 0;
|
|
169
170
|
const toolN = translatedBody.tools?.length || body.tools?.length || 0;
|
|
170
171
|
const fmtStr = passthrough ? `FMT: ${sourceFormat} (passthrough)` : `FMT: ${sourceFormat}→${targetFormat}`;
|
|
171
|
-
const
|
|
172
|
+
const showThinking = provider !== "grok-cli" || supportsGrokCliReasoningEffort(model);
|
|
173
|
+
const think = showThinking ? log.fmtThink?.(extractThinking(translatedBody)) : null;
|
|
172
174
|
const acc = credentials?.connectionName || credentials?.connectionId?.slice(0, 8) || "-";
|
|
173
175
|
const parts = [
|
|
174
176
|
`POST ${clientModel} → ${provider}/${model}`,
|
|
@@ -188,40 +190,37 @@ export async function handleChatCore({ body, modelInfo, credentials, log, onCred
|
|
|
188
190
|
delete translatedBody.tools;
|
|
189
191
|
}
|
|
190
192
|
|
|
191
|
-
//
|
|
192
|
-
const
|
|
193
|
+
// Per-request opt-out: client can bypass all token savers via header
|
|
194
|
+
const tokenSaverEnabled = clientRawRequest?.headers?.[TOKEN_SAVER_HEADER]?.toLowerCase() !== "off";
|
|
193
195
|
|
|
194
196
|
// RTK: compress tool_result content
|
|
195
|
-
const rtkStats = compressMessages(translatedBody, rtkEnabled);
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
const pct = rtkStats.bytesBefore > 0 ? ((saved / rtkStats.bytesBefore) * 100).toFixed(0) : "0";
|
|
199
|
-
xf.push(`RTK −${saved}B(${pct}%)`);
|
|
200
|
-
}
|
|
197
|
+
const rtkStats = compressMessages(translatedBody, tokenSaverEnabled && rtkEnabled);
|
|
198
|
+
const rtkLine = formatRtkLog(rtkStats);
|
|
199
|
+
if (rtkLine) console.log(rtkLine);
|
|
201
200
|
|
|
202
201
|
// Headroom: optional external proxy compression; fail open if proxy is absent.
|
|
203
202
|
const headroomDiagnostics = {};
|
|
204
|
-
const headroomStats = await compressWithHeadroom(translatedBody, { enabled: headroomEnabled, url: headroomUrl, model: upstreamModel, format: finalFormat, compressUserMessages: headroomCompressUserMessages, diagnostics: headroomDiagnostics });
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
xf.push(`HEADROOM −${delta}tok(${pct}%)`);
|
|
203
|
+
const headroomStats = await compressWithHeadroom(translatedBody, { enabled: tokenSaverEnabled && headroomEnabled, url: headroomUrl, model: upstreamModel, format: finalFormat, compressUserMessages: headroomCompressUserMessages, diagnostics: headroomDiagnostics });
|
|
204
|
+
const headroomLine = formatHeadroomLog(headroomStats);
|
|
205
|
+
const headroomSizeLine = formatHeadroomSizeLog(headroomDiagnostics);
|
|
206
|
+
if (headroomLine) {
|
|
207
|
+
log?.info?.("HEADROOM", `${headroomLine}${headroomSizeLine ? ` | ${headroomSizeLine}` : ""}`);
|
|
210
208
|
if (isHeadroomPhantomSavings(headroomStats, headroomDiagnostics)) {
|
|
211
209
|
log?.warn?.("HEADROOM", `reported token delta, but outbound JSON shrank <5%; provider may bill near-original payload | ${formatHeadroomSizeLog(headroomDiagnostics)}`);
|
|
212
210
|
}
|
|
213
|
-
} else if (headroomEnabled) {
|
|
214
|
-
|
|
215
|
-
|
|
211
|
+
} else if (tokenSaverEnabled && headroomEnabled) log?.warn?.("HEADROOM", `skipped: ${headroomDiagnostics.reason || "compression unavailable"}${headroomDiagnostics.endpoint ? ` (${headroomDiagnostics.endpoint})` : ""}`);
|
|
212
|
+
|
|
213
|
+
// Token-saver flags accumulator for the single "⚙" log line below.
|
|
214
|
+
const xf = [];
|
|
216
215
|
|
|
217
216
|
// Caveman: inject terse-style system prompt
|
|
218
|
-
if (cavemanEnabled && cavemanLevel) {
|
|
217
|
+
if (tokenSaverEnabled && cavemanEnabled && cavemanLevel) {
|
|
219
218
|
injectCaveman(translatedBody, finalFormat, cavemanLevel);
|
|
220
219
|
xf.push(`CAVEMAN:${cavemanLevel}`);
|
|
221
220
|
}
|
|
222
221
|
|
|
223
222
|
// Ponytail: inject lazy-senior-dev system prompt
|
|
224
|
-
if (ponytailEnabled && ponytailLevel) {
|
|
223
|
+
if (tokenSaverEnabled && ponytailEnabled && ponytailLevel) {
|
|
225
224
|
injectPonytail(translatedBody, finalFormat, ponytailLevel);
|
|
226
225
|
xf.push(`PONYTAIL:${ponytailLevel}`);
|
|
227
226
|
}
|
|
@@ -243,20 +242,19 @@ export async function handleChatCore({ body, modelInfo, credentials, log, onCred
|
|
|
243
242
|
|
|
244
243
|
const executor = getExecutor(provider);
|
|
245
244
|
trackPendingRequest(model, provider, connectionId, true);
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
});
|
|
245
|
+
appendRequestLog({ model, provider, connectionId, status: "PENDING" }).catch(() => { });
|
|
246
|
+
|
|
247
|
+
const msgCount = translatedBody.messages?.length || translatedBody.input?.length || translatedBody.contents?.length || translatedBody.request?.contents?.length || 0;
|
|
248
|
+
log?.debug?.("REQUEST", `${provider.toUpperCase()} | ${model} | ${msgCount} msgs`);
|
|
249
|
+
|
|
250
|
+
const streamController = createStreamController({
|
|
251
|
+
onDisconnect: (reason) => {
|
|
252
|
+
trackPendingRequest(model, provider, connectionId, false);
|
|
253
|
+
if (onDisconnect) onDisconnect(reason);
|
|
254
|
+
},
|
|
255
|
+
onError: () => trackPendingRequest(model, provider, connectionId, false),
|
|
256
|
+
log, provider, model, reqTag
|
|
257
|
+
});
|
|
260
258
|
|
|
261
259
|
const proxyOptions = {
|
|
262
260
|
connectionProxyEnabled: credentials?.providerSpecificData?.connectionProxyEnabled === true,
|
|
@@ -392,10 +390,6 @@ export async function handleChatCore({ body, modelInfo, credentials, log, onCred
|
|
|
392
390
|
// Streaming response
|
|
393
391
|
const { onStreamComplete, streamDetailId } = buildOnStreamComplete({ ...sharedCtx });
|
|
394
392
|
return handleStreamingResponse({ ...sharedCtx, providerResponse, sourceFormat, targetFormat, userAgent, reqLogger, toolNameMap, streamController, onStreamComplete, streamDetailId });
|
|
395
|
-
} catch (error) {
|
|
396
|
-
trackPendingRequest(model, provider, connectionId, false);
|
|
397
|
-
throw error;
|
|
398
|
-
}
|
|
399
393
|
}
|
|
400
394
|
|
|
401
395
|
export function isTokenExpiringSoon(expiresAt, bufferMs = 5 * 60 * 1000) {
|
|
@@ -1,29 +1,21 @@
|
|
|
1
1
|
// OpenAI-compatible embeddings adapter (most providers)
|
|
2
2
|
import { bearerAuth } from "./_base.js";
|
|
3
|
+
import { PROVIDER_MEDIA } from "../../providers/index.js";
|
|
3
4
|
|
|
5
|
+
// media-only providers without a registry file keep URL here; rest derive from registry media.embeddingConfig.baseUrl
|
|
4
6
|
const ENDPOINTS = {
|
|
5
|
-
openai: "https://api.openai.com/v1/embeddings",
|
|
6
|
-
openrouter: "https://openrouter.ai/api/v1/embeddings",
|
|
7
|
-
mistral: "https://api.mistral.ai/v1/embeddings",
|
|
8
|
-
"voyage-ai": "https://api.voyageai.com/v1/embeddings",
|
|
9
|
-
fireworks: "https://api.fireworks.ai/inference/v1/embeddings",
|
|
10
|
-
together: "https://api.together.xyz/v1/embeddings",
|
|
11
|
-
nebius: "https://api.tokenfactory.nebius.com/v1/embeddings",
|
|
12
|
-
github: "https://models.github.ai/inference/embeddings",
|
|
13
|
-
nvidia: "https://integrate.api.nvidia.com/v1/embeddings",
|
|
14
7
|
"jina-ai": "https://api.jina.ai/v1/embeddings",
|
|
15
8
|
};
|
|
16
9
|
|
|
10
|
+
const embedCfg = (id) => PROVIDER_MEDIA[id]?.embeddingConfig || {};
|
|
11
|
+
const embedUrl = (id) => embedCfg(id).baseUrl || ENDPOINTS[id];
|
|
12
|
+
|
|
17
13
|
export default function createOpenAIEmbeddingAdapter(providerId) {
|
|
14
|
+
const cfg = embedCfg(providerId);
|
|
18
15
|
return {
|
|
19
|
-
buildUrl: () =>
|
|
16
|
+
buildUrl: () => embedUrl(providerId),
|
|
20
17
|
buildHeaders: (creds) => {
|
|
21
|
-
|
|
22
|
-
if (providerId === "openrouter") {
|
|
23
|
-
headers["HTTP-Referer"] = "https://endpoint-proxy.local";
|
|
24
|
-
headers["X-Title"] = "Endpoint Proxy";
|
|
25
|
-
}
|
|
26
|
-
return headers;
|
|
18
|
+
return { "Content-Type": "application/json", ...bearerAuth(creds), ...(cfg.headers || {}) };
|
|
27
19
|
},
|
|
28
20
|
buildBody: (model, { input, encoding_format, dimensions }) => {
|
|
29
21
|
const body = { model, input };
|
|
@@ -1,27 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Black Forest Labs FLUX API adapter.
|
|
3
|
-
*
|
|
4
|
-
* Providers: black-forest-labs
|
|
5
|
-
* Auth: x-key header (not Authorization Bearer) — uses apiKey or accessToken
|
|
6
|
-
* Format: JSON body → async polling via task result URL
|
|
7
|
-
* Polling: Yes — polls until status == "Ready"
|
|
8
|
-
*
|
|
9
|
-
* Supported request params:
|
|
10
|
-
* @param {string} prompt - (required) Image description
|
|
11
|
-
* @param {string} [model] - Model ID (e.g. "flux-pro-1.1", "flux-kontext-pro")
|
|
12
|
-
* @param {string} [size] - Dimensions → parsed to width/height integers
|
|
13
|
-
* @param {number} [seed] - Fixed seed
|
|
14
|
-
* @param {number} [guidance] - Guidance scale
|
|
15
|
-
* @param {number} [num_steps] - Diffusion steps
|
|
16
|
-
* @param {string} [output_format="jpeg"] - "jpeg"|"png"|"webp"
|
|
17
|
-
* @param {string} [image_url] - Reference image (Kontext edit models only)
|
|
18
|
-
*
|
|
19
|
-
* Response normalize: result.sample → { created, data: [{ url }] }.
|
|
20
|
-
*/
|
|
21
1
|
// Black Forest Labs (FLUX) — async submit + polling_url
|
|
22
2
|
import { sleep, nowSec, POLL_INTERVAL_MS, POLL_TIMEOUT_MS } from "./_base.js";
|
|
3
|
+
import { PROVIDER_MEDIA } from "../../providers/index.js";
|
|
23
4
|
|
|
24
|
-
const BASE_URL = "
|
|
5
|
+
const BASE_URL = PROVIDER_MEDIA["black-forest-labs"]?.imageConfig?.baseUrl;
|
|
25
6
|
|
|
26
7
|
export default {
|
|
27
8
|
async: true,
|
|
@@ -1,35 +1,7 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cloudflare AI Workers image generation adapter.
|
|
3
|
-
*
|
|
4
|
-
* Providers: cloudflare-ai
|
|
5
|
-
* Auth: Bearer token via Authorization header
|
|
6
|
-
* Requires providerSpecificData.accountId for endpoint construction.
|
|
7
|
-
* Format: JSON body OR FormData (model-dependent) → sync base64 response
|
|
8
|
-
* Polling: None (synchronous)
|
|
9
|
-
*
|
|
10
|
-
* Endpoint: https://api.cloudflare.com/client/v4/accounts/{accountId}/ai/run/{model}
|
|
11
|
-
*
|
|
12
|
-
* Supported request params:
|
|
13
|
-
* @param {string} prompt - (required) Image description
|
|
14
|
-
* @param {string} [size] - Parsed to width/height integers (e.g. "1024x1024")
|
|
15
|
-
* @param {number} [seed] - Fixed seed
|
|
16
|
-
* @param {number} [num_steps] - Diffusion steps
|
|
17
|
-
* @param {number} [guidance] - CFG guidance scale
|
|
18
|
-
* @param {string} [negative_prompt] - Elements to exclude
|
|
19
|
-
* @param {string} [image_url] - Reference image for img2img (SD v1.5-img2img)
|
|
20
|
-
* @param {string} [mask_image] - Mask image for inpainting (SD v1.5-inpainting)
|
|
21
|
-
*
|
|
22
|
-
* Body format:
|
|
23
|
-
* - FLUX.2 Dev and similar multipart-only models → FormData
|
|
24
|
-
* - All other models → JSON { prompt, width, height, ... }
|
|
25
|
-
*
|
|
26
|
-
* Response normalize:
|
|
27
|
-
* - string → { data: [{ b64_json: result }] }
|
|
28
|
-
* - { image: b64 } → { data: [{ b64_json: image }] }
|
|
29
|
-
*/
|
|
30
1
|
import { nowSec, urlToBase64 } from "./_base.js";
|
|
2
|
+
import { PROVIDER_MEDIA } from "../../providers/index.js";
|
|
31
3
|
|
|
32
|
-
const BASE_URL = "
|
|
4
|
+
const BASE_URL = PROVIDER_MEDIA["cloudflare-ai"]?.imageConfig?.baseUrl;
|
|
33
5
|
|
|
34
6
|
const MULTIPART_MODELS = new Set([
|
|
35
7
|
"@cf/black-forest-labs/flux-2-dev",
|
|
@@ -1,27 +1,9 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* OpenAI Codex (Responses API) image generation adapter.
|
|
3
|
-
*
|
|
4
|
-
* Providers: codex (ChatGPT Plus/Pro accounts via OAuth session)
|
|
5
|
-
* Auth: Bearer session token + chatgpt-account-id header
|
|
6
|
-
* Format: JSON body → SSE stream (parses image_generation_call delta events)
|
|
7
|
-
* Polling: None (streaming SSE)
|
|
8
|
-
*
|
|
9
|
-
* Supported request params:
|
|
10
|
-
* @param {string} prompt - (required) Image description
|
|
11
|
-
* @param {string} [model="gpt-4o"] - Model ID ("-image" suffix is stripped automatically)
|
|
12
|
-
* @param {string} [size="1024x1024"] - Dimensions: "1024x1024"|"1792x1024"|"1024x1792"|"1536x1024"|"1024x1536"
|
|
13
|
-
* @param {string} [quality="auto"] - "low"|"medium"|"high"|"auto"
|
|
14
|
-
* @param {string} [output_format="png"] - "png"|"jpeg"|"webp"
|
|
15
|
-
* @param {string} [background="auto"] - "auto"|"transparent"|"opaque"
|
|
16
|
-
* @param {string} [image_detail="high"] - "low"|"high"|"auto"
|
|
17
|
-
* @param {string} [image] - Reference image URL or base64 data URI
|
|
18
|
-
* @param {string[]} [images] - Multiple reference images
|
|
19
|
-
*/
|
|
20
1
|
// Codex (ChatGPT Plus/Pro) image generation via Responses API + SSE
|
|
21
2
|
import { randomUUID } from "node:crypto";
|
|
22
3
|
import { nowSec } from "./_base.js";
|
|
4
|
+
import { PROVIDERS } from "../../config/providers.js";
|
|
23
5
|
|
|
24
|
-
const CODEX_RESPONSES_URL = "
|
|
6
|
+
const CODEX_RESPONSES_URL = PROVIDERS["codex"].baseUrl;
|
|
25
7
|
const CODEX_USER_AGENT = "codex_cli_rs/0.136.0";
|
|
26
8
|
const CODEX_VERSION = "0.136.0";
|
|
27
9
|
const CODEX_ORIGINATOR = "codex_cli_rs";
|
|
@@ -1,24 +1,11 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ComfyUI local node-graph image generation adapter.
|
|
3
|
-
*
|
|
4
|
-
* Providers: comfyui (self-hosted instance)
|
|
5
|
-
* Auth: None (unauthenticated local endpoint)
|
|
6
|
-
* Format: JSON workflow prompt → async polling via /history endpoint
|
|
7
|
-
* Polling: Yes — submits prompt then polls /history/{prompt_id}
|
|
8
|
-
*
|
|
9
|
-
* Supported request params:
|
|
10
|
-
* @param {string} prompt - (required) Positive prompt text
|
|
11
|
-
* @param {number} [n=1] - Number of images
|
|
12
|
-
* @param {string} [size] - Dimensions → width/height in workflow
|
|
13
|
-
* @param {number} [seed] - Fixed seed
|
|
14
|
-
* @param {number} [num_steps] - Sampling steps
|
|
15
|
-
*
|
|
16
|
-
* Response normalize: downloads generated images and converts to base64.
|
|
17
|
-
*/
|
|
18
1
|
// ComfyUI — local, noAuth (placeholder; full graph workflow not implemented)
|
|
2
|
+
import { PROVIDER_MEDIA } from "../../providers/index.js";
|
|
3
|
+
|
|
4
|
+
const BASE_URL = PROVIDER_MEDIA["comfyui"]?.imageConfig?.baseUrl;
|
|
5
|
+
|
|
19
6
|
export default {
|
|
20
7
|
noAuth: true,
|
|
21
|
-
buildUrl: () =>
|
|
8
|
+
buildUrl: () => BASE_URL,
|
|
22
9
|
buildHeaders: () => ({ "Content-Type": "application/json" }),
|
|
23
10
|
buildBody: (_model, body) => ({ prompt: body.prompt }),
|
|
24
11
|
normalize: (responseBody) => responseBody,
|
|
@@ -1,28 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Fal.ai asynchronous image generation adapter.
|
|
3
|
-
*
|
|
4
|
-
* Providers: fal-ai
|
|
5
|
-
* Auth: Key {apiKey} via Authorization header (uses "Key" prefix, not "Bearer")
|
|
6
|
-
* Format: JSON body → async queue submission + polling
|
|
7
|
-
* Polling: Yes — submits to /runs, polls /requests/{id}/status, fetches /requests/{id}
|
|
8
|
-
*
|
|
9
|
-
* Supported request params:
|
|
10
|
-
* @param {string} prompt - (required) Image description
|
|
11
|
-
* @param {string} [model] - Model path (e.g. "fal-ai/flux/schnell")
|
|
12
|
-
* @param {number} [n=1] - Number of images (num_images)
|
|
13
|
-
* @param {string} [size="1024x1024"] - Maps to image_size aspect ratio: "1:1"|"16:9"|"9:16" etc.
|
|
14
|
-
* @param {number} [seed] - Fixed seed for reproducibility
|
|
15
|
-
* @param {number} [guidance] - Guidance scale (model-dependent)
|
|
16
|
-
* @param {number} [num_steps] - Diffusion sampling steps
|
|
17
|
-
* @param {string} [style] - Style preset (Recraft/Ideogram only)
|
|
18
|
-
* @param {string} [image] - Reference image URL (img2img conditioning)
|
|
19
|
-
*
|
|
20
|
-
* Response normalize: maps images[] or image{} to { created, data: [{ url }] }.
|
|
21
|
-
*/
|
|
22
1
|
// Fal.ai — async submit + queue polling
|
|
23
2
|
import { sleep, nowSec, sizeToAspectRatio, POLL_INTERVAL_MS, POLL_TIMEOUT_MS } from "./_base.js";
|
|
3
|
+
import { PROVIDER_MEDIA } from "../../providers/index.js";
|
|
24
4
|
|
|
25
|
-
const BASE_URL = "
|
|
5
|
+
const BASE_URL = PROVIDER_MEDIA["fal-ai"]?.imageConfig?.baseUrl;
|
|
26
6
|
|
|
27
7
|
export default {
|
|
28
8
|
async: true,
|
|
@@ -1,22 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Google Gemini multimodal image generation adapter.
|
|
3
|
-
*
|
|
4
|
-
* Providers: gemini (via NanoBanana tier routing)
|
|
5
|
-
* Auth: API key appended as ?key= query param
|
|
6
|
-
* Format: JSON body → sync JSON response (generateContent / generateImage)
|
|
7
|
-
* Polling: None (synchronous)
|
|
8
|
-
*
|
|
9
|
-
* Supported request params:
|
|
10
|
-
* @param {string} prompt - (required) Image description text
|
|
11
|
-
*
|
|
12
|
-
* Notes:
|
|
13
|
-
* - No size, quality, or style params are supported by the Gemini image endpoint.
|
|
14
|
-
* - Response is normalized to { created, data: [{ b64_json, revised_prompt }] }.
|
|
15
|
-
*/
|
|
16
1
|
// Google Gemini adapter (Nano Banana models)
|
|
17
2
|
import { nowSec } from "./_base.js";
|
|
3
|
+
import { PROVIDER_MEDIA } from "../../providers/index.js";
|
|
18
4
|
|
|
19
|
-
const BASE_URL = "
|
|
5
|
+
const BASE_URL = PROVIDER_MEDIA["gemini"]?.imageConfig?.baseUrl;
|
|
20
6
|
|
|
21
7
|
export default {
|
|
22
8
|
buildUrl: (model, creds) => {
|
|
@@ -1,23 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* HuggingFace Inference API image generation adapter.
|
|
3
|
-
*
|
|
4
|
-
* Providers: huggingface
|
|
5
|
-
* Auth: Bearer token via Authorization header (apiKey or accessToken)
|
|
6
|
-
* Format: JSON body { inputs: prompt } → binary image response (PNG/JPEG)
|
|
7
|
-
* Polling: None (synchronous, may queue on HF side)
|
|
8
|
-
*
|
|
9
|
-
* Supported request params:
|
|
10
|
-
* @param {string} prompt - (required) Image description text
|
|
11
|
-
*
|
|
12
|
-
* Notes:
|
|
13
|
-
* - Only "inputs" (prompt) is accepted by the HF Inference endpoint.
|
|
14
|
-
* - No size, quality, style, or other params are passed through.
|
|
15
|
-
* - Response normalize: converts raw binary image to base64 data URI.
|
|
16
|
-
*/
|
|
17
1
|
// HuggingFace Inference API — returns binary image
|
|
18
2
|
import { nowSec } from "./_base.js";
|
|
3
|
+
import { PROVIDER_MEDIA } from "../../providers/index.js";
|
|
19
4
|
|
|
20
|
-
const BASE_URL = "
|
|
5
|
+
const BASE_URL = PROVIDER_MEDIA["huggingface"]?.imageConfig?.baseUrl;
|
|
21
6
|
|
|
22
7
|
export default {
|
|
23
8
|
buildUrl: (model) => `${BASE_URL}/${model}`,
|
|
@@ -11,14 +11,14 @@ import stabilityAi from "./stabilityAi.js";
|
|
|
11
11
|
import blackForestLabs from "./blackForestLabs.js";
|
|
12
12
|
import runwayml from "./runwayml.js";
|
|
13
13
|
import cloudflareAi from "./cloudflareAi.js";
|
|
14
|
-
import
|
|
15
|
-
import weavy from "./weavy.js";
|
|
14
|
+
import antigravity from "./antigravity.js";
|
|
16
15
|
|
|
17
16
|
const ADAPTERS = {
|
|
18
17
|
openai: createOpenAIAdapter("openai"),
|
|
19
18
|
minimax: createOpenAIAdapter("minimax"),
|
|
20
19
|
openrouter: createOpenAIAdapter("openrouter"),
|
|
21
20
|
recraft: createOpenAIAdapter("recraft"),
|
|
21
|
+
"vercel-ai-gateway": createOpenAIAdapter("vercel-ai-gateway"),
|
|
22
22
|
xai: createOpenAIAdapter("xai"),
|
|
23
23
|
gemini,
|
|
24
24
|
codex,
|
|
@@ -26,13 +26,12 @@ const ADAPTERS = {
|
|
|
26
26
|
comfyui,
|
|
27
27
|
huggingface,
|
|
28
28
|
nanobanana,
|
|
29
|
+
antigravity,
|
|
29
30
|
"fal-ai": falAi,
|
|
30
31
|
"stability-ai": stabilityAi,
|
|
31
32
|
"black-forest-labs": blackForestLabs,
|
|
32
33
|
runwayml,
|
|
33
34
|
"cloudflare-ai": cloudflareAi,
|
|
34
|
-
leonardo,
|
|
35
|
-
weavy,
|
|
36
35
|
};
|
|
37
36
|
|
|
38
37
|
export function getImageAdapter(provider) {
|
|
@@ -34,7 +34,7 @@ import { randomBytes } from "crypto";
|
|
|
34
34
|
// Falls back to empty object if DB not available (e.g., first boot).
|
|
35
35
|
async function getLeonardoAdminConfig() {
|
|
36
36
|
try {
|
|
37
|
-
const { getAdapter } = await import('
|
|
37
|
+
const { getAdapter } = await import('../../dist/lib/db/driver.js');
|
|
38
38
|
const db = await getAdapter();
|
|
39
39
|
const row = db.get(`SELECT value FROM kv WHERE scope = 'leonardo' AND key = 'admin_config'`);
|
|
40
40
|
if (!row?.value) return null;
|
|
@@ -1,29 +1,10 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* NanoBanana image generation adapter.
|
|
3
|
-
*
|
|
4
|
-
* Providers: nanobanana
|
|
5
|
-
* Auth: Bearer token (apiKey or accessToken)
|
|
6
|
-
* Format: JSON body → async polling via task status endpoint
|
|
7
|
-
* Polling: Yes — polls until resultImageUrl is available
|
|
8
|
-
*
|
|
9
|
-
* Supported request params:
|
|
10
|
-
* @param {string} prompt - (required) Image description
|
|
11
|
-
* @param {number} [n=1] - Number of images (numImages)
|
|
12
|
-
* @param {string} [size="1024x1024"] - Maps to aspect ratio: "1:1"|"9:16"|"16:9"|"4:3"|"3:2"|"2:3"
|
|
13
|
-
* @param {string} [image] - Reference image URL → enables IMAGETOIAMGE mode
|
|
14
|
-
* @param {string[]} [images] - Multiple reference image URLs
|
|
15
|
-
*
|
|
16
|
-
* Request type:
|
|
17
|
-
* - No image → type: "TEXTTOIAMGE"
|
|
18
|
-
* - image/images provided → type: "IMAGETOIAMGE"
|
|
19
|
-
*
|
|
20
|
-
* Response normalize: extracts resultImageUrl (falls back to originImageUrl).
|
|
21
|
-
*/
|
|
22
1
|
// NanoBanana API — async submit + poll record-info
|
|
23
2
|
import { sleep, nowSec, sizeToAspectRatio, POLL_INTERVAL_MS, POLL_TIMEOUT_MS } from "./_base.js";
|
|
3
|
+
import { PROVIDER_MEDIA } from "../../providers/index.js";
|
|
24
4
|
|
|
25
|
-
const
|
|
26
|
-
const
|
|
5
|
+
const IMG_CFG = PROVIDER_MEDIA["nanobanana"]?.imageConfig || {};
|
|
6
|
+
const SUBMIT_URL = IMG_CFG.baseUrl;
|
|
7
|
+
const POLL_BASE = IMG_CFG.pollUrl;
|
|
27
8
|
|
|
28
9
|
export default {
|
|
29
10
|
async: true,
|
|
@@ -1,60 +1,32 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* OpenAI-compatible image generation adapter.
|
|
3
|
-
*
|
|
4
|
-
* Providers: openai | minimax | openrouter | recraft | xai
|
|
5
|
-
* Auth: Bearer token via Authorization header (apiKey or accessToken)
|
|
6
|
-
* Format: JSON body → sync JSON response
|
|
7
|
-
* Polling: None (synchronous)
|
|
8
|
-
*
|
|
9
|
-
* Supported request params:
|
|
10
|
-
* @param {string} prompt - (required) Image description
|
|
11
|
-
* @param {string} [model] - Model ID (set by caller)
|
|
12
|
-
* @param {number} [n=1] - Number of images (1–10 for DALL-E 2; 1 for DALL-E 3/GPT Image 1)
|
|
13
|
-
* @param {string} [size="1024x1024"] - Dimensions: "256x256"|"512x512"|"1024x1024"|"1792x1024"|"1024x1792"
|
|
14
|
-
* @param {string} [quality="standard"] - "standard"|"hd"|"low"|"medium"|"high"|"auto"
|
|
15
|
-
* @param {string} [style] - DALL-E 3 only: "vivid"|"natural"
|
|
16
|
-
* @param {string} [response_format="url"] - "url"|"b64_json"
|
|
17
|
-
* @param {string} [output_format] - GPT Image 1 only: "png"|"jpeg"|"webp"
|
|
18
|
-
* @param {string} [background] - GPT Image 1 only: "auto"|"transparent"|"opaque"
|
|
19
|
-
*
|
|
20
|
-
* xAI note: only prompt, model, n, response_format are forwarded.
|
|
21
|
-
*/
|
|
22
1
|
// OpenAI-compatible adapter (used by openai, minimax, openrouter, recraft)
|
|
2
|
+
import { PROVIDER_MEDIA } from "../../providers/index.js";
|
|
23
3
|
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
minimax: "https://api.minimaxi.com/v1/images/generations",
|
|
27
|
-
openrouter: "https://openrouter.ai/api/v1/images/generations",
|
|
28
|
-
recraft: "https://external.api.recraft.ai/v1/images/generations",
|
|
29
|
-
xai: "https://api.x.ai/v1/images/generations",
|
|
30
|
-
};
|
|
4
|
+
const imageCfg = (id) => PROVIDER_MEDIA[id]?.imageConfig || {};
|
|
5
|
+
const imageUrl = (id) => imageCfg(id).baseUrl;
|
|
31
6
|
|
|
32
7
|
export default function createOpenAIAdapter(providerId) {
|
|
8
|
+
const cfg = imageCfg(providerId);
|
|
33
9
|
return {
|
|
34
|
-
buildUrl: () =>
|
|
10
|
+
buildUrl: () => imageUrl(providerId),
|
|
35
11
|
buildHeaders: (creds) => {
|
|
36
|
-
const headers = { "Content-Type": "application/json" };
|
|
12
|
+
const headers = { "Content-Type": "application/json", ...(cfg.headers || {}) };
|
|
37
13
|
const key = creds?.apiKey || creds?.accessToken;
|
|
38
14
|
if (key) headers["Authorization"] = `Bearer ${key}`;
|
|
39
|
-
if (providerId === "openrouter") {
|
|
40
|
-
headers["HTTP-Referer"] = "https://endpoint-proxy.local";
|
|
41
|
-
headers["X-Title"] = "Endpoint Proxy";
|
|
42
|
-
}
|
|
43
15
|
return headers;
|
|
44
16
|
},
|
|
45
17
|
buildBody: (model, body) => {
|
|
46
18
|
const { prompt, n = 1, size = "1024x1024", quality, style, response_format } = body;
|
|
47
|
-
|
|
48
|
-
if (
|
|
49
|
-
|
|
50
|
-
|
|
19
|
+
const full = { model, prompt, n, size };
|
|
20
|
+
if (quality) full.quality = quality;
|
|
21
|
+
if (style) full.style = style;
|
|
22
|
+
if (response_format) full.response_format = response_format;
|
|
23
|
+
// bodyFields whitelist (e.g. xAI accepts only model/prompt/n/response_format)
|
|
24
|
+
if (Array.isArray(cfg.bodyFields)) {
|
|
25
|
+
const req = {};
|
|
26
|
+
for (const f of cfg.bodyFields) if (full[f] !== undefined) req[f] = full[f];
|
|
51
27
|
return req;
|
|
52
28
|
}
|
|
53
|
-
|
|
54
|
-
if (quality) req.quality = quality;
|
|
55
|
-
if (style) req.style = style;
|
|
56
|
-
if (response_format) req.response_format = response_format;
|
|
57
|
-
return req;
|
|
29
|
+
return full;
|
|
58
30
|
},
|
|
59
31
|
normalize: (responseBody) => responseBody,
|
|
60
32
|
};
|
|
@@ -1,32 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* RunwayML image and video generation adapter.
|
|
3
|
-
*
|
|
4
|
-
* Providers: runwayml
|
|
5
|
-
* Auth: Bearer token + X-Runway-Version header
|
|
6
|
-
* Format: JSON body → async polling
|
|
7
|
-
* Polling: Yes — polls task ID until status == "SUCCEEDED"
|
|
8
|
-
*
|
|
9
|
-
* Model routing:
|
|
10
|
-
* - "*_image*" model IDs → POST /text_to_image (image generation)
|
|
11
|
-
* - all others → POST /image_to_video (video generation)
|
|
12
|
-
*
|
|
13
|
-
* Image model params:
|
|
14
|
-
* @param {string} prompt - (required) Image description (sent as promptText)
|
|
15
|
-
* @param {string} [size] - Maps to ratio: "1:1"|"16:9"|"9:16" etc.
|
|
16
|
-
* @param {string} [image] - Reference image URL (referenceImages[])
|
|
17
|
-
*
|
|
18
|
-
* Video model params:
|
|
19
|
-
* @param {string} prompt - (required) Video description (promptText)
|
|
20
|
-
* @param {string} [image] - Start frame URL (promptImage)
|
|
21
|
-
* @param {number} [duration=5] - Video duration in seconds
|
|
22
|
-
* @param {string} [resolution] - "720p"|"1080p"
|
|
23
|
-
*
|
|
24
|
-
* Response normalize: output[] → { created, data: [{ url }] }.
|
|
25
|
-
*/
|
|
26
1
|
// Runway ML — async submit + /tasks/{id} polling
|
|
27
2
|
import { sleep, nowSec, sizeToAspectRatio, POLL_INTERVAL_MS, POLL_TIMEOUT_MS } from "./_base.js";
|
|
3
|
+
import { PROVIDER_MEDIA } from "../../providers/index.js";
|
|
28
4
|
|
|
29
|
-
const BASE_URL = "
|
|
5
|
+
const BASE_URL = PROVIDER_MEDIA["runwayml"]?.imageConfig?.baseUrl;
|
|
30
6
|
|
|
31
7
|
export default {
|
|
32
8
|
async: true,
|
|
@@ -1,28 +1,12 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Stable Diffusion WebUI (Automatic1111) local adapter.
|
|
3
|
-
*
|
|
4
|
-
* Providers: sdwebui (self-hosted instance)
|
|
5
|
-
* Auth: Optional HTTP Basic auth (username/password)
|
|
6
|
-
* Format: JSON body → sync JSON response
|
|
7
|
-
* Polling: None (synchronous, but can be slow)
|
|
8
|
-
*
|
|
9
|
-
* Supported request params:
|
|
10
|
-
* @param {string} prompt - (required) Positive prompt
|
|
11
|
-
* @param {number} [n=1] - Number of images (batch_size)
|
|
12
|
-
* @param {string} [size="512x512"] - Dimensions e.g. "512x512", "768x768" → width/height
|
|
13
|
-
* @param {string} [negative_prompt] - Tokens to exclude
|
|
14
|
-
* @param {number} [seed] - Fixed seed (-1 = random)
|
|
15
|
-
* @param {number} [guidance=7] - CFG scale
|
|
16
|
-
* @param {number} [num_steps=20] - Sampling steps
|
|
17
|
-
*
|
|
18
|
-
* Response normalize: extracts images[0] → { created, data: [{ b64_json }] }.
|
|
19
|
-
*/
|
|
20
1
|
// SD WebUI (AUTOMATIC1111) — local, noAuth
|
|
21
2
|
import { nowSec } from "./_base.js";
|
|
3
|
+
import { PROVIDER_MEDIA } from "../../providers/index.js";
|
|
4
|
+
|
|
5
|
+
const BASE_URL = PROVIDER_MEDIA["sdwebui"]?.imageConfig?.baseUrl;
|
|
22
6
|
|
|
23
7
|
export default {
|
|
24
8
|
noAuth: true,
|
|
25
|
-
buildUrl: () =>
|
|
9
|
+
buildUrl: () => BASE_URL,
|
|
26
10
|
buildHeaders: () => ({ "Content-Type": "application/json" }),
|
|
27
11
|
buildBody: (_model, body) => {
|
|
28
12
|
const { prompt, n = 1, size = "1024x1024" } = body;
|