@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
|
@@ -1,6 +1,21 @@
|
|
|
1
|
-
import { execSync } from "child_process";
|
|
1
|
+
import { execFileSync, execSync } from "child_process";
|
|
2
2
|
import path from "path";
|
|
3
3
|
|
|
4
|
+
// Extras that improve headroom compression quality. `proxy` is the base;
|
|
5
|
+
// `code` adds tree-sitter AST compression; `ml` adds Kompress-v2 HF model.
|
|
6
|
+
// Other `[all]` extras (image, voice, otel, reports, evals, ...) are not
|
|
7
|
+
// useful for the 9router proxy use case, so we don't track them here.
|
|
8
|
+
export const HEADROOM_COMPRESSION_EXTRAS = ["code", "ml"];
|
|
9
|
+
|
|
10
|
+
// Marker packages that each extra pulls in. Detected from `pip list --format=json`
|
|
11
|
+
// so one call can answer both the installed version and active extras.
|
|
12
|
+
export const EXTRA_MARKERS = {
|
|
13
|
+
code: ["tree-sitter", "tree-sitter-language-pack"],
|
|
14
|
+
ml: ["torch", "huggingface-hub"],
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const HEADROOM_PIP_TIMEOUT_MS = 8000;
|
|
18
|
+
|
|
4
19
|
const IS_WIN = process.platform === "win32";
|
|
5
20
|
const WHICH_CMD = IS_WIN ? "where" : "which";
|
|
6
21
|
|
|
@@ -49,8 +64,33 @@ export function findHeadroomBinary() {
|
|
|
49
64
|
}
|
|
50
65
|
|
|
51
66
|
// Find a Python interpreter >= 3.10 (headroom-ai requires it). Returns null if none.
|
|
67
|
+
// `python3`, `python3.13`, `python` can point at different envs on any OS. Prefer
|
|
68
|
+
// the interpreter that can also see the installed `headroom-ai` package so the
|
|
69
|
+
// dashboard probes and install action operate on the same interpreter as the CLI.
|
|
70
|
+
// Falls back to the first version-eligible candidate when headroom-ai is not yet
|
|
71
|
+
// installed anywhere (needed for the initial install).
|
|
72
|
+
// Interpreters to probe, most specific first: the python next to the headroom
|
|
73
|
+
// binary (guaranteed to have headroom-ai), then full paths from EXTRA_BINS, then
|
|
74
|
+
// bare names resolved via PATH.
|
|
75
|
+
function pythonCandidates() {
|
|
76
|
+
const list = [];
|
|
77
|
+
const bin = findHeadroomBinary();
|
|
78
|
+
if (bin) {
|
|
79
|
+
const dir = path.dirname(bin);
|
|
80
|
+
const names = IS_WIN ? ["python.exe", "python3.exe"] : ["python3", "python3.13", "python"];
|
|
81
|
+
for (const n of names) list.push(path.join(dir, n));
|
|
82
|
+
}
|
|
83
|
+
for (const dir of EXTRA_BINS) {
|
|
84
|
+
if (!dir) continue;
|
|
85
|
+
for (const n of PYTHON_CANDIDATES) list.push(path.join(dir, IS_WIN ? `${n}.exe` : n));
|
|
86
|
+
}
|
|
87
|
+
list.push(...PYTHON_CANDIDATES);
|
|
88
|
+
return list;
|
|
89
|
+
}
|
|
90
|
+
|
|
52
91
|
export function findPython310() {
|
|
53
|
-
|
|
92
|
+
let fallback = null;
|
|
93
|
+
for (const candidate of pythonCandidates()) {
|
|
54
94
|
try {
|
|
55
95
|
const ver = execSync(`${candidate} --version`, {
|
|
56
96
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -60,14 +100,24 @@ export function findPython310() {
|
|
|
60
100
|
const match = ver.match(/(\d+)\.(\d+)/);
|
|
61
101
|
if (!match) continue;
|
|
62
102
|
const [major, minor] = [parseInt(match[1], 10), parseInt(match[2], 10)];
|
|
63
|
-
if (major > MIN_VERSION[0] || (major === MIN_VERSION[0] && minor >= MIN_VERSION[1]))
|
|
103
|
+
if (!(major > MIN_VERSION[0] || (major === MIN_VERSION[0] && minor >= MIN_VERSION[1]))) continue;
|
|
104
|
+
if (!fallback) fallback = candidate;
|
|
105
|
+
try {
|
|
106
|
+
execFileSync(candidate, ["-m", "pip", "show", "headroom-ai"], {
|
|
107
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
108
|
+
windowsHide: true,
|
|
109
|
+
timeout: HEADROOM_PIP_TIMEOUT_MS,
|
|
110
|
+
env: { ...process.env, PATH: EXTENDED_PATH },
|
|
111
|
+
});
|
|
64
112
|
return candidate;
|
|
113
|
+
} catch {
|
|
114
|
+
// Keep scanning until an interpreter that sees headroom-ai is found.
|
|
65
115
|
}
|
|
66
116
|
} catch {
|
|
67
117
|
// candidate not present, try next
|
|
68
118
|
}
|
|
69
119
|
}
|
|
70
|
-
return
|
|
120
|
+
return fallback;
|
|
71
121
|
}
|
|
72
122
|
|
|
73
123
|
// Probe whether a Headroom proxy is reachable at the given URL by hitting /health.
|
|
@@ -93,10 +143,50 @@ export function isLoopbackHeadroomUrl(url) {
|
|
|
93
143
|
|
|
94
144
|
// Aggregate status for the dashboard: installed, running, python interpreter.
|
|
95
145
|
export async function getHeadroomStatus(url) {
|
|
96
|
-
const
|
|
146
|
+
const path = findHeadroomBinary();
|
|
97
147
|
const python = findPython310();
|
|
98
|
-
const installed = Boolean(
|
|
148
|
+
const installed = Boolean(path);
|
|
99
149
|
const running = await probeProxyRunning(url);
|
|
100
150
|
const localUrl = isLoopbackHeadroomUrl(url);
|
|
101
|
-
|
|
151
|
+
const extrasStatus = installed ? getInstalledHeadroomExtras(python) : { installed: false, version: null, extras: { code: false, ml: false } };
|
|
152
|
+
return {
|
|
153
|
+
installed,
|
|
154
|
+
path,
|
|
155
|
+
running,
|
|
156
|
+
python,
|
|
157
|
+
localUrl,
|
|
158
|
+
canStart: installed && localUrl,
|
|
159
|
+
version: extrasStatus.version,
|
|
160
|
+
extras: extrasStatus.extras,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Parse installed headroom-ai version + which compression extras are
|
|
165
|
+
// actually installed (detected via marker package presence). One `pip list`
|
|
166
|
+
// call is enough to answer both questions.
|
|
167
|
+
//
|
|
168
|
+
// Returns: { installed: bool, version: string|null, extras: { code, ml } }
|
|
169
|
+
export function getInstalledHeadroomExtras(python) {
|
|
170
|
+
const py = python || findPython310();
|
|
171
|
+
if (!py) return { installed: false, version: null, extras: { code: false, ml: false } };
|
|
172
|
+
try {
|
|
173
|
+
const out = execFileSync(py, ["-m", "pip", "list", "--format=json", "--disable-pip-version-check"], {
|
|
174
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
175
|
+
windowsHide: true,
|
|
176
|
+
timeout: HEADROOM_PIP_TIMEOUT_MS,
|
|
177
|
+
env: { ...process.env, PATH: EXTENDED_PATH },
|
|
178
|
+
}).toString();
|
|
179
|
+
const packages = JSON.parse(out);
|
|
180
|
+
const names = new Set(packages.map((p) => String(p.name || "").toLowerCase()));
|
|
181
|
+
const installed = names.has("headroom-ai");
|
|
182
|
+
if (!installed) return { installed: false, version: null, extras: { code: false, ml: false } };
|
|
183
|
+
const version = packages.find((p) => p.name?.toLowerCase() === "headroom-ai")?.version || null;
|
|
184
|
+
const extras = {};
|
|
185
|
+
for (const extra of HEADROOM_COMPRESSION_EXTRAS) {
|
|
186
|
+
extras[extra] = EXTRA_MARKERS[extra].some((m) => names.has(m));
|
|
187
|
+
}
|
|
188
|
+
return { installed: true, version, extras };
|
|
189
|
+
} catch {
|
|
190
|
+
return { installed: false, version: null, extras: { code: false, ml: false } };
|
|
191
|
+
}
|
|
102
192
|
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import path from "path";
|
|
3
3
|
import { spawn } from "child_process";
|
|
4
|
-
import { DATA_DIR } from
|
|
5
|
-
import { findHeadroomBinary } from "./detect.js";
|
|
4
|
+
import { DATA_DIR } from '../../lib/dataDir.js';
|
|
5
|
+
import { findHeadroomBinary, findPython310, HEADROOM_COMPRESSION_EXTRAS, EXTRA_MARKERS, getInstalledHeadroomExtras } from "./detect.js";
|
|
6
6
|
|
|
7
7
|
const HEADROOM_DIR = path.join(DATA_DIR, "headroom");
|
|
8
8
|
const PID_FILE = path.join(HEADROOM_DIR, "proxy.pid");
|
|
9
9
|
const LOG_FILE = path.join(HEADROOM_DIR, "proxy.log");
|
|
10
|
+
const INSTALL_LOG_FILE = path.join(HEADROOM_DIR, "install.log");
|
|
10
11
|
const DEFAULT_PORT = 8787;
|
|
11
12
|
const STARTUP_TIMEOUT_MS = 8000;
|
|
12
13
|
|
|
@@ -41,7 +42,17 @@ export function getManagedPid() {
|
|
|
41
42
|
return pid && isPidAlive(pid) ? pid : null;
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
|
|
45
|
+
// Build proxy CLI flags for the active compression extras. `[code]` (AST
|
|
46
|
+
// compression) is off by default in headroom → pass --code-aware to turn it on;
|
|
47
|
+
// `[ml]` (Kompress) is on by default → pass --disable-kompress to turn it off.
|
|
48
|
+
function extrasProxyArgs({ codeAware, kompress } = {}) {
|
|
49
|
+
const args = [];
|
|
50
|
+
if (codeAware) args.push("--code-aware");
|
|
51
|
+
if (kompress === false) args.push("--disable-kompress");
|
|
52
|
+
return args;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export async function startHeadroomProxy({ port = DEFAULT_PORT, codeAware = false, kompress = true } = {}) {
|
|
45
56
|
const safePort = Number(port) > 0 && Number(port) < 65536 ? Number(port) : DEFAULT_PORT;
|
|
46
57
|
const binary = findHeadroomBinary();
|
|
47
58
|
if (!binary) {
|
|
@@ -57,7 +68,8 @@ export async function startHeadroomProxy({ port = DEFAULT_PORT } = {}) {
|
|
|
57
68
|
// spawn stdio requires fd numbers, not WriteStream objects.
|
|
58
69
|
const outFd = fs.openSync(LOG_FILE, "a");
|
|
59
70
|
|
|
60
|
-
const
|
|
71
|
+
const args = ["proxy", "--port", String(safePort), ...extrasProxyArgs({ codeAware, kompress })];
|
|
72
|
+
const child = spawn(binary, args, {
|
|
61
73
|
stdio: ["ignore", outFd, outFd],
|
|
62
74
|
detached: true,
|
|
63
75
|
windowsHide: true,
|
|
@@ -118,6 +130,25 @@ export function stopHeadroomProxy() {
|
|
|
118
130
|
}
|
|
119
131
|
}
|
|
120
132
|
|
|
133
|
+
// Stop the managed proxy (if any), wait for the pid to die, then start again
|
|
134
|
+
// with the given flags. Used when toggling active extras that require a restart.
|
|
135
|
+
export async function restartHeadroomProxy(opts = {}) {
|
|
136
|
+
const pid = getManagedPid();
|
|
137
|
+
if (pid) {
|
|
138
|
+
try { process.kill(pid, "SIGTERM"); } catch { /* already gone */ }
|
|
139
|
+
// Wait up to ~3s for graceful exit, force-kill if still alive.
|
|
140
|
+
for (let i = 0; i < 30 && isPidAlive(pid); i++) {
|
|
141
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
142
|
+
}
|
|
143
|
+
if (isPidAlive(pid)) {
|
|
144
|
+
try { process.kill(pid, "SIGKILL"); } catch { /* already gone */ }
|
|
145
|
+
await new Promise((r) => setTimeout(r, 300));
|
|
146
|
+
}
|
|
147
|
+
clearPid();
|
|
148
|
+
}
|
|
149
|
+
return startHeadroomProxy(opts);
|
|
150
|
+
}
|
|
151
|
+
|
|
121
152
|
export function getHeadroomLogTail(maxLines = 200) {
|
|
122
153
|
try {
|
|
123
154
|
if (!fs.existsSync(LOG_FILE)) return "";
|
|
@@ -126,3 +157,104 @@ export function getHeadroomLogTail(maxLines = 200) {
|
|
|
126
157
|
return lines.slice(-maxLines).join("\n");
|
|
127
158
|
} catch { return ""; }
|
|
128
159
|
}
|
|
160
|
+
|
|
161
|
+
// Install (or upgrade) headroom-ai with the requested compression extras.
|
|
162
|
+
// `extras` is a whitelist from HEADROOM_COMPRESSION_EXTRAS — anything else
|
|
163
|
+
// is rejected to keep the install surface predictable. Always installs the
|
|
164
|
+
// `proxy` base + whatever extras the user picked, regardless of what is
|
|
165
|
+
// already present.
|
|
166
|
+
export async function installHeadroomExtras(extras = []) {
|
|
167
|
+
const requested = Array.isArray(extras) ? extras.filter((e) => HEADROOM_COMPRESSION_EXTRAS.includes(e)) : [];
|
|
168
|
+
const py = findPython310();
|
|
169
|
+
if (!py) {
|
|
170
|
+
const err = new Error("Python >= 3.10 not found");
|
|
171
|
+
err.code = "NO_PYTHON";
|
|
172
|
+
throw err;
|
|
173
|
+
}
|
|
174
|
+
if (!findHeadroomBinary()) {
|
|
175
|
+
const err = new Error("headroom-ai not installed (run `pip install headroom-ai[proxy]` first)");
|
|
176
|
+
err.code = "NOT_INSTALLED";
|
|
177
|
+
throw err;
|
|
178
|
+
}
|
|
179
|
+
// pip install string is built from a closed set (HEADROOM_COMPRESSION_EXTRAS),
|
|
180
|
+
// so it cannot be poisoned by caller input — the comma-list is a fixed
|
|
181
|
+
// ['proxy', ...requested]. No shell interpolation.
|
|
182
|
+
const extrasList = ["proxy", ...requested].join(",");
|
|
183
|
+
const spec = `headroom-ai[${extrasList}]`;
|
|
184
|
+
const args = ["-m", "pip", "install", "--upgrade", spec];
|
|
185
|
+
|
|
186
|
+
ensureDir();
|
|
187
|
+
// Truncate ("w") so the log reflects only the current install for live progress.
|
|
188
|
+
const outFd = fs.openSync(INSTALL_LOG_FILE, "w");
|
|
189
|
+
const child = spawn(py, args, {
|
|
190
|
+
stdio: ["ignore", outFd, outFd],
|
|
191
|
+
windowsHide: true,
|
|
192
|
+
env: { ...process.env },
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
return new Promise((resolve, reject) => {
|
|
196
|
+
child.once("error", (e) => { fs.closeSync(outFd); reject(e); });
|
|
197
|
+
child.once("exit", (code) => {
|
|
198
|
+
fs.closeSync(outFd);
|
|
199
|
+
if (code === 0) {
|
|
200
|
+
const status = getInstalledHeadroomExtras(py);
|
|
201
|
+
resolve({ success: true, code, spec, extras: requested, ...status });
|
|
202
|
+
} else {
|
|
203
|
+
const err = new Error(`pip install exited with code=${code} — see headroom/install.log`);
|
|
204
|
+
err.code = "INSTALL_FAILED";
|
|
205
|
+
reject(err);
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Uninstall the marker packages that back a single extra (e.g. `ml` → torch,
|
|
212
|
+
// huggingface-hub). `headroom-ai` base and the `proxy` extra are never removed.
|
|
213
|
+
export async function uninstallHeadroomExtras(extras = []) {
|
|
214
|
+
const requested = Array.isArray(extras) ? extras.filter((e) => HEADROOM_COMPRESSION_EXTRAS.includes(e)) : [];
|
|
215
|
+
const py = findPython310();
|
|
216
|
+
if (!py) {
|
|
217
|
+
const err = new Error("Python >= 3.10 not found");
|
|
218
|
+
err.code = "NO_PYTHON";
|
|
219
|
+
throw err;
|
|
220
|
+
}
|
|
221
|
+
const pkgs = [...new Set(requested.flatMap((e) => EXTRA_MARKERS[e] || []))];
|
|
222
|
+
if (pkgs.length === 0) {
|
|
223
|
+
const err = new Error("No valid extras to remove");
|
|
224
|
+
err.code = "INVALID_EXTRAS";
|
|
225
|
+
throw err;
|
|
226
|
+
}
|
|
227
|
+
const args = ["-m", "pip", "uninstall", "-y", ...pkgs];
|
|
228
|
+
|
|
229
|
+
ensureDir();
|
|
230
|
+
const outFd = fs.openSync(INSTALL_LOG_FILE, "w");
|
|
231
|
+
const child = spawn(py, args, {
|
|
232
|
+
stdio: ["ignore", outFd, outFd],
|
|
233
|
+
windowsHide: true,
|
|
234
|
+
env: { ...process.env },
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
return new Promise((resolve, reject) => {
|
|
238
|
+
child.once("error", (e) => { fs.closeSync(outFd); reject(e); });
|
|
239
|
+
child.once("exit", (code) => {
|
|
240
|
+
fs.closeSync(outFd);
|
|
241
|
+
if (code === 0) {
|
|
242
|
+
const status = getInstalledHeadroomExtras(py);
|
|
243
|
+
resolve({ success: true, code, removed: pkgs, extras: requested, ...status });
|
|
244
|
+
} else {
|
|
245
|
+
const err = new Error(`pip uninstall exited with code=${code} — see headroom/install.log`);
|
|
246
|
+
err.code = "UNINSTALL_FAILED";
|
|
247
|
+
reject(err);
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Read the tail of the install/uninstall log for live progress in the UI.
|
|
254
|
+
export function getInstallLogTail(maxLines = 15) {
|
|
255
|
+
try {
|
|
256
|
+
if (!fs.existsSync(INSTALL_LOG_FILE)) return "";
|
|
257
|
+
const lines = fs.readFileSync(INSTALL_LOG_FILE, "utf8").split(/\r?\n/).filter(Boolean);
|
|
258
|
+
return lines.slice(-maxLines).join("\n");
|
|
259
|
+
} catch { return ""; }
|
|
260
|
+
}
|
|
@@ -1,44 +1,10 @@
|
|
|
1
1
|
import { platform, arch } from "os";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
// === Kimchi CLI version (dynamic, cached from GitHub releases) ===
|
|
5
|
-
const KIMCHI_FALLBACK_VERSION = "0.1.39";
|
|
6
|
-
let _kimchiVersionCache = null;
|
|
7
|
-
let _kimchiVersionFetching = null;
|
|
8
|
-
const KIMCHI_VERSION_TTL_MS = 3600_000; // 1h
|
|
9
|
-
|
|
10
|
-
async function fetchKimchiVersion() {
|
|
11
|
-
try {
|
|
12
|
-
const res = await proxyAwareFetch("https://api.github.com/repos/getkimchi/kimchi/releases/latest", {
|
|
13
|
-
headers: { Accept: "application/vnd.github+json" },
|
|
14
|
-
signal: AbortSignal.timeout(5000),
|
|
15
|
-
});
|
|
16
|
-
if (!res.ok) return KIMCHI_FALLBACK_VERSION;
|
|
17
|
-
const body = await res.json();
|
|
18
|
-
const tag = body?.tag_name || "";
|
|
19
|
-
const ver = tag.replace(/^v/, "");
|
|
20
|
-
return ver || KIMCHI_FALLBACK_VERSION;
|
|
21
|
-
} catch {
|
|
22
|
-
return KIMCHI_FALLBACK_VERSION;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export async function getKimchiVersion() {
|
|
27
|
-
if (_kimchiVersionCache && Date.now() - _kimchiVersionCache.ts < KIMCHI_VERSION_TTL_MS) return _kimchiVersionCache.ver;
|
|
28
|
-
if (_kimchiVersionFetching) return _kimchiVersionFetching;
|
|
29
|
-
_kimchiVersionFetching = fetchKimchiVersion().finally(() => { _kimchiVersionFetching = null; });
|
|
30
|
-
const ver = await _kimchiVersionFetching;
|
|
31
|
-
_kimchiVersionCache = { ver, ts: Date.now() };
|
|
32
|
-
return ver;
|
|
33
|
-
}
|
|
2
|
+
import { PROVIDERS, PROVIDER_OAUTH } from "./providers.js";
|
|
3
|
+
import { ANTIGRAVITY_IDE_USER_AGENT } from "../providers/shared.js";
|
|
34
4
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
// === Gemini CLI ===
|
|
40
|
-
export const GEMINI_CLI_VERSION = "0.34.0";
|
|
41
|
-
export const GEMINI_CLI_API_CLIENT = "google-genai-sdk/1.41.0 gl-node/v22.19.0";
|
|
5
|
+
// === Gemini CLI === derive từ registry gemini-cli.transport
|
|
6
|
+
export const GEMINI_CLI_VERSION = PROVIDERS["gemini-cli"]?.cliVersion;
|
|
7
|
+
export const GEMINI_CLI_API_CLIENT = PROVIDERS["gemini-cli"]?.apiClient;
|
|
42
8
|
|
|
43
9
|
// Map Node arch to Gemini CLI arch string (x64/x86/arm64/...)
|
|
44
10
|
function geminiCLIArch() {
|
|
@@ -52,11 +18,13 @@ export function geminiCLIUserAgent(model = "unknown") {
|
|
|
52
18
|
}
|
|
53
19
|
|
|
54
20
|
// === GitHub Copilot ===
|
|
21
|
+
// Derive từ registry github.transport.copilot
|
|
22
|
+
const _ghCopilot = PROVIDERS.github?.copilot || {};
|
|
55
23
|
export const GITHUB_COPILOT = {
|
|
56
|
-
VSCODE_VERSION:
|
|
57
|
-
COPILOT_CHAT_VERSION:
|
|
58
|
-
USER_AGENT:
|
|
59
|
-
API_VERSION:
|
|
24
|
+
VSCODE_VERSION: _ghCopilot.vscodeVersion,
|
|
25
|
+
COPILOT_CHAT_VERSION: _ghCopilot.chatVersion,
|
|
26
|
+
USER_AGENT: _ghCopilot.userAgent,
|
|
27
|
+
API_VERSION: _ghCopilot.apiVersion,
|
|
60
28
|
};
|
|
61
29
|
|
|
62
30
|
// === Antigravity enums ===
|
|
@@ -92,7 +60,7 @@ export function getPlatformEnum() {
|
|
|
92
60
|
}
|
|
93
61
|
|
|
94
62
|
export function getPlatformUserAgent() {
|
|
95
|
-
return
|
|
63
|
+
return ANTIGRAVITY_IDE_USER_AGENT;
|
|
96
64
|
}
|
|
97
65
|
|
|
98
66
|
export const CLIENT_METADATA = {
|
|
@@ -162,7 +130,7 @@ export const AG_DEFAULT_TOOLS = new Set([
|
|
|
162
130
|
|
|
163
131
|
// Antigravity chat/stream headers
|
|
164
132
|
export const ANTIGRAVITY_HEADERS = {
|
|
165
|
-
"User-Agent":
|
|
133
|
+
"User-Agent": ANTIGRAVITY_IDE_USER_AGENT
|
|
166
134
|
};
|
|
167
135
|
|
|
168
136
|
// Cloud Code Assist API
|
|
@@ -188,43 +156,19 @@ export const LOAD_CODE_ASSIST_METADATA = {
|
|
|
188
156
|
export const CLAUDE_SYSTEM_PROMPT = "You are Claude Code, Anthropic's official CLI for Claude.";
|
|
189
157
|
export const ANTIGRAVITY_DEFAULT_SYSTEM = "You are Antigravity, a powerful agentic AI coding assistant designed by the Google Deepmind team working on Advanced Agentic Coding.You are pair programming with a USER to solve their coding task. The task may require creating a new codebase, modifying or debugging an existing codebase, or simply answering a question.**Absolute paths only****Proactiveness**";
|
|
190
158
|
|
|
191
|
-
//
|
|
192
|
-
export const REFRESH_LEAD_MS =
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
iflow: 24 * 60 * 60 * 1000, // 24 hours
|
|
196
|
-
qwen: 20 * 60 * 1000, // 20 minutes
|
|
197
|
-
"kimi-coding": 5 * 60 * 1000, // 5 minutes
|
|
198
|
-
antigravity: 5 * 60 * 1000, // 5 minutes
|
|
199
|
-
};
|
|
159
|
+
// Derive từ registry oauth.refreshLeadMs
|
|
160
|
+
export const REFRESH_LEAD_MS = Object.fromEntries(
|
|
161
|
+
Object.entries(PROVIDER_OAUTH).filter(([, o]) => o.refreshLeadMs).map(([id, o]) => [id, o.refreshLeadMs])
|
|
162
|
+
);
|
|
200
163
|
|
|
201
164
|
// OAuth endpoints
|
|
202
165
|
export const OAUTH_ENDPOINTS = {
|
|
203
|
-
google:
|
|
204
|
-
token: "
|
|
205
|
-
|
|
206
|
-
},
|
|
207
|
-
|
|
208
|
-
token: "
|
|
209
|
-
auth: "https://auth.openai.com/oauth/authorize"
|
|
210
|
-
},
|
|
211
|
-
anthropic: {
|
|
212
|
-
token: "https://api.anthropic.com/v1/oauth/token",
|
|
213
|
-
auth: "https://api.anthropic.com/v1/oauth/authorize"
|
|
214
|
-
},
|
|
215
|
-
qwen: {
|
|
216
|
-
token: "https://qwen.ai/api/v1/oauth2/token",
|
|
217
|
-
auth: "https://qwen.ai/api/v1/oauth2/device/code"
|
|
218
|
-
},
|
|
219
|
-
iflow: {
|
|
220
|
-
token: "https://iflow.cn/oauth/token",
|
|
221
|
-
auth: "https://iflow.cn/oauth"
|
|
222
|
-
},
|
|
223
|
-
github: {
|
|
224
|
-
token: "https://github.com/login/oauth/access_token",
|
|
225
|
-
auth: "https://github.com/login/oauth/authorize",
|
|
226
|
-
deviceCode: "https://github.com/login/device/code"
|
|
227
|
-
}
|
|
166
|
+
google: { token: "https://oauth2.googleapis.com/token", auth: "https://accounts.google.com/o/oauth2/auth" },
|
|
167
|
+
openai: { token: PROVIDER_OAUTH["codex"]?.tokenUrl, auth: PROVIDER_OAUTH["codex"]?.authorizeUrl },
|
|
168
|
+
anthropic: { token: PROVIDER_OAUTH["claude"]?.tokenUrl, auth: "https://api.anthropic.com/v1/oauth/authorize" }, // ≠ claude.authorizeUrl (claude.ai login) — keep
|
|
169
|
+
qwen: { token: PROVIDER_OAUTH["qwen"]?.tokenUrl, auth: PROVIDER_OAUTH["qwen"]?.deviceCodeUrl },
|
|
170
|
+
iflow: { token: PROVIDER_OAUTH["iflow"]?.tokenUrl, auth: PROVIDER_OAUTH["iflow"]?.authorizeUrl },
|
|
171
|
+
github: { token: PROVIDER_OAUTH["github"]?.tokenUrl, auth: PROVIDER_OAUTH["github"]?.authorizeUrl, deviceCode: PROVIDER_OAUTH["github"]?.deviceCodeUrl },
|
|
228
172
|
};
|
|
229
173
|
|
|
230
174
|
// Generate Kimi OAuth custom headers
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
GITHUB_COPILOT_CHAT_USER_AGENT,
|
|
5
5
|
getQwenOauthHeaders
|
|
6
6
|
} from "./providerHeaderProfiles.ts";
|
|
7
|
-
import { normalizeCliCompatProviderId } from '
|
|
7
|
+
import { normalizeCliCompatProviderId } from '../../dist/shared/utils/cliCompat.js';
|
|
8
8
|
const CLI_FINGERPRINTS = {
|
|
9
9
|
codex: {
|
|
10
10
|
headerOrder: [
|
|
@@ -45,7 +45,6 @@ export const MAX_RATE_LIMIT_COOLDOWN_MS = 30 * 60 * 1000;
|
|
|
45
45
|
const COOLDOWN = {
|
|
46
46
|
long: 2 * 60 * 1000,
|
|
47
47
|
short: 5 * 1000,
|
|
48
|
-
exhausted: 24 * 60 * 60 * 1000, // 24 hours
|
|
49
48
|
};
|
|
50
49
|
|
|
51
50
|
/**
|
|
@@ -59,16 +58,6 @@ const COOLDOWN = {
|
|
|
59
58
|
*/
|
|
60
59
|
export const ERROR_RULES = [
|
|
61
60
|
// --- Text-based rules (checked first, order = priority) ---
|
|
62
|
-
{ text: "exhausted", cooldownMs: COOLDOWN.exhausted },
|
|
63
|
-
{ text: "insufficient credits", cooldownMs: COOLDOWN.exhausted },
|
|
64
|
-
{ text: "1076", cooldownMs: COOLDOWN.exhausted },
|
|
65
|
-
{ text: "only available on paid plans", cooldownMs: COOLDOWN.exhausted },
|
|
66
|
-
{ text: "failed to capture weavy firebase id token", cooldownMs: COOLDOWN.exhausted },
|
|
67
|
-
{ text: "trial version is not yet", cooldownMs: COOLDOWN.exhausted },
|
|
68
|
-
{ text: "neurons", cooldownMs: COOLDOWN.exhausted }, // CF Workers AI daily quota
|
|
69
|
-
{ text: "daily free allocation", cooldownMs: COOLDOWN.exhausted }, // CF Workers AI daily quota
|
|
70
|
-
{ text: "upgrade to cloudflare", cooldownMs: COOLDOWN.exhausted }, // CF Workers AI paid plan prompt
|
|
71
|
-
{ text: "4006", cooldownMs: COOLDOWN.exhausted }, // CF Workers AI error code
|
|
72
61
|
{ text: "no credentials", cooldownMs: COOLDOWN.long },
|
|
73
62
|
{ text: "request not allowed", cooldownMs: COOLDOWN.short },
|
|
74
63
|
{ text: "improperly formed request", cooldownMs: COOLDOWN.long },
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const GROK_CLI_VERSION = "0.2.99";
|
|
2
|
+
export const GROK_CLI_MODEL = "grok-build";
|
|
3
|
+
export const GROK_CLI_BASE_URL = "https://cli-chat-proxy.grok.com/v1";
|
|
4
|
+
export const GROK_CLI_CLIENT_IDENTIFIER = "grok-shell";
|
|
5
|
+
export const GROK_CLI_USER_AGENT = `grok-shell/${GROK_CLI_VERSION} (linux; x86_64)`;
|
|
6
|
+
|
|
7
|
+
export function supportsGrokCliReasoningEffort(model) {
|
|
8
|
+
// ponytail: unknown models omit effort until live metadata reaches dispatch.
|
|
9
|
+
return /^grok-4\.5(?:$|-)/.test(String(model || ""));
|
|
10
|
+
}
|