@jsonstudio/rcc 0.89.1968 → 0.89.2202
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/README.md +22 -0
- package/config/file-line-limit-policy.json +21 -0
- package/configsamples/config.json +1 -1
- package/configsamples/config.v1.quickstart.sanitized.json +6 -6
- package/configsamples/provider/iflow/config.v1.json +1 -1
- package/dist/app/config-readers.d.ts +18 -0
- package/dist/app/config-readers.js +95 -0
- package/dist/app/config-readers.js.map +1 -0
- package/dist/app/index.d.ts +9 -0
- package/dist/app/index.js +8 -0
- package/dist/app/index.js.map +1 -0
- package/dist/app/shutdown.d.ts +32 -0
- package/dist/app/shutdown.js +41 -0
- package/dist/app/shutdown.js.map +1 -0
- package/dist/bootstrap/index.d.ts +7 -0
- package/dist/bootstrap/index.js +7 -0
- package/dist/bootstrap/index.js.map +1 -0
- package/dist/bootstrap/log-filter.d.ts +15 -0
- package/dist/bootstrap/log-filter.js +81 -0
- package/dist/bootstrap/log-filter.js.map +1 -0
- package/dist/build-info.js +2 -2
- package/dist/cli/commands/claude.js +6 -5
- package/dist/cli/commands/claude.js.map +1 -1
- package/dist/cli/commands/init/basic.d.ts +1 -7
- package/dist/cli/commands/init/basic.js +0 -79
- package/dist/cli/commands/init/basic.js.map +1 -1
- package/dist/cli/commands/init/prompt-utils.d.ts +7 -0
- package/dist/cli/commands/init/prompt-utils.js +80 -0
- package/dist/cli/commands/init/prompt-utils.js.map +1 -0
- package/dist/cli/commands/init/workflows.js +2 -1
- package/dist/cli/commands/init/workflows.js.map +1 -1
- package/dist/cli/commands/init.js +74 -2
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/launcher/index.d.ts +7 -0
- package/dist/cli/commands/launcher/index.js +7 -0
- package/dist/cli/commands/launcher/index.js.map +1 -0
- package/dist/cli/commands/launcher/types.d.ts +112 -0
- package/dist/cli/commands/launcher/types.js +7 -0
- package/dist/cli/commands/launcher/types.js.map +1 -0
- package/dist/cli/commands/launcher/utils.d.ts +114 -0
- package/dist/cli/commands/launcher/utils.js +378 -0
- package/dist/cli/commands/launcher/utils.js.map +1 -0
- package/dist/cli/commands/launcher-kernel.d.ts +2 -74
- package/dist/cli/commands/launcher-kernel.js +141 -143
- package/dist/cli/commands/launcher-kernel.js.map +1 -1
- package/dist/cli/commands/start-types.d.ts +67 -0
- package/dist/cli/commands/start-types.js +3 -0
- package/dist/cli/commands/start-types.js.map +1 -0
- package/dist/cli/commands/start-utils.d.ts +19 -0
- package/dist/cli/commands/start-utils.js +78 -0
- package/dist/cli/commands/start-utils.js.map +1 -0
- package/dist/cli/commands/start.d.ts +2 -67
- package/dist/cli/commands/start.js +201 -48
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/commands/stop.js +17 -1
- package/dist/cli/commands/stop.js.map +1 -1
- package/dist/cli/commands/tmux-inject.js +1 -1
- package/dist/cli/commands/tmux-inject.js.map +1 -1
- package/dist/cli/config/init-config.js +60 -2
- package/dist/cli/config/init-config.js.map +1 -1
- package/dist/cli/config/init-provider-catalog.js +3 -1
- package/dist/cli/config/init-provider-catalog.js.map +1 -1
- package/dist/cli/config/precommand-default-script.d.ts +17 -0
- package/dist/cli/config/precommand-default-script.js +47 -0
- package/dist/cli/config/precommand-default-script.js.map +1 -0
- package/dist/cli/server/port-utils.js +63 -51
- package/dist/cli/server/port-utils.js.map +1 -1
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/client/gemini-cli/gemini-cli-protocol-client.js +55 -5
- package/dist/client/gemini-cli/gemini-cli-protocol-client.js.map +1 -1
- package/dist/commands/oauth.js +28 -4
- package/dist/commands/oauth.js.map +1 -1
- package/dist/commands/quota-daemon.js +12 -0
- package/dist/commands/quota-daemon.js.map +1 -1
- package/dist/configsamples/config.v1.quickstart.sanitized.json +6 -6
- package/dist/constants/index.d.ts +34 -0
- package/dist/constants/index.js +57 -0
- package/dist/constants/index.js.map +1 -1
- package/dist/docs/daemon-admin-ui.html +268 -11
- package/dist/error-handling/quiet-error-handling-center.js +19 -1
- package/dist/error-handling/quiet-error-handling-center.js.map +1 -1
- package/dist/index.js +233 -30
- package/dist/index.js.map +1 -1
- package/dist/manager/index.js +4 -4
- package/dist/manager/index.js.map +1 -1
- package/dist/manager/modules/quota/antigravity-quota-core.d.ts +26 -0
- package/dist/manager/modules/quota/antigravity-quota-core.js +23 -0
- package/dist/manager/modules/quota/antigravity-quota-core.js.map +1 -0
- package/dist/manager/modules/quota/antigravity-quota-helpers.d.ts +16 -0
- package/dist/manager/modules/quota/antigravity-quota-helpers.js +167 -0
- package/dist/manager/modules/quota/antigravity-quota-helpers.js.map +1 -0
- package/dist/manager/modules/quota/antigravity-quota-manager.d.ts +10 -39
- package/dist/manager/modules/quota/antigravity-quota-manager.js +167 -464
- package/dist/manager/modules/quota/antigravity-quota-manager.js.map +1 -1
- package/dist/manager/modules/quota/antigravity-quota-persistence.d.ts +20 -0
- package/dist/manager/modules/quota/antigravity-quota-persistence.js +139 -0
- package/dist/manager/modules/quota/antigravity-quota-persistence.js.map +1 -0
- package/dist/manager/modules/quota/antigravity-quota-runtime.d.ts +55 -0
- package/dist/manager/modules/quota/antigravity-quota-runtime.js +174 -0
- package/dist/manager/modules/quota/antigravity-quota-runtime.js.map +1 -0
- package/dist/manager/modules/quota/antigravity-quota-sync.d.ts +46 -0
- package/dist/manager/modules/quota/antigravity-quota-sync.js +162 -0
- package/dist/manager/modules/quota/antigravity-quota-sync.js.map +1 -0
- package/dist/manager/modules/quota/index.d.ts +1 -0
- package/dist/manager/modules/quota/provider-quota-daemon.error-helpers.d.ts +13 -0
- package/dist/manager/modules/quota/provider-quota-daemon.error-helpers.js +149 -0
- package/dist/manager/modules/quota/provider-quota-daemon.error-helpers.js.map +1 -0
- package/dist/manager/modules/quota/provider-quota-daemon.events.js +1 -148
- package/dist/manager/modules/quota/provider-quota-daemon.events.js.map +1 -1
- package/dist/manager/modules/quota/provider-quota-daemon.js.map +1 -1
- package/dist/manager/modules/quota/quota-adapter.d.ts +111 -0
- package/dist/manager/modules/quota/quota-adapter.js +325 -0
- package/dist/manager/modules/quota/quota-adapter.js.map +1 -0
- package/dist/manager/quota/provider-quota-center.d.ts +10 -0
- package/dist/manager/quota/provider-quota-center.js +15 -2
- package/dist/manager/quota/provider-quota-center.js.map +1 -1
- package/dist/modules/llmswitch/bridge/antigravity-signature.d.ts +28 -0
- package/dist/modules/llmswitch/bridge/antigravity-signature.js +180 -0
- package/dist/modules/llmswitch/bridge/antigravity-signature.js.map +1 -0
- package/dist/modules/llmswitch/bridge/index.d.ts +13 -0
- package/dist/modules/llmswitch/bridge/index.js +14 -0
- package/dist/modules/llmswitch/bridge/index.js.map +1 -0
- package/dist/modules/llmswitch/bridge/module-loader.d.ts +16 -0
- package/dist/modules/llmswitch/bridge/module-loader.js +59 -0
- package/dist/modules/llmswitch/bridge/module-loader.js.map +1 -0
- package/dist/modules/llmswitch/bridge/quota-manager.d.ts +8 -0
- package/dist/modules/llmswitch/bridge/quota-manager.js +37 -0
- package/dist/modules/llmswitch/bridge/quota-manager.js.map +1 -0
- package/dist/modules/llmswitch/bridge/response-converter.d.ts +11 -0
- package/dist/modules/llmswitch/bridge/response-converter.js +68 -0
- package/dist/modules/llmswitch/bridge/response-converter.js.map +1 -0
- package/dist/modules/llmswitch/bridge/routing-integrations.d.ts +12 -0
- package/dist/modules/llmswitch/bridge/routing-integrations.js +56 -0
- package/dist/modules/llmswitch/bridge/routing-integrations.js.map +1 -0
- package/dist/modules/llmswitch/bridge/runtime-integrations.d.ts +34 -0
- package/dist/modules/llmswitch/bridge/runtime-integrations.js +87 -0
- package/dist/modules/llmswitch/bridge/runtime-integrations.js.map +1 -0
- package/dist/modules/llmswitch/bridge/snapshot-recorder.d.ts +13 -0
- package/dist/modules/llmswitch/bridge/snapshot-recorder.js +484 -0
- package/dist/modules/llmswitch/bridge/snapshot-recorder.js.map +1 -0
- package/dist/modules/llmswitch/bridge/state-integrations.d.ts +59 -0
- package/dist/modules/llmswitch/bridge/state-integrations.js +264 -0
- package/dist/modules/llmswitch/bridge/state-integrations.js.map +1 -0
- package/dist/modules/llmswitch/bridge.d.ts +14 -131
- package/dist/modules/llmswitch/bridge.js +14 -834
- package/dist/modules/llmswitch/bridge.js.map +1 -1
- package/dist/modules/pipeline/types/provider-config-types.d.ts +240 -0
- package/dist/modules/pipeline/types/provider-config-types.js +2 -0
- package/dist/modules/pipeline/types/provider-config-types.js.map +1 -0
- package/dist/modules/pipeline/types/provider-types.d.ts +2 -239
- package/dist/modules/pipeline/types/provider-types.js +1 -1
- package/dist/modules/pipeline/types/provider-types.js.map +1 -1
- package/dist/modules/pipeline/utils/debug-logger.js +3 -5
- package/dist/modules/pipeline/utils/debug-logger.js.map +1 -1
- package/dist/providers/auth/apikey-auth.d.ts +57 -1
- package/dist/providers/auth/apikey-auth.js +131 -1
- package/dist/providers/auth/apikey-auth.js.map +1 -1
- package/dist/providers/auth/oauth-lifecycle/error-detection.d.ts +8 -0
- package/dist/providers/auth/oauth-lifecycle/error-detection.js +71 -0
- package/dist/providers/auth/oauth-lifecycle/error-detection.js.map +1 -0
- package/dist/providers/auth/oauth-lifecycle/index.d.ts +10 -0
- package/dist/providers/auth/oauth-lifecycle/index.js +11 -0
- package/dist/providers/auth/oauth-lifecycle/index.js.map +1 -0
- package/dist/providers/auth/oauth-lifecycle/path-resolver.d.ts +18 -0
- package/dist/providers/auth/oauth-lifecycle/path-resolver.js +121 -0
- package/dist/providers/auth/oauth-lifecycle/path-resolver.js.map +1 -0
- package/dist/providers/auth/oauth-lifecycle/throttle.d.ts +22 -0
- package/dist/providers/auth/oauth-lifecycle/throttle.js +37 -0
- package/dist/providers/auth/oauth-lifecycle/throttle.js.map +1 -0
- package/dist/providers/auth/oauth-lifecycle/token-helpers.d.ts +36 -0
- package/dist/providers/auth/oauth-lifecycle/token-helpers.js +127 -0
- package/dist/providers/auth/oauth-lifecycle/token-helpers.js.map +1 -0
- package/dist/providers/auth/oauth-lifecycle/token-io.d.ts +14 -0
- package/dist/providers/auth/oauth-lifecycle/token-io.js +151 -0
- package/dist/providers/auth/oauth-lifecycle/token-io.js.map +1 -0
- package/dist/providers/auth/oauth-lifecycle.js +70 -446
- package/dist/providers/auth/oauth-lifecycle.js.map +1 -1
- package/dist/providers/auth/oauth-repair-cooldown.js +8 -3
- package/dist/providers/auth/oauth-repair-cooldown.js.map +1 -1
- package/dist/providers/auth/oauth-repair-env.js +5 -3
- package/dist/providers/auth/oauth-repair-env.js.map +1 -1
- package/dist/providers/auth/oauth-token-utils.d.ts +61 -0
- package/dist/providers/auth/oauth-token-utils.js +187 -0
- package/dist/providers/auth/oauth-token-utils.js.map +1 -0
- package/dist/providers/auth/oauth-utils/camoufox-helper.d.ts +21 -0
- package/dist/providers/auth/oauth-utils/camoufox-helper.js +82 -0
- package/dist/providers/auth/oauth-utils/camoufox-helper.js.map +1 -0
- package/dist/providers/auth/oauth-utils/error-extraction.d.ts +17 -0
- package/dist/providers/auth/oauth-utils/error-extraction.js +80 -0
- package/dist/providers/auth/oauth-utils/error-extraction.js.map +1 -0
- package/dist/providers/auth/oauth-utils/index.d.ts +7 -0
- package/dist/providers/auth/oauth-utils/index.js +8 -0
- package/dist/providers/auth/oauth-utils/index.js.map +1 -0
- package/dist/providers/auth/token-refresh/index.d.ts +6 -0
- package/dist/providers/auth/token-refresh/index.js +7 -0
- package/dist/providers/auth/token-refresh/index.js.map +1 -0
- package/dist/providers/auth/token-refresh/token-state.d.ts +17 -0
- package/dist/providers/auth/token-refresh/token-state.js +30 -0
- package/dist/providers/auth/token-refresh/token-state.js.map +1 -0
- package/dist/providers/auth/token-storage/index.d.ts +7 -0
- package/dist/providers/auth/token-storage/index.js +8 -0
- package/dist/providers/auth/token-storage/index.js.map +1 -0
- package/dist/providers/auth/token-storage/token-file-resolver.d.ts +12 -0
- package/dist/providers/auth/token-storage/token-file-resolver.js +117 -0
- package/dist/providers/auth/token-storage/token-file-resolver.js.map +1 -0
- package/dist/providers/auth/token-storage/token-persistence.d.ts +22 -0
- package/dist/providers/auth/token-storage/token-persistence.js +86 -0
- package/dist/providers/auth/token-storage/token-persistence.js.map +1 -0
- package/dist/providers/auth/tokenfile-auth.js +12 -9
- package/dist/providers/auth/tokenfile-auth.js.map +1 -1
- package/dist/providers/core/api/provider-config.d.ts +8 -0
- package/dist/providers/core/config/camoufox-launcher.d.ts +1 -0
- package/dist/providers/core/config/camoufox-launcher.js +40 -9
- package/dist/providers/core/config/camoufox-launcher.js.map +1 -1
- package/dist/providers/core/config/oauth-flows.js +7 -2
- package/dist/providers/core/config/oauth-flows.js.map +1 -1
- package/dist/providers/core/config/provider-debug-hooks.d.ts +0 -12
- package/dist/providers/core/config/provider-debug-hooks.js +16 -56
- package/dist/providers/core/config/provider-debug-hooks.js.map +1 -1
- package/dist/providers/core/config/provider-debug-output-utils.d.ts +38 -0
- package/dist/providers/core/config/provider-debug-output-utils.js +46 -0
- package/dist/providers/core/config/provider-debug-output-utils.js.map +1 -0
- package/dist/providers/core/config/provider-oauth-configs.js +13 -9
- package/dist/providers/core/config/provider-oauth-configs.js.map +1 -1
- package/dist/providers/core/runtime/antigravity-request-type.d.ts +2 -0
- package/dist/providers/core/runtime/antigravity-request-type.js +126 -0
- package/dist/providers/core/runtime/antigravity-request-type.js.map +1 -0
- package/dist/providers/core/runtime/base-provider-runtime-helpers.d.ts +27 -0
- package/dist/providers/core/runtime/base-provider-runtime-helpers.js +105 -0
- package/dist/providers/core/runtime/base-provider-runtime-helpers.js.map +1 -0
- package/dist/providers/core/runtime/base-provider-series-cooldown.d.ts +19 -0
- package/dist/providers/core/runtime/base-provider-series-cooldown.js +363 -0
- package/dist/providers/core/runtime/base-provider-series-cooldown.js.map +1 -0
- package/dist/providers/core/runtime/base-provider.d.ts +4 -35
- package/dist/providers/core/runtime/base-provider.js +20 -501
- package/dist/providers/core/runtime/base-provider.js.map +1 -1
- package/dist/providers/core/runtime/deepseek-http-provider-helpers.d.ts +32 -0
- package/dist/providers/core/runtime/deepseek-http-provider-helpers.js +301 -0
- package/dist/providers/core/runtime/deepseek-http-provider-helpers.js.map +1 -0
- package/dist/providers/core/runtime/deepseek-http-provider.d.ts +0 -3
- package/dist/providers/core/runtime/deepseek-http-provider.js +5 -127
- package/dist/providers/core/runtime/deepseek-http-provider.js.map +1 -1
- package/dist/providers/core/runtime/deepseek-session-pow-helpers.d.ts +21 -0
- package/dist/providers/core/runtime/deepseek-session-pow-helpers.js +99 -0
- package/dist/providers/core/runtime/deepseek-session-pow-helpers.js.map +1 -0
- package/dist/providers/core/runtime/deepseek-session-pow.js +13 -108
- package/dist/providers/core/runtime/deepseek-session-pow.js.map +1 -1
- package/dist/providers/core/runtime/gemini-cli-http-provider.d.ts +0 -15
- package/dist/providers/core/runtime/gemini-cli-http-provider.js +13 -303
- package/dist/providers/core/runtime/gemini-cli-http-provider.js.map +1 -1
- package/dist/providers/core/runtime/gemini-cli-response-postprocessor.d.ts +9 -0
- package/dist/providers/core/runtime/gemini-cli-response-postprocessor.js +85 -0
- package/dist/providers/core/runtime/gemini-cli-response-postprocessor.js.map +1 -0
- package/dist/providers/core/runtime/gemini-http-provider.js +2 -2
- package/dist/providers/core/runtime/gemini-http-provider.js.map +1 -1
- package/dist/providers/core/runtime/gemini-sse-normalizer.d.ts +25 -0
- package/dist/providers/core/runtime/gemini-sse-normalizer.js +159 -0
- package/dist/providers/core/runtime/gemini-sse-normalizer.js.map +1 -0
- package/dist/providers/core/runtime/http-request-executor.js +1 -48
- package/dist/providers/core/runtime/http-request-executor.js.map +1 -1
- package/dist/providers/core/runtime/http-transport-provider.d.ts +2 -48
- package/dist/providers/core/runtime/http-transport-provider.js +158 -1273
- package/dist/providers/core/runtime/http-transport-provider.js.map +1 -1
- package/dist/providers/core/runtime/provider-bootstrap-utils.d.ts +20 -0
- package/dist/providers/core/runtime/provider-bootstrap-utils.js +78 -0
- package/dist/providers/core/runtime/provider-bootstrap-utils.js.map +1 -0
- package/dist/providers/core/runtime/provider-factory-helpers.d.ts +19 -0
- package/dist/providers/core/runtime/provider-factory-helpers.js +203 -0
- package/dist/providers/core/runtime/provider-factory-helpers.js.map +1 -0
- package/dist/providers/core/runtime/provider-factory.d.ts +9 -7
- package/dist/providers/core/runtime/provider-factory.js +57 -214
- package/dist/providers/core/runtime/provider-factory.js.map +1 -1
- package/dist/providers/core/runtime/provider-family-profile-utils.d.ts +23 -0
- package/dist/providers/core/runtime/provider-family-profile-utils.js +57 -0
- package/dist/providers/core/runtime/provider-family-profile-utils.js.map +1 -0
- package/dist/providers/core/runtime/provider-http-executor-utils.d.ts +32 -0
- package/dist/providers/core/runtime/provider-http-executor-utils.js +92 -0
- package/dist/providers/core/runtime/provider-http-executor-utils.js.map +1 -0
- package/dist/providers/core/runtime/provider-iflow-business-error-utils.d.ts +15 -0
- package/dist/providers/core/runtime/provider-iflow-business-error-utils.js +49 -0
- package/dist/providers/core/runtime/provider-iflow-business-error-utils.js.map +1 -0
- package/dist/providers/core/runtime/provider-request-executor-deps-factory.d.ts +29 -0
- package/dist/providers/core/runtime/provider-request-executor-deps-factory.js +41 -0
- package/dist/providers/core/runtime/provider-request-executor-deps-factory.js.map +1 -0
- package/dist/providers/core/runtime/provider-request-header-orchestrator.d.ts +30 -0
- package/dist/providers/core/runtime/provider-request-header-orchestrator.js +91 -0
- package/dist/providers/core/runtime/provider-request-header-orchestrator.js.map +1 -0
- package/dist/providers/core/runtime/provider-request-preprocessor.d.ts +5 -0
- package/dist/providers/core/runtime/provider-request-preprocessor.js +39 -0
- package/dist/providers/core/runtime/provider-request-preprocessor.js.map +1 -0
- package/dist/providers/core/runtime/provider-request-shaping-utils.d.ts +37 -0
- package/dist/providers/core/runtime/provider-request-shaping-utils.js +65 -0
- package/dist/providers/core/runtime/provider-request-shaping-utils.js.map +1 -0
- package/dist/providers/core/runtime/provider-response-postprocessor.d.ts +7 -0
- package/dist/providers/core/runtime/provider-response-postprocessor.js +28 -0
- package/dist/providers/core/runtime/provider-response-postprocessor.js.map +1 -0
- package/dist/providers/core/runtime/provider-runtime-utils.d.ts +16 -0
- package/dist/providers/core/runtime/provider-runtime-utils.js +51 -0
- package/dist/providers/core/runtime/provider-runtime-utils.js.map +1 -0
- package/dist/providers/core/runtime/responses-provider-helpers.d.ts +37 -0
- package/dist/providers/core/runtime/responses-provider-helpers.js +212 -0
- package/dist/providers/core/runtime/responses-provider-helpers.js.map +1 -0
- package/dist/providers/core/runtime/responses-provider.d.ts +0 -10
- package/dist/providers/core/runtime/responses-provider.js +14 -224
- package/dist/providers/core/runtime/responses-provider.js.map +1 -1
- package/dist/providers/core/runtime/runtime-endpoint-resolver.d.ts +21 -0
- package/dist/providers/core/runtime/runtime-endpoint-resolver.js +64 -0
- package/dist/providers/core/runtime/runtime-endpoint-resolver.js.map +1 -0
- package/dist/providers/core/runtime/service-profile-resolver.d.ts +29 -0
- package/dist/providers/core/runtime/service-profile-resolver.js +88 -0
- package/dist/providers/core/runtime/service-profile-resolver.js.map +1 -0
- package/dist/providers/core/runtime/transport/auth-mode-utils.d.ts +13 -0
- package/dist/providers/core/runtime/transport/auth-mode-utils.js +43 -0
- package/dist/providers/core/runtime/transport/auth-mode-utils.js.map +1 -0
- package/dist/providers/core/runtime/transport/auth-provider-factory.d.ts +37 -0
- package/dist/providers/core/runtime/transport/auth-provider-factory.js +131 -0
- package/dist/providers/core/runtime/transport/auth-provider-factory.js.map +1 -0
- package/dist/providers/core/runtime/transport/header-utils.d.ts +15 -0
- package/dist/providers/core/runtime/transport/header-utils.js +85 -0
- package/dist/providers/core/runtime/transport/header-utils.js.map +1 -0
- package/dist/providers/core/runtime/transport/iflow-signer.d.ts +12 -0
- package/dist/providers/core/runtime/transport/iflow-signer.js +63 -0
- package/dist/providers/core/runtime/transport/iflow-signer.js.map +1 -0
- package/dist/providers/core/runtime/transport/index.d.ts +15 -0
- package/dist/providers/core/runtime/transport/index.js +16 -0
- package/dist/providers/core/runtime/transport/index.js.map +1 -0
- package/dist/providers/core/runtime/transport/oauth-header-preflight.d.ts +12 -0
- package/dist/providers/core/runtime/transport/oauth-header-preflight.js +56 -0
- package/dist/providers/core/runtime/transport/oauth-header-preflight.js.map +1 -0
- package/dist/providers/core/runtime/transport/oauth-recovery-handler.d.ts +34 -0
- package/dist/providers/core/runtime/transport/oauth-recovery-handler.js +126 -0
- package/dist/providers/core/runtime/transport/oauth-recovery-handler.js.map +1 -0
- package/dist/providers/core/runtime/transport/provider-payload-utils.d.ts +21 -0
- package/dist/providers/core/runtime/transport/provider-payload-utils.js +88 -0
- package/dist/providers/core/runtime/transport/provider-payload-utils.js.map +1 -0
- package/dist/providers/core/runtime/transport/request-header-builder.d.ts +24 -0
- package/dist/providers/core/runtime/transport/request-header-builder.js +90 -0
- package/dist/providers/core/runtime/transport/request-header-builder.js.map +1 -0
- package/dist/providers/core/runtime/transport/runtime-detector.d.ts +22 -0
- package/dist/providers/core/runtime/transport/runtime-detector.js +63 -0
- package/dist/providers/core/runtime/transport/runtime-detector.js.map +1 -0
- package/dist/providers/core/runtime/transport/session-header-utils.d.ts +8 -0
- package/dist/providers/core/runtime/transport/session-header-utils.js +72 -0
- package/dist/providers/core/runtime/transport/session-header-utils.js.map +1 -0
- package/dist/providers/core/runtime/vision-debug-utils.d.ts +2 -0
- package/dist/providers/core/runtime/vision-debug-utils.js +31 -0
- package/dist/providers/core/runtime/vision-debug-utils.js.map +1 -1
- package/dist/providers/core/strategies/oauth-auth-code-flow.d.ts +13 -0
- package/dist/providers/core/strategies/oauth-auth-code-flow.js +272 -55
- package/dist/providers/core/strategies/oauth-auth-code-flow.js.map +1 -1
- package/dist/providers/core/utils/snapshot-writer-buffer.d.ts +13 -0
- package/dist/providers/core/utils/snapshot-writer-buffer.js +39 -0
- package/dist/providers/core/utils/snapshot-writer-buffer.js.map +1 -0
- package/dist/providers/core/utils/snapshot-writer.js +75 -54
- package/dist/providers/core/utils/snapshot-writer.js.map +1 -1
- package/dist/providers/profile/families/antigravity-profile.js +2 -10
- package/dist/providers/profile/families/antigravity-profile.js.map +1 -1
- package/dist/providers/profile/families/deepseek-profile.d.ts +2 -0
- package/dist/providers/profile/families/deepseek-profile.js +110 -0
- package/dist/providers/profile/families/deepseek-profile.js.map +1 -0
- package/dist/providers/profile/families/iflow-profile.js +89 -10
- package/dist/providers/profile/families/iflow-profile.js.map +1 -1
- package/dist/providers/profile/provider-profile-loader.d.ts +5 -0
- package/dist/providers/profile/provider-profile-loader.js +35 -0
- package/dist/providers/profile/provider-profile-loader.js.map +1 -1
- package/dist/providers/profile/provider-profile.d.ts +16 -1
- package/dist/runtime/runtime-flags.js +1 -1
- package/dist/runtime/runtime-flags.js.map +1 -1
- package/dist/runtime/wasm-runtime/index.d.ts +56 -0
- package/dist/runtime/wasm-runtime/index.js +69 -0
- package/dist/runtime/wasm-runtime/index.js.map +1 -0
- package/dist/scripts/camoufox/launch-auth.mjs +158 -10
- package/dist/server/handlers/handler-response-utils.d.ts +13 -0
- package/dist/server/handlers/handler-response-utils.js +427 -0
- package/dist/server/handlers/handler-response-utils.js.map +1 -0
- package/dist/server/handlers/handler-utils.d.ts +2 -11
- package/dist/server/handlers/handler-utils.js +21 -421
- package/dist/server/handlers/handler-utils.js.map +1 -1
- package/dist/server/runtime/http-server/clock-client-reaper.d.ts +23 -0
- package/dist/server/runtime/http-server/clock-client-reaper.js +159 -0
- package/dist/server/runtime/http-server/clock-client-reaper.js.map +1 -0
- package/dist/server/runtime/http-server/clock-client-registry-utils.d.ts +87 -0
- package/dist/server/runtime/http-server/clock-client-registry-utils.js +276 -0
- package/dist/server/runtime/http-server/clock-client-registry-utils.js.map +1 -0
- package/dist/server/runtime/http-server/clock-client-registry.d.ts +5 -50
- package/dist/server/runtime/http-server/clock-client-registry.js +74 -320
- package/dist/server/runtime/http-server/clock-client-registry.js.map +1 -1
- package/dist/server/runtime/http-server/clock-client-route-utils.d.ts +12 -0
- package/dist/server/runtime/http-server/clock-client-route-utils.js +210 -0
- package/dist/server/runtime/http-server/clock-client-route-utils.js.map +1 -0
- package/dist/server/runtime/http-server/clock-client-routes.js +27 -201
- package/dist/server/runtime/http-server/clock-client-routes.js.map +1 -1
- package/dist/server/runtime/http-server/clock-daemon-log-throttle.d.ts +12 -0
- package/dist/server/runtime/http-server/clock-daemon-log-throttle.js +56 -0
- package/dist/server/runtime/http-server/clock-daemon-log-throttle.js.map +1 -0
- package/dist/server/runtime/http-server/daemon-admin/control-handler.js +143 -14
- package/dist/server/runtime/http-server/daemon-admin/control-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/credentials-handler-utils.d.ts +19 -0
- package/dist/server/runtime/http-server/daemon-admin/credentials-handler-utils.js +107 -0
- package/dist/server/runtime/http-server/daemon-admin/credentials-handler-utils.js.map +1 -0
- package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js +2 -104
- package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/providers-handler-routing-utils.d.ts +28 -0
- package/dist/server/runtime/http-server/daemon-admin/providers-handler-routing-utils.js +298 -0
- package/dist/server/runtime/http-server/daemon-admin/providers-handler-routing-utils.js.map +1 -0
- package/dist/server/runtime/http-server/daemon-admin/providers-handler-utils.d.ts +22 -0
- package/dist/server/runtime/http-server/daemon-admin/providers-handler-utils.js +211 -0
- package/dist/server/runtime/http-server/daemon-admin/providers-handler-utils.js.map +1 -0
- package/dist/server/runtime/http-server/daemon-admin/providers-handler.js +25 -454
- package/dist/server/runtime/http-server/daemon-admin/providers-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/quota-handler.js +81 -32
- package/dist/server/runtime/http-server/daemon-admin/quota-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/routecodex-x7e-gate.d.ts +22 -0
- package/dist/server/runtime/http-server/daemon-admin/routecodex-x7e-gate.js +70 -0
- package/dist/server/runtime/http-server/daemon-admin/routecodex-x7e-gate.js.map +1 -0
- package/dist/server/runtime/http-server/executor/antigravity-detector.d.ts +34 -0
- package/dist/server/runtime/http-server/executor/antigravity-detector.js +118 -0
- package/dist/server/runtime/http-server/executor/antigravity-detector.js.map +1 -0
- package/dist/server/runtime/http-server/executor/env-config.d.ts +13 -0
- package/dist/server/runtime/http-server/executor/env-config.js +20 -0
- package/dist/server/runtime/http-server/executor/env-config.js.map +1 -0
- package/dist/server/runtime/http-server/executor/index.d.ts +11 -0
- package/dist/server/runtime/http-server/executor/index.js +18 -0
- package/dist/server/runtime/http-server/executor/index.js.map +1 -0
- package/dist/server/runtime/http-server/executor/provider-request-context.d.ts +20 -0
- package/dist/server/runtime/http-server/executor/provider-request-context.js +38 -0
- package/dist/server/runtime/http-server/executor/provider-request-context.js.map +1 -0
- package/dist/server/runtime/http-server/executor/provider-response-converter.d.ts +23 -0
- package/dist/server/runtime/http-server/executor/provider-response-converter.js +337 -0
- package/dist/server/runtime/http-server/executor/provider-response-converter.js.map +1 -0
- package/dist/server/runtime/http-server/executor/provider-response-utils.d.ts +8 -0
- package/dist/server/runtime/http-server/executor/provider-response-utils.js +93 -0
- package/dist/server/runtime/http-server/executor/provider-response-utils.js.map +1 -0
- package/dist/server/runtime/http-server/executor/provider-runtime-resolver.d.ts +23 -0
- package/dist/server/runtime/http-server/executor/provider-runtime-resolver.js +85 -0
- package/dist/server/runtime/http-server/executor/provider-runtime-resolver.js.map +1 -0
- package/dist/server/runtime/http-server/executor/request-executor-core-utils.d.ts +7 -0
- package/dist/server/runtime/http-server/executor/request-executor-core-utils.js +39 -0
- package/dist/server/runtime/http-server/executor/request-executor-core-utils.js.map +1 -0
- package/dist/server/runtime/http-server/executor/request-retry-helpers.d.ts +16 -0
- package/dist/server/runtime/http-server/executor/request-retry-helpers.js +218 -0
- package/dist/server/runtime/http-server/executor/request-retry-helpers.js.map +1 -0
- package/dist/server/runtime/http-server/executor/retry-engine.d.ts +21 -0
- package/dist/server/runtime/http-server/executor/retry-engine.js +73 -0
- package/dist/server/runtime/http-server/executor/retry-engine.js.map +1 -0
- package/dist/server/runtime/http-server/executor/sse-error-handler.d.ts +14 -0
- package/dist/server/runtime/http-server/executor/sse-error-handler.js +127 -0
- package/dist/server/runtime/http-server/executor/sse-error-handler.js.map +1 -0
- package/dist/server/runtime/http-server/executor/usage-aggregator.d.ts +39 -0
- package/dist/server/runtime/http-server/executor/usage-aggregator.js +177 -0
- package/dist/server/runtime/http-server/executor/usage-aggregator.js.map +1 -0
- package/dist/server/runtime/http-server/executor/usage-logger.d.ts +7 -0
- package/dist/server/runtime/http-server/executor/usage-logger.js +13 -0
- package/dist/server/runtime/http-server/executor/usage-logger.js.map +1 -0
- package/dist/server/runtime/http-server/executor/utils.d.ts +21 -0
- package/dist/server/runtime/http-server/executor/utils.js +62 -0
- package/dist/server/runtime/http-server/executor/utils.js.map +1 -0
- package/dist/server/runtime/http-server/executor-metadata.js +83 -2
- package/dist/server/runtime/http-server/executor-metadata.js.map +1 -1
- package/dist/server/runtime/http-server/executor-response.js +17 -9
- package/dist/server/runtime/http-server/executor-response.js.map +1 -1
- package/dist/server/runtime/http-server/http-server-bootstrap.d.ts +31 -0
- package/dist/server/runtime/http-server/http-server-bootstrap.js +367 -0
- package/dist/server/runtime/http-server/http-server-bootstrap.js.map +1 -0
- package/dist/server/runtime/http-server/http-server-clock-daemon.d.ts +5 -0
- package/dist/server/runtime/http-server/http-server-clock-daemon.js +242 -0
- package/dist/server/runtime/http-server/http-server-clock-daemon.js.map +1 -0
- package/dist/server/runtime/http-server/http-server-legacy-pipeline.d.ts +2 -0
- package/dist/server/runtime/http-server/http-server-legacy-pipeline.js +65 -0
- package/dist/server/runtime/http-server/http-server-legacy-pipeline.js.map +1 -0
- package/dist/server/runtime/http-server/http-server-lifecycle.d.ts +27 -0
- package/dist/server/runtime/http-server/http-server-lifecycle.js +285 -0
- package/dist/server/runtime/http-server/http-server-lifecycle.js.map +1 -0
- package/dist/server/runtime/http-server/http-server-runtime-providers.d.ts +10 -0
- package/dist/server/runtime/http-server/http-server-runtime-providers.js +415 -0
- package/dist/server/runtime/http-server/http-server-runtime-providers.js.map +1 -0
- package/dist/server/runtime/http-server/http-server-runtime-setup.d.ts +2 -0
- package/dist/server/runtime/http-server/http-server-runtime-setup.js +93 -0
- package/dist/server/runtime/http-server/http-server-runtime-setup.js.map +1 -0
- package/dist/server/runtime/http-server/index.d.ts +2 -46
- package/dist/server/runtime/http-server/index.js +96 -2615
- package/dist/server/runtime/http-server/index.js.map +1 -1
- package/dist/server/runtime/http-server/request-executor.d.ts +8 -21
- package/dist/server/runtime/http-server/request-executor.js +94 -956
- package/dist/server/runtime/http-server/request-executor.js.map +1 -1
- package/dist/server/runtime/http-server/routes.js +2 -2
- package/dist/server/runtime/http-server/routes.js.map +1 -1
- package/dist/server/runtime/http-server/servertool-admin-state.d.ts +42 -0
- package/dist/server/runtime/http-server/servertool-admin-state.js +210 -0
- package/dist/server/runtime/http-server/servertool-admin-state.js.map +1 -0
- package/dist/server/runtime/http-server/stats-manager-internals.d.ts +96 -0
- package/dist/server/runtime/http-server/stats-manager-internals.js +311 -0
- package/dist/server/runtime/http-server/stats-manager-internals.js.map +1 -0
- package/dist/server/runtime/http-server/stats-manager-table.d.ts +6 -0
- package/dist/server/runtime/http-server/stats-manager-table.js +135 -0
- package/dist/server/runtime/http-server/stats-manager-table.js.map +1 -0
- package/dist/server/runtime/http-server/stats-manager.d.ts +0 -23
- package/dist/server/runtime/http-server/stats-manager.js +95 -483
- package/dist/server/runtime/http-server/stats-manager.js.map +1 -1
- package/dist/server/utils/client-connection-state.js +61 -0
- package/dist/server/utils/client-connection-state.js.map +1 -1
- package/dist/server/utils/request-id-manager.d.ts +6 -0
- package/dist/server/utils/request-id-manager.js +105 -15
- package/dist/server/utils/request-id-manager.js.map +1 -1
- package/dist/server/utils/stage-logger.js +14 -4
- package/dist/server/utils/stage-logger.js.map +1 -1
- package/dist/server-lifecycle/index.d.ts +6 -0
- package/dist/server-lifecycle/index.js +7 -0
- package/dist/server-lifecycle/index.js.map +1 -0
- package/dist/server-lifecycle/port-utils.d.ts +18 -0
- package/dist/server-lifecycle/port-utils.js +204 -0
- package/dist/server-lifecycle/port-utils.js.map +1 -0
- package/dist/sharedmodule/process-snapshot.d.ts +26 -0
- package/dist/sharedmodule/process-snapshot.js +141 -0
- package/dist/sharedmodule/process-snapshot.js.map +1 -0
- package/dist/token-daemon/index.js +10 -3
- package/dist/token-daemon/index.js.map +1 -1
- package/dist/token-daemon/token-daemon.js +9 -11
- package/dist/token-daemon/token-daemon.js.map +1 -1
- package/dist/token-daemon/token-utils.d.ts +1 -1
- package/dist/token-daemon/token-utils.js +19 -3
- package/dist/token-daemon/token-utils.js.map +1 -1
- package/dist/tools/semantic-replay-snapshot-loader.d.ts +4 -0
- package/dist/tools/semantic-replay-snapshot-loader.js +396 -0
- package/dist/tools/semantic-replay-snapshot-loader.js.map +1 -0
- package/dist/tools/semantic-replay.js +2 -393
- package/dist/tools/semantic-replay.js.map +1 -1
- package/dist/utils/daemon-stop-intent.d.ts +17 -0
- package/dist/utils/daemon-stop-intent.js +104 -0
- package/dist/utils/daemon-stop-intent.js.map +1 -0
- package/dist/utils/key-429-tracker.js +6 -5
- package/dist/utils/key-429-tracker.js.map +1 -1
- package/dist/utils/managed-server-pids.js +44 -6
- package/dist/utils/managed-server-pids.js.map +1 -1
- package/dist/utils/pipeline-health-manager.js +7 -6
- package/dist/utils/pipeline-health-manager.js.map +1 -1
- package/dist/utils/process-lifecycle-logger.js +45 -1
- package/dist/utils/process-lifecycle-logger.js.map +1 -1
- package/dist/utils/runtime-exit-forensics.d.ts +2 -2
- package/dist/utils/runtime-exit-forensics.js +10 -5
- package/dist/utils/runtime-exit-forensics.js.map +1 -1
- package/dist/utils/snapshot-writer.js +3 -3
- package/dist/utils/snapshot-writer.js.map +1 -1
- package/docs/QUOTA_MANAGER_V3.md +3 -0
- package/docs/VIRTUAL_ROUTER_PRIORITY_AND_HEALTH.md +114 -0
- package/docs/daemon-admin-ui.html +268 -11
- package/docs/file-line-limit-gate.md +30 -0
- package/docs/refactoring/host-164.3-responsibility-migration.md +62 -0
- package/docs/release-iflow-400-gate.md +58 -0
- package/docs/replay-evidence-iflow-400.txt +33 -0
- package/docs/stop-message-auto.md +4 -3
- package/package.json +4 -3
- package/scripts/auth-iflow-manual.mjs +13 -23
- package/scripts/camoufox/launch-auth.mjs +158 -10
- package/scripts/ci/check-file-line-limit.mjs +149 -0
- package/scripts/copy-compat-assets.mjs +26 -0
- package/scripts/tests/ci-jest.mjs +4 -0
- package/scripts/verify-codex-error-samples.mjs +27 -6
|
@@ -8,25 +8,23 @@
|
|
|
8
8
|
*
|
|
9
9
|
* 各协议具体行为(OpenAI Chat、Responses、Anthropic、Gemini 等)通过子类覆写钩子实现。
|
|
10
10
|
*/
|
|
11
|
-
import { createHash, createHmac } from 'node:crypto';
|
|
12
11
|
import { BaseProvider } from './base-provider.js';
|
|
13
|
-
import {
|
|
14
|
-
import { DynamicProfileLoader, ServiceProfileValidator } from '../config/service-profiles.js';
|
|
15
|
-
import { ApiKeyAuthProvider } from '../../auth/apikey-auth.js';
|
|
16
|
-
import { OAuthAuthProvider } from '../../auth/oauth-auth.js';
|
|
17
|
-
import { logOAuthDebug } from '../../auth/oauth-logger.js';
|
|
18
|
-
import { TokenFileAuthProvider } from '../../auth/tokenfile-auth.js';
|
|
19
|
-
import { IflowCookieAuthProvider } from '../../auth/iflow-cookie-auth.js';
|
|
20
|
-
import { ensureValidOAuthToken, handleUpstreamInvalidOAuthToken, shouldTriggerInteractiveOAuthRepair } from '../../auth/oauth-lifecycle.js';
|
|
21
|
-
import { attachProviderSseSnapshotStream, writeProviderSnapshot } from '../utils/snapshot-writer.js';
|
|
22
|
-
import { attachProviderRuntimeMetadata, extractProviderRuntimeMetadata } from './provider-runtime-metadata.js';
|
|
23
|
-
import { buildVisionSnapshotPayload, shouldCaptureVisionDebug, summarizeVisionMessages } from './vision-debug-utils.js';
|
|
12
|
+
import { captureVisionDebugPayloadSnapshot, logVisionDebugSummary } from './vision-debug-utils.js';
|
|
24
13
|
import { OpenAIChatProtocolClient } from '../../../client/openai/chat-protocol-client.js';
|
|
25
14
|
import { HttpRequestExecutor } from './http-request-executor.js';
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
|
|
29
|
-
|
|
15
|
+
import { normalizeProviderHttpError } from './provider-http-executor-utils.js';
|
|
16
|
+
import { RuntimeEndpointResolver } from './runtime-endpoint-resolver.js';
|
|
17
|
+
import { ProviderRequestPreprocessor } from './provider-request-preprocessor.js';
|
|
18
|
+
import { buildProviderRequestExecutorDeps } from './provider-request-executor-deps-factory.js';
|
|
19
|
+
import { buildPostprocessedProviderResponse } from './provider-response-postprocessor.js';
|
|
20
|
+
import { ServiceProfileResolver } from './service-profile-resolver.js';
|
|
21
|
+
import { createTransportAuthProvider, createTransportHttpClient } from './provider-bootstrap-utils.js';
|
|
22
|
+
import { createProviderRuntimeContext, resolveProviderProfileKey } from './provider-runtime-utils.js';
|
|
23
|
+
import { buildProviderRequestHeaders, finalizeProviderRequestHeaders } from './provider-request-header-orchestrator.js';
|
|
24
|
+
import { resolveLegacyIflowEndpoint as resolveLegacyIflowEndpointFromRequest, resolveLegacyIflowRequestBody as resolveLegacyIflowRequestBodyFromRequest, resolveProviderFamilyProfile } from './provider-family-profile-utils.js';
|
|
25
|
+
import { applyProviderStreamModeHeaders, buildProviderHttpRequestBody, resolveProviderBusinessResponseError, resolveProviderRequestEndpoint, resolveProviderWantsUpstreamSse } from './provider-request-shaping-utils.js';
|
|
26
|
+
// Transport submodules
|
|
27
|
+
import { AuthModeUtils, RuntimeDetector } from './transport/index.js';
|
|
30
28
|
export class HttpTransportProvider extends BaseProvider {
|
|
31
29
|
type;
|
|
32
30
|
authProvider = null;
|
|
@@ -58,7 +56,7 @@ export class HttpTransportProvider extends BaseProvider {
|
|
|
58
56
|
await this.authProvider.initialize();
|
|
59
57
|
const providerConfig = this.config.config;
|
|
60
58
|
const auth = providerConfig.auth;
|
|
61
|
-
const authMode =
|
|
59
|
+
const authMode = AuthModeUtils.normalizeAuthMode(auth.type);
|
|
62
60
|
// Token 管理迁移后,OAuth 初始化交由 TokenManager/TokenDaemon 负责,
|
|
63
61
|
// 这里不再在服务器启动阶段主动跑 ensureValidOAuthToken,避免多余日志和上游调用。
|
|
64
62
|
if (authMode !== 'oauth') {
|
|
@@ -101,223 +99,40 @@ export class HttpTransportProvider extends BaseProvider {
|
|
|
101
99
|
}
|
|
102
100
|
getServiceProfile() {
|
|
103
101
|
const cfg = this.config.config;
|
|
104
|
-
const profileKey =
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
const endpointFromCfg = (cfg.overrides?.endpoint || cfg.endpoint || '').trim();
|
|
115
|
-
const defaultModelFromCfg = (cfg.overrides?.defaultModel || cfg.defaultModel || '').trim();
|
|
116
|
-
const timeoutFromCfg = cfg.overrides?.timeout ?? cfg.timeout;
|
|
117
|
-
const maxRetriesFromCfg = cfg.overrides?.maxRetries ?? cfg.maxRetries;
|
|
118
|
-
const headersFromCfg = (cfg.overrides?.headers || cfg.headers);
|
|
119
|
-
const authCapsFromCfg = cfg.authCapabilities;
|
|
120
|
-
const hasConfigCoreProfile = !!baseFromCfg ||
|
|
121
|
-
!!endpointFromCfg ||
|
|
122
|
-
!!defaultModelFromCfg ||
|
|
123
|
-
typeof timeoutFromCfg === 'number' ||
|
|
124
|
-
typeof maxRetriesFromCfg === 'number' ||
|
|
125
|
-
!!authCapsFromCfg ||
|
|
126
|
-
!!headersFromCfg;
|
|
127
|
-
// 先从 service-profiles 取出基础 profile(用于补全缺失字段/校验)
|
|
128
|
-
const baseProfile = DynamicProfileLoader.buildServiceProfile(profileKey) ||
|
|
129
|
-
DynamicProfileLoader.buildServiceProfile(this.providerType);
|
|
130
|
-
// 如果 config-core 已提供字段,或强制要求使用 config-core,则以 config-core 为主
|
|
131
|
-
if (hasConfigCoreProfile || forceConfigCoreDefaults) {
|
|
132
|
-
if (forceConfigCoreDefaults) {
|
|
133
|
-
// 严格模式下,关键字段缺失直接 Fail Fast
|
|
134
|
-
if (!baseFromCfg) {
|
|
135
|
-
throw new Error(`Provider config-core defaults missing baseUrl for providerId=${profileKey}`);
|
|
136
|
-
}
|
|
137
|
-
if (!endpointFromCfg && !baseProfile?.defaultEndpoint) {
|
|
138
|
-
throw new Error(`Provider config-core defaults missing endpoint for providerId=${profileKey}`);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
const defaultBaseUrl = baseFromCfg ||
|
|
142
|
-
baseProfile?.defaultBaseUrl ||
|
|
143
|
-
'https://api.openai.com/v1';
|
|
144
|
-
const defaultEndpoint = endpointFromCfg ||
|
|
145
|
-
baseProfile?.defaultEndpoint ||
|
|
146
|
-
'/chat/completions';
|
|
147
|
-
const defaultModel = (defaultModelFromCfg && defaultModelFromCfg.length > 0)
|
|
148
|
-
? defaultModelFromCfg
|
|
149
|
-
: (baseProfile?.defaultModel ?? '');
|
|
150
|
-
const genericRequiredAuth = [];
|
|
151
|
-
const genericOptionalAuth = ['apikey', 'oauth'];
|
|
152
|
-
const requiredAuth = authCapsFromCfg?.required && authCapsFromCfg.required.length
|
|
153
|
-
? authCapsFromCfg.required
|
|
154
|
-
: (baseProfile?.requiredAuth ?? genericRequiredAuth);
|
|
155
|
-
const optionalAuth = authCapsFromCfg?.optional && authCapsFromCfg.optional.length
|
|
156
|
-
? authCapsFromCfg.optional
|
|
157
|
-
: (baseProfile?.optionalAuth ?? genericOptionalAuth);
|
|
158
|
-
const mergedHeaders = {
|
|
159
|
-
...(baseProfile?.headers || {}),
|
|
160
|
-
...(headersFromCfg || {})
|
|
161
|
-
};
|
|
162
|
-
const timeout = typeof timeoutFromCfg === 'number'
|
|
163
|
-
? timeoutFromCfg
|
|
164
|
-
// 默认 Provider 请求超时时间:500s
|
|
165
|
-
: (baseProfile?.timeout ?? 500000);
|
|
166
|
-
const maxRetries = typeof maxRetriesFromCfg === 'number'
|
|
167
|
-
? maxRetriesFromCfg
|
|
168
|
-
: (baseProfile?.maxRetries ?? 3);
|
|
169
|
-
return {
|
|
170
|
-
defaultBaseUrl,
|
|
171
|
-
defaultEndpoint,
|
|
172
|
-
defaultModel,
|
|
173
|
-
requiredAuth,
|
|
174
|
-
optionalAuth,
|
|
175
|
-
headers: mergedHeaders,
|
|
176
|
-
timeout,
|
|
177
|
-
maxRetries,
|
|
178
|
-
hooks: baseProfile?.hooks,
|
|
179
|
-
features: baseProfile?.features,
|
|
180
|
-
extensions: {
|
|
181
|
-
...(baseProfile?.extensions || {}),
|
|
182
|
-
protocol: cfg.protocol || baseProfile?.extensions?.protocol
|
|
183
|
-
}
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
// 未提供 config-core provider 行为字段时,保持原有 service-profiles 行为
|
|
187
|
-
if (baseProfile) {
|
|
188
|
-
return baseProfile;
|
|
189
|
-
}
|
|
190
|
-
throw new Error(`Unknown providerType='${this.providerType}' (no service profile registered)`);
|
|
102
|
+
const profileKey = resolveProviderProfileKey({
|
|
103
|
+
moduleType: this.type,
|
|
104
|
+
providerType: this.providerType,
|
|
105
|
+
providerId: typeof cfg.providerId === 'string' ? cfg.providerId : undefined
|
|
106
|
+
});
|
|
107
|
+
return ServiceProfileResolver.resolve({
|
|
108
|
+
cfg,
|
|
109
|
+
profileKey,
|
|
110
|
+
providerType: this.providerType
|
|
111
|
+
});
|
|
191
112
|
}
|
|
192
113
|
createAuthProvider() {
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
throw new Error(`Invalid auth configuration for ${serviceProfileKey}: ${validation.errors.join(', ')}`);
|
|
206
|
-
}
|
|
207
|
-
// 根据认证类型创建对应的认证提供者
|
|
208
|
-
if (authMode === 'apikey') {
|
|
209
|
-
const rawTypeValue = typeof auth.rawType === 'string'
|
|
210
|
-
? String(auth.rawType)
|
|
211
|
-
: typeof auth.type === 'string'
|
|
212
|
-
? String(auth.type)
|
|
213
|
-
: '';
|
|
214
|
-
const rawType = rawTypeValue.toLowerCase();
|
|
215
|
-
const providerId = typeof (this.config.config.providerId) === 'string'
|
|
216
|
-
? this.config.config.providerId.toLowerCase()
|
|
217
|
-
: '';
|
|
218
|
-
const baseUrl = typeof this.config.config.baseUrl === 'string'
|
|
219
|
-
? this.config.config.baseUrl.toLowerCase()
|
|
220
|
-
: '';
|
|
221
|
-
const isIflowFamily = providerId === 'iflow' ||
|
|
222
|
-
baseUrl.includes('apis.iflow.cn') ||
|
|
223
|
-
baseUrl.includes('iflow.cn');
|
|
224
|
-
// iFlow Cookie 模式:使用浏览器导出的 Cookie 交换 API Key,避免频繁走 OAuth。
|
|
225
|
-
if (isIflowFamily &&
|
|
226
|
-
(rawType === 'iflow-cookie' ||
|
|
227
|
-
(!(auth.apiKey) &&
|
|
228
|
-
(typeof auth.cookie === 'string' ||
|
|
229
|
-
typeof auth.cookieFile === 'string')))) {
|
|
230
|
-
return new IflowCookieAuthProvider(auth);
|
|
231
|
-
}
|
|
232
|
-
return new ApiKeyAuthProvider(auth);
|
|
233
|
-
}
|
|
234
|
-
else if (authMode === 'oauth') {
|
|
235
|
-
const oauthAuth = auth;
|
|
236
|
-
const oauthProviderId = resolvedOAuthProviderId ?? serviceProfileKey;
|
|
237
|
-
this.oauthProviderId = oauthProviderId;
|
|
238
|
-
const familyProfile = getProviderFamilyProfile({
|
|
239
|
-
providerId: this.config.config.providerId,
|
|
240
|
-
providerType: this.providerType,
|
|
241
|
-
oauthProviderId
|
|
242
|
-
});
|
|
243
|
-
const profileTokenFileMode = familyProfile?.resolveOAuthTokenFileMode?.({
|
|
244
|
-
oauthProviderId,
|
|
245
|
-
auth: {
|
|
246
|
-
clientId: oauthAuth.clientId,
|
|
247
|
-
tokenUrl: oauthAuth.tokenUrl,
|
|
248
|
-
deviceCodeUrl: oauthAuth.deviceCodeUrl
|
|
249
|
-
},
|
|
250
|
-
moduleType: this.type
|
|
251
|
-
});
|
|
252
|
-
// For providers like Qwen/iflow/Gemini CLI where public OAuth client may not be available,
|
|
253
|
-
// allow reading tokens produced by external login tools (CLIProxyAPI) via token file.
|
|
254
|
-
const useTokenFile = (typeof profileTokenFileMode === 'boolean'
|
|
255
|
-
? profileTokenFileMode
|
|
256
|
-
: (oauthProviderId === 'qwen' ||
|
|
257
|
-
oauthProviderId === 'iflow' ||
|
|
258
|
-
this.type === 'gemini-cli-http-provider')) &&
|
|
259
|
-
!oauthAuth.clientId &&
|
|
260
|
-
!oauthAuth.tokenUrl &&
|
|
261
|
-
!oauthAuth.deviceCodeUrl;
|
|
262
|
-
if (useTokenFile) {
|
|
263
|
-
// Keep TokenFileAuthProvider pure: do not infer providerId from type/rawType.
|
|
264
|
-
// The creator already knows oauthProviderId and must pass it explicitly.
|
|
265
|
-
return new TokenFileAuthProvider({ ...oauthAuth, oauthProviderId });
|
|
266
|
-
}
|
|
267
|
-
return new OAuthAuthProvider(oauthAuth, oauthProviderId);
|
|
268
|
-
}
|
|
269
|
-
else {
|
|
270
|
-
throw new Error(`Unsupported auth type: ${auth.type}`);
|
|
271
|
-
}
|
|
114
|
+
const authBootstrap = createTransportAuthProvider({
|
|
115
|
+
config: this.config,
|
|
116
|
+
providerType: this.providerType,
|
|
117
|
+
moduleType: this.type,
|
|
118
|
+
serviceProfile: this.serviceProfile,
|
|
119
|
+
extensions: this.config.config.extensions && typeof this.config.config.extensions === 'object'
|
|
120
|
+
? this.config.config.extensions
|
|
121
|
+
: undefined
|
|
122
|
+
});
|
|
123
|
+
this.authMode = authBootstrap.authMode;
|
|
124
|
+
this.oauthProviderId = authBootstrap.oauthProviderId;
|
|
125
|
+
return authBootstrap.authProvider;
|
|
272
126
|
}
|
|
273
127
|
createHttpClient() {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
? envTimeout
|
|
279
|
-
// 默认 Provider 请求超时时间:500s(可被 env / overrides 覆盖)
|
|
280
|
-
: (this.config.config.overrides?.timeout ?? profile.timeout ?? 500000);
|
|
281
|
-
const envRetries = Number(process.env.ROUTECODEX_PROVIDER_RETRIES || process.env.RCC_PROVIDER_RETRIES || NaN);
|
|
282
|
-
const effectiveRetries = Number.isFinite(envRetries) && envRetries >= 0
|
|
283
|
-
? envRetries
|
|
284
|
-
: (this.config.config.overrides?.maxRetries ?? profile.maxRetries ?? 3);
|
|
285
|
-
const overrideHeaders = this.config.config.overrides?.headers ||
|
|
286
|
-
this.config.config.headers ||
|
|
287
|
-
undefined;
|
|
288
|
-
const envStreamIdleTimeoutMs = Number(process.env.ROUTECODEX_PROVIDER_STREAM_IDLE_TIMEOUT_MS ||
|
|
289
|
-
process.env.RCC_PROVIDER_STREAM_IDLE_TIMEOUT_MS ||
|
|
290
|
-
NaN);
|
|
291
|
-
const normalizedStreamIdleTimeoutMs = Number.isFinite(envStreamIdleTimeoutMs) && envStreamIdleTimeoutMs > 0
|
|
292
|
-
? envStreamIdleTimeoutMs
|
|
293
|
-
: (typeof this.config.config.overrides?.streamIdleTimeoutMs === 'number' &&
|
|
294
|
-
Number.isFinite(this.config.config.overrides.streamIdleTimeoutMs)
|
|
295
|
-
? this.config.config.overrides.streamIdleTimeoutMs
|
|
296
|
-
: undefined);
|
|
297
|
-
const envStreamHeadersTimeoutMs = Number(process.env.ROUTECODEX_PROVIDER_STREAM_HEADERS_TIMEOUT_MS ||
|
|
298
|
-
process.env.RCC_PROVIDER_STREAM_HEADERS_TIMEOUT_MS ||
|
|
299
|
-
NaN);
|
|
300
|
-
const normalizedStreamHeadersTimeoutMs = Number.isFinite(envStreamHeadersTimeoutMs) && envStreamHeadersTimeoutMs > 0
|
|
301
|
-
? envStreamHeadersTimeoutMs
|
|
302
|
-
: (typeof this.config.config.overrides?.streamHeadersTimeoutMs === 'number' &&
|
|
303
|
-
Number.isFinite(this.config.config.overrides.streamHeadersTimeoutMs)
|
|
304
|
-
? this.config.config.overrides.streamHeadersTimeoutMs
|
|
305
|
-
: undefined);
|
|
306
|
-
this.httpClient = new HttpClient({
|
|
307
|
-
baseUrl: effectiveBase,
|
|
308
|
-
timeout: effectiveTimeout,
|
|
309
|
-
maxRetries: effectiveRetries,
|
|
310
|
-
streamIdleTimeoutMs: normalizedStreamIdleTimeoutMs ?? profile.streamIdleTimeoutMs,
|
|
311
|
-
streamHeadersTimeoutMs: normalizedStreamHeadersTimeoutMs ?? profile.streamHeadersTimeoutMs,
|
|
312
|
-
defaultHeaders: {
|
|
313
|
-
'Content-Type': 'application/json',
|
|
314
|
-
...(profile.headers || {}),
|
|
315
|
-
...(overrideHeaders || {}),
|
|
316
|
-
}
|
|
128
|
+
this.httpClient = createTransportHttpClient({
|
|
129
|
+
config: this.config,
|
|
130
|
+
serviceProfile: this.serviceProfile,
|
|
131
|
+
effectiveBaseUrl: this.getEffectiveBaseUrl()
|
|
317
132
|
});
|
|
318
133
|
}
|
|
319
134
|
createRequestExecutorDeps() {
|
|
320
|
-
return {
|
|
135
|
+
return buildProviderRequestExecutorDeps({
|
|
321
136
|
wantsUpstreamSse: this.wantsUpstreamSse.bind(this),
|
|
322
137
|
getEffectiveEndpoint: () => this.getEffectiveEndpoint(),
|
|
323
138
|
resolveRequestEndpoint: this.resolveRequestEndpoint.bind(this),
|
|
@@ -328,121 +143,32 @@ export class HttpTransportProvider extends BaseProvider {
|
|
|
328
143
|
getBaseUrlCandidates: this.getBaseUrlCandidates.bind(this),
|
|
329
144
|
buildHttpRequestBody: this.buildHttpRequestBody.bind(this),
|
|
330
145
|
prepareSseRequestBody: this.prepareSseRequestBody.bind(this),
|
|
331
|
-
getEntryEndpointFromPayload: this.getEntryEndpointFromPayload.bind(this),
|
|
332
|
-
getClientRequestIdFromContext: this.getClientRequestIdFromContext.bind(this),
|
|
333
146
|
wrapUpstreamSseResponse: this.wrapUpstreamSseResponse.bind(this),
|
|
334
|
-
getHttpRetryLimit: () => this.getHttpRetryLimit(),
|
|
335
|
-
shouldRetryHttpError: this.shouldRetryHttpError.bind(this),
|
|
336
|
-
delayBeforeHttpRetry: this.delayBeforeHttpRetry.bind(this),
|
|
337
|
-
tryRecoverOAuthAndReplay: this.tryRecoverOAuthAndReplay.bind(this),
|
|
338
147
|
resolveBusinessResponseError: this.resolveProfileBusinessResponseError.bind(this),
|
|
339
|
-
normalizeHttpError: this.normalizeHttpError.bind(this)
|
|
340
|
-
|
|
148
|
+
normalizeHttpError: this.normalizeHttpError.bind(this),
|
|
149
|
+
authProvider: this.authProvider,
|
|
150
|
+
oauthProviderId: this.oauthProviderId,
|
|
151
|
+
providerType: this.providerType,
|
|
152
|
+
config: this.config,
|
|
153
|
+
httpClient: this.httpClient
|
|
154
|
+
});
|
|
341
155
|
}
|
|
342
156
|
async preprocessRequest(request) {
|
|
343
157
|
const context = this.createProviderContext();
|
|
344
158
|
const runtimeMetadata = context.runtimeMetadata;
|
|
345
|
-
const headersFromRequest = this.normalizeClientHeaders(request?.metadata?.clientHeaders);
|
|
346
|
-
const headersFromRuntime = this.normalizeClientHeaders(runtimeMetadata?.metadata && typeof runtimeMetadata.metadata === 'object'
|
|
347
|
-
? runtimeMetadata.metadata.clientHeaders
|
|
348
|
-
: undefined);
|
|
349
|
-
const effectiveClientHeaders = headersFromRequest ?? headersFromRuntime;
|
|
350
|
-
if (effectiveClientHeaders) {
|
|
351
|
-
if (runtimeMetadata) {
|
|
352
|
-
if (!runtimeMetadata.metadata || typeof runtimeMetadata.metadata !== 'object') {
|
|
353
|
-
runtimeMetadata.metadata = {};
|
|
354
|
-
}
|
|
355
|
-
runtimeMetadata.metadata.clientHeaders = effectiveClientHeaders;
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
const ensureRuntimeMetadata = (payload) => {
|
|
359
|
-
if (!runtimeMetadata || !payload || typeof payload !== 'object') {
|
|
360
|
-
return;
|
|
361
|
-
}
|
|
362
|
-
attachProviderRuntimeMetadata(payload, runtimeMetadata);
|
|
363
|
-
};
|
|
364
|
-
// 初始请求预处理
|
|
365
159
|
this.getRuntimeProfile();
|
|
366
|
-
const processedRequest =
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
try {
|
|
370
|
-
const requestCarrier = request;
|
|
371
|
-
const inboundModel = typeof requestCarrier?.model === 'string' ? requestCarrier.model : undefined;
|
|
372
|
-
const entryEndpoint = typeof requestCarrier?.metadata?.entryEndpoint === 'string'
|
|
373
|
-
? requestCarrier.metadata.entryEndpoint
|
|
374
|
-
: requestCarrier?.entryEndpoint;
|
|
375
|
-
const streamFlag = typeof requestCarrier?.metadata?.stream === 'boolean'
|
|
376
|
-
? requestCarrier.metadata.stream
|
|
377
|
-
: requestCarrier?.stream;
|
|
378
|
-
const processedMetadata = processedRequest.metadata ?? {};
|
|
379
|
-
processedRequest.metadata = {
|
|
380
|
-
...processedMetadata,
|
|
381
|
-
...(entryEndpoint ? { entryEndpoint } : {}),
|
|
382
|
-
...(typeof streamFlag === 'boolean' ? { stream: !!streamFlag } : {}),
|
|
383
|
-
...(effectiveClientHeaders ? { clientHeaders: effectiveClientHeaders } : {}),
|
|
384
|
-
__origModel: inboundModel
|
|
385
|
-
};
|
|
386
|
-
}
|
|
387
|
-
catch { /* ignore */ }
|
|
388
|
-
this.logVisionDebug('preprocess', processedRequest);
|
|
389
|
-
await this.captureVisionDebugSnapshot('provider-preprocess-debug', processedRequest);
|
|
160
|
+
const processedRequest = ProviderRequestPreprocessor.preprocess(request, runtimeMetadata);
|
|
161
|
+
logVisionDebugSummary('preprocess', processedRequest);
|
|
162
|
+
await captureVisionDebugPayloadSnapshot('provider-preprocess-debug', processedRequest);
|
|
390
163
|
return processedRequest;
|
|
391
164
|
}
|
|
392
165
|
async postprocessResponse(response, context) {
|
|
393
166
|
this.getRuntimeProfile();
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
processedRecord.data?.__sse_responses;
|
|
400
|
-
if (sseStream) {
|
|
401
|
-
return { __sse_responses: sseStream };
|
|
402
|
-
}
|
|
403
|
-
return {
|
|
404
|
-
data: processedRecord.data || processedResponse,
|
|
405
|
-
status: processedRecord.status ?? originalRecord.status,
|
|
406
|
-
headers: processedRecord.headers || originalRecord.headers,
|
|
407
|
-
metadata: {
|
|
408
|
-
requestId: context.requestId,
|
|
409
|
-
processingTime,
|
|
410
|
-
providerType: this.providerType,
|
|
411
|
-
// 对外暴露的 model 统一为入站模型
|
|
412
|
-
model: context.model ?? this.extractModel(processedRecord) ?? this.extractModel(originalRecord),
|
|
413
|
-
usage: this.extractUsage(processedRecord) ?? this.extractUsage(originalRecord)
|
|
414
|
-
}
|
|
415
|
-
};
|
|
416
|
-
}
|
|
417
|
-
logVisionDebug(stage, payload) {
|
|
418
|
-
const debug = shouldCaptureVisionDebug(payload);
|
|
419
|
-
if (!debug.enabled) {
|
|
420
|
-
return;
|
|
421
|
-
}
|
|
422
|
-
const summary = summarizeVisionMessages(payload);
|
|
423
|
-
const label = debug.routeName ?? 'vision';
|
|
424
|
-
console.debug(`[vision-debug][${stage}] route=${label} request=${debug.requestId ?? '-'} ${summary}`);
|
|
425
|
-
}
|
|
426
|
-
async captureVisionDebugSnapshot(stage, payload) {
|
|
427
|
-
const debug = shouldCaptureVisionDebug(payload);
|
|
428
|
-
if (!debug.enabled || !debug.requestId) {
|
|
429
|
-
return;
|
|
430
|
-
}
|
|
431
|
-
try {
|
|
432
|
-
const metadataNode = payload?.metadata;
|
|
433
|
-
const entryEndpoint = metadataNode && typeof metadataNode === 'object' && typeof metadataNode.entryEndpoint === 'string'
|
|
434
|
-
? metadataNode.entryEndpoint
|
|
435
|
-
: undefined;
|
|
436
|
-
await writeProviderSnapshot({
|
|
437
|
-
phase: stage,
|
|
438
|
-
requestId: debug.requestId,
|
|
439
|
-
data: buildVisionSnapshotPayload(payload),
|
|
440
|
-
entryEndpoint
|
|
441
|
-
});
|
|
442
|
-
}
|
|
443
|
-
catch {
|
|
444
|
-
// snapshot is best-effort; ignore failures
|
|
445
|
-
}
|
|
167
|
+
return buildPostprocessedProviderResponse({
|
|
168
|
+
response,
|
|
169
|
+
context,
|
|
170
|
+
providerType: this.providerType
|
|
171
|
+
});
|
|
446
172
|
}
|
|
447
173
|
async sendRequestInternal(request) {
|
|
448
174
|
const context = this.createProviderContext();
|
|
@@ -450,39 +176,30 @@ export class HttpTransportProvider extends BaseProvider {
|
|
|
450
176
|
}
|
|
451
177
|
wantsUpstreamSse(request, context) {
|
|
452
178
|
const runtimeMetadata = context.runtimeMetadata ?? this.getCurrentRuntimeMetadata();
|
|
453
|
-
|
|
454
|
-
const profileResolved = familyProfile?.resolveStreamIntent?.({
|
|
179
|
+
return resolveProviderWantsUpstreamSse({
|
|
455
180
|
request,
|
|
456
181
|
context,
|
|
457
|
-
runtimeMetadata
|
|
182
|
+
runtimeMetadata,
|
|
183
|
+
familyProfile: this.resolveFamilyProfile(runtimeMetadata)
|
|
458
184
|
});
|
|
459
|
-
return typeof profileResolved === 'boolean' ? profileResolved : false;
|
|
460
185
|
}
|
|
461
186
|
applyStreamModeHeaders(headers, wantsSse) {
|
|
462
|
-
const normalized = { ...headers };
|
|
463
|
-
const acceptKey = Object.keys(normalized).find((key) => key.toLowerCase() === 'accept');
|
|
464
|
-
// 上游 Accept 必须由我们“上游是否走 SSE”来决定;不能透传客户端的 SSE Accept。
|
|
465
|
-
// 否则会出现 “Accept: text/event-stream 但 body 无 stream 标记” 的组合(部分上游会返回 406)。
|
|
466
|
-
if (acceptKey) {
|
|
467
|
-
delete normalized[acceptKey];
|
|
468
|
-
}
|
|
469
|
-
normalized['Accept'] = wantsSse ? 'text/event-stream' : 'application/json';
|
|
470
187
|
const runtimeMetadata = this.getCurrentRuntimeMetadata();
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
headers: normalized,
|
|
188
|
+
return applyProviderStreamModeHeaders({
|
|
189
|
+
headers,
|
|
474
190
|
wantsSse,
|
|
475
|
-
runtimeMetadata
|
|
191
|
+
runtimeMetadata,
|
|
192
|
+
familyProfile: this.resolveFamilyProfile(runtimeMetadata)
|
|
476
193
|
});
|
|
477
|
-
if (profileHeaders && typeof profileHeaders === 'object') {
|
|
478
|
-
return profileHeaders;
|
|
479
|
-
}
|
|
480
|
-
return normalized;
|
|
481
194
|
}
|
|
482
195
|
prepareSseRequestBody(body, context) {
|
|
483
196
|
const runtimeMetadata = context?.runtimeMetadata ?? this.getCurrentRuntimeMetadata();
|
|
484
197
|
const familyProfile = this.resolveFamilyProfile(runtimeMetadata);
|
|
485
|
-
const effectiveContext = context ??
|
|
198
|
+
const effectiveContext = context ?? createProviderRuntimeContext({
|
|
199
|
+
runtime: this.getCurrentRuntimeMetadata(),
|
|
200
|
+
serviceProfile: this.serviceProfile,
|
|
201
|
+
providerType: this.providerType
|
|
202
|
+
});
|
|
486
203
|
familyProfile?.prepareStreamBody?.({
|
|
487
204
|
body,
|
|
488
205
|
context: effectiveContext,
|
|
@@ -502,332 +219,97 @@ export class HttpTransportProvider extends BaseProvider {
|
|
|
502
219
|
return false;
|
|
503
220
|
}
|
|
504
221
|
}
|
|
505
|
-
getHttpRetryLimit() {
|
|
506
|
-
// Provider 层禁止重复尝试;失败后由虚拟路由负责 failover。
|
|
507
|
-
return 1;
|
|
508
|
-
}
|
|
509
|
-
async delayBeforeHttpRetry(attempt) {
|
|
510
|
-
const delay = Math.min(500 * attempt, 2000);
|
|
511
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
512
|
-
}
|
|
513
|
-
shouldRetryHttpError(error, attempt, maxAttempts) {
|
|
514
|
-
if (attempt >= maxAttempts) {
|
|
515
|
-
return false;
|
|
516
|
-
}
|
|
517
|
-
const normalized = error;
|
|
518
|
-
const statusCode = extractStatusCodeFromError(normalized);
|
|
519
|
-
if (statusCode && statusCode >= 500) {
|
|
520
|
-
return true;
|
|
521
|
-
}
|
|
522
|
-
return false;
|
|
523
|
-
}
|
|
524
|
-
async tryRecoverOAuthAndReplay(error, requestInfo, processedRequest, captureSse, context) {
|
|
525
|
-
try {
|
|
526
|
-
const providerAuth = this.config.config.auth;
|
|
527
|
-
const authRawType = typeof providerAuth.rawType === 'string'
|
|
528
|
-
? String(providerAuth.rawType).trim().toLowerCase()
|
|
529
|
-
: '';
|
|
530
|
-
const isDeepSeekAccount = authRawType === 'deepseek-account';
|
|
531
|
-
if (isDeepSeekAccount) {
|
|
532
|
-
const statusCode = extractStatusCodeFromError(error);
|
|
533
|
-
const authProvider = this.authProvider;
|
|
534
|
-
if (statusCode === 401 && authProvider?.refreshCredentials) {
|
|
535
|
-
await authProvider.refreshCredentials();
|
|
536
|
-
const retryHeaders = await this.buildRequestHeaders();
|
|
537
|
-
let finalRetryHeaders = await this.finalizeRequestHeaders(retryHeaders, processedRequest);
|
|
538
|
-
finalRetryHeaders = this.applyStreamModeHeaders(finalRetryHeaders, requestInfo.wantsSse);
|
|
539
|
-
if (requestInfo.wantsSse) {
|
|
540
|
-
const upstreamStream = await this.httpClient.postStream(requestInfo.targetUrl, requestInfo.body, finalRetryHeaders);
|
|
541
|
-
const streamForHost = captureSse
|
|
542
|
-
? attachProviderSseSnapshotStream(upstreamStream, {
|
|
543
|
-
requestId: context.requestId,
|
|
544
|
-
headers: finalRetryHeaders,
|
|
545
|
-
url: requestInfo.targetUrl,
|
|
546
|
-
entryEndpoint: requestInfo.entryEndpoint,
|
|
547
|
-
clientRequestId: requestInfo.clientRequestId,
|
|
548
|
-
providerKey: context.providerKey,
|
|
549
|
-
providerId: context.providerId,
|
|
550
|
-
extra: { retry: true, authRefresh: true }
|
|
551
|
-
})
|
|
552
|
-
: upstreamStream;
|
|
553
|
-
return await this.wrapUpstreamSseResponse(streamForHost, context);
|
|
554
|
-
}
|
|
555
|
-
const response = await this.httpClient.post(requestInfo.targetUrl, requestInfo.body, finalRetryHeaders);
|
|
556
|
-
return response;
|
|
557
|
-
}
|
|
558
|
-
return undefined;
|
|
559
|
-
}
|
|
560
|
-
if (this.normalizeAuthMode(providerAuth.type) !== 'oauth') {
|
|
561
|
-
return undefined;
|
|
562
|
-
}
|
|
563
|
-
const shouldRetry = await handleUpstreamInvalidOAuthToken(this.oauthProviderId || this.providerType, providerAuth, error,
|
|
564
|
-
// Never block server requests waiting for interactive OAuth.
|
|
565
|
-
// The repair flow (if needed) will run in background and Virtual Router should failover immediately.
|
|
566
|
-
{ allowBlocking: false });
|
|
567
|
-
if (!shouldRetry) {
|
|
568
|
-
return undefined;
|
|
569
|
-
}
|
|
570
|
-
const retryHeaders = await this.buildRequestHeaders();
|
|
571
|
-
let finalRetryHeaders = await this.finalizeRequestHeaders(retryHeaders, processedRequest);
|
|
572
|
-
finalRetryHeaders = this.applyStreamModeHeaders(finalRetryHeaders, requestInfo.wantsSse);
|
|
573
|
-
if (requestInfo.wantsSse) {
|
|
574
|
-
const upstreamStream = await this.httpClient.postStream(requestInfo.targetUrl, requestInfo.body, finalRetryHeaders);
|
|
575
|
-
const streamForHost = captureSse
|
|
576
|
-
? attachProviderSseSnapshotStream(upstreamStream, {
|
|
577
|
-
requestId: context.requestId,
|
|
578
|
-
headers: finalRetryHeaders,
|
|
579
|
-
url: requestInfo.targetUrl,
|
|
580
|
-
entryEndpoint: requestInfo.entryEndpoint,
|
|
581
|
-
clientRequestId: requestInfo.clientRequestId,
|
|
582
|
-
providerKey: context.providerKey,
|
|
583
|
-
providerId: context.providerId,
|
|
584
|
-
extra: { retry: true }
|
|
585
|
-
})
|
|
586
|
-
: upstreamStream;
|
|
587
|
-
const wrapped = await this.wrapUpstreamSseResponse(streamForHost, context);
|
|
588
|
-
if (!captureSse) {
|
|
589
|
-
try {
|
|
590
|
-
await writeProviderSnapshot({
|
|
591
|
-
phase: 'provider-response',
|
|
592
|
-
requestId: context.requestId,
|
|
593
|
-
data: { mode: 'sse', retry: true },
|
|
594
|
-
headers: finalRetryHeaders,
|
|
595
|
-
url: requestInfo.targetUrl,
|
|
596
|
-
entryEndpoint: requestInfo.entryEndpoint,
|
|
597
|
-
clientRequestId: requestInfo.clientRequestId,
|
|
598
|
-
providerKey: context.providerKey,
|
|
599
|
-
providerId: context.providerId
|
|
600
|
-
});
|
|
601
|
-
}
|
|
602
|
-
catch { /* non-blocking */ }
|
|
603
|
-
}
|
|
604
|
-
return wrapped;
|
|
605
|
-
}
|
|
606
|
-
const response = await this.httpClient.post(requestInfo.targetUrl, requestInfo.body, finalRetryHeaders);
|
|
607
|
-
try {
|
|
608
|
-
await writeProviderSnapshot({
|
|
609
|
-
phase: 'provider-response',
|
|
610
|
-
requestId: context.requestId,
|
|
611
|
-
data: response,
|
|
612
|
-
headers: finalRetryHeaders,
|
|
613
|
-
url: requestInfo.targetUrl,
|
|
614
|
-
entryEndpoint: requestInfo.entryEndpoint,
|
|
615
|
-
clientRequestId: requestInfo.clientRequestId,
|
|
616
|
-
providerKey: context.providerKey,
|
|
617
|
-
providerId: context.providerId
|
|
618
|
-
});
|
|
619
|
-
}
|
|
620
|
-
catch { /* non-blocking */ }
|
|
621
|
-
return response;
|
|
622
|
-
}
|
|
623
|
-
catch {
|
|
624
|
-
return undefined;
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
222
|
async normalizeHttpError(error, processedRequest, requestInfo, context) {
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
normalized.status = statusCode;
|
|
635
|
-
}
|
|
636
|
-
if (!normalized.code) {
|
|
637
|
-
normalized.code = `HTTP_${statusCode}`;
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
if (!normalized.response) {
|
|
641
|
-
normalized.response = {};
|
|
642
|
-
}
|
|
643
|
-
if (!normalized.response.data) {
|
|
644
|
-
normalized.response.data = {};
|
|
645
|
-
}
|
|
646
|
-
if (!normalized.response.data.error) {
|
|
647
|
-
normalized.response.data.error = {};
|
|
648
|
-
}
|
|
649
|
-
if (normalized.code && !normalized.response.data.error.code) {
|
|
650
|
-
normalized.response.data.error.code = normalized.code;
|
|
651
|
-
}
|
|
652
|
-
if (normalized.message && !normalized.response.data.error.message) {
|
|
653
|
-
normalized.response.data.error.message = normalized.message;
|
|
654
|
-
}
|
|
655
|
-
}
|
|
656
|
-
catch {
|
|
657
|
-
/* ignore */
|
|
658
|
-
}
|
|
659
|
-
try {
|
|
660
|
-
await writeProviderSnapshot({
|
|
661
|
-
phase: 'provider-error',
|
|
662
|
-
requestId: context.requestId,
|
|
663
|
-
data: {
|
|
664
|
-
status: normalized?.statusCode ?? normalized?.status ?? null,
|
|
665
|
-
code: normalized?.code ?? null,
|
|
666
|
-
error: typeof normalized?.message === 'string' ? normalized.message : String(error || '')
|
|
667
|
-
},
|
|
668
|
-
headers: requestInfo.headers,
|
|
669
|
-
url: requestInfo.targetUrl,
|
|
670
|
-
entryEndpoint: requestInfo.entryEndpoint ?? this.getEntryEndpointFromPayload(processedRequest),
|
|
671
|
-
clientRequestId: requestInfo.clientRequestId ?? this.getClientRequestIdFromContext(context),
|
|
672
|
-
providerKey: context.providerKey,
|
|
673
|
-
providerId: context.providerId
|
|
674
|
-
});
|
|
675
|
-
}
|
|
676
|
-
catch { /* non-blocking */ }
|
|
677
|
-
return normalized;
|
|
223
|
+
return normalizeProviderHttpError({
|
|
224
|
+
error,
|
|
225
|
+
processedRequest,
|
|
226
|
+
requestInfo,
|
|
227
|
+
context
|
|
228
|
+
});
|
|
678
229
|
}
|
|
679
230
|
resolveProfileBusinessResponseError(response, context) {
|
|
680
231
|
const runtimeMetadata = context.runtimeMetadata ?? this.getCurrentRuntimeMetadata();
|
|
681
|
-
|
|
682
|
-
if (!familyProfile?.resolveBusinessResponseError) {
|
|
683
|
-
return undefined;
|
|
684
|
-
}
|
|
685
|
-
return familyProfile.resolveBusinessResponseError({
|
|
232
|
+
return resolveProviderBusinessResponseError({
|
|
686
233
|
response,
|
|
687
|
-
runtimeMetadata
|
|
234
|
+
runtimeMetadata,
|
|
235
|
+
familyProfile: this.resolveFamilyProfile(runtimeMetadata)
|
|
688
236
|
});
|
|
689
237
|
}
|
|
690
238
|
/**
|
|
691
239
|
* 为特定请求确定最终 endpoint(默认使用配置值,可由子类覆写)
|
|
692
240
|
*/
|
|
693
241
|
resolveRequestEndpoint(request, defaultEndpoint) {
|
|
694
|
-
const protocolResolvedEndpoint = this.protocolClient.resolveEndpoint(request, defaultEndpoint);
|
|
695
242
|
const runtimeMetadata = this.getCurrentRuntimeMetadata();
|
|
696
|
-
|
|
697
|
-
const profileResolvedEndpoint = familyProfile?.resolveEndpoint?.({
|
|
243
|
+
return resolveProviderRequestEndpoint({
|
|
698
244
|
request,
|
|
699
|
-
defaultEndpoint
|
|
700
|
-
|
|
245
|
+
defaultEndpoint,
|
|
246
|
+
protocolClient: this.protocolClient,
|
|
247
|
+
runtimeMetadata,
|
|
248
|
+
familyProfile: this.resolveFamilyProfile(runtimeMetadata),
|
|
249
|
+
legacyEndpoint: this.resolveLegacyIflowEndpoint(request)
|
|
701
250
|
});
|
|
702
|
-
if (typeof profileResolvedEndpoint === 'string' && profileResolvedEndpoint.trim()) {
|
|
703
|
-
return profileResolvedEndpoint.trim();
|
|
704
|
-
}
|
|
705
|
-
const legacyEndpoint = this.resolveLegacyIflowEndpoint(request);
|
|
706
|
-
if (legacyEndpoint) {
|
|
707
|
-
return legacyEndpoint;
|
|
708
|
-
}
|
|
709
|
-
return protocolResolvedEndpoint;
|
|
710
251
|
}
|
|
711
252
|
/**
|
|
712
253
|
* 构造最终发送到上游的请求体,默认实现包含模型/令牌治理,可由子类覆写
|
|
713
254
|
*/
|
|
714
255
|
buildHttpRequestBody(request) {
|
|
715
256
|
const runtimeMetadata = this.getCurrentRuntimeMetadata();
|
|
716
|
-
|
|
717
|
-
const defaultBody = this.protocolClient.buildRequestBody(request);
|
|
718
|
-
const profileBody = familyProfile?.buildRequestBody?.({
|
|
257
|
+
return buildProviderHttpRequestBody({
|
|
719
258
|
request,
|
|
720
|
-
|
|
721
|
-
runtimeMetadata
|
|
259
|
+
protocolClient: this.protocolClient,
|
|
260
|
+
runtimeMetadata,
|
|
261
|
+
familyProfile: this.resolveFamilyProfile(runtimeMetadata),
|
|
262
|
+
legacyBody: this.resolveLegacyIflowRequestBody(request)
|
|
722
263
|
});
|
|
723
|
-
if (profileBody && typeof profileBody === 'object') {
|
|
724
|
-
return profileBody;
|
|
725
|
-
}
|
|
726
|
-
const legacyBody = this.resolveLegacyIflowRequestBody(request);
|
|
727
|
-
if (legacyBody && typeof legacyBody === 'object') {
|
|
728
|
-
return legacyBody;
|
|
729
|
-
}
|
|
730
|
-
return defaultBody;
|
|
731
264
|
}
|
|
732
265
|
resolveFamilyProfile(runtimeMetadata) {
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
:
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
const normalized = value.trim().toLowerCase();
|
|
741
|
-
return normalized.length ? normalized : undefined;
|
|
742
|
-
};
|
|
743
|
-
return getProviderFamilyProfile({
|
|
744
|
-
providerFamily: normalize(runtimeMetadata?.providerFamily) ??
|
|
745
|
-
normalize(this.getRuntimeProfile()?.providerFamily),
|
|
746
|
-
providerId: normalize(runtimeMetadata?.providerId) ??
|
|
747
|
-
normalize(targetNode?.providerId) ??
|
|
748
|
-
normalize(this.config?.config?.providerId),
|
|
749
|
-
providerKey: normalize(runtimeMetadata?.providerKey) ??
|
|
750
|
-
normalize(targetNode?.providerKey) ??
|
|
751
|
-
normalize(this.getRuntimeProfile()?.providerKey),
|
|
752
|
-
providerType: normalize(runtimeMetadata?.providerType) ??
|
|
753
|
-
normalize(targetNode?.providerType) ??
|
|
754
|
-
normalize(this.config?.config?.providerType) ??
|
|
755
|
-
normalize(this.providerType),
|
|
756
|
-
oauthProviderId: normalize(this.oauthProviderId)
|
|
266
|
+
return resolveProviderFamilyProfile({
|
|
267
|
+
runtimeMetadata,
|
|
268
|
+
runtimeProfile: this.getRuntimeProfile(),
|
|
269
|
+
configProviderId: this.config?.config?.providerId,
|
|
270
|
+
configProviderType: this.config?.config?.providerType,
|
|
271
|
+
providerType: this.providerType,
|
|
272
|
+
oauthProviderId: this.oauthProviderId
|
|
757
273
|
});
|
|
758
274
|
}
|
|
759
|
-
isIflowWebSearchRequest(request) {
|
|
760
|
-
const metadata = request.metadata;
|
|
761
|
-
if (!metadata || typeof metadata !== 'object') {
|
|
762
|
-
return false;
|
|
763
|
-
}
|
|
764
|
-
const flag = metadata.iflowWebSearch;
|
|
765
|
-
return flag === true;
|
|
766
|
-
}
|
|
767
275
|
resolveLegacyIflowEndpoint(request) {
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
return undefined;
|
|
773
|
-
}
|
|
774
|
-
const metadata = request.metadata;
|
|
775
|
-
const endpoint = metadata && typeof metadata.entryEndpoint === 'string'
|
|
776
|
-
? (metadata.entryEndpoint || '').trim()
|
|
777
|
-
: '';
|
|
778
|
-
return endpoint || '/chat/retrieve';
|
|
276
|
+
return resolveLegacyIflowEndpointFromRequest({
|
|
277
|
+
request,
|
|
278
|
+
isIflowRuntime: this.isIflowTransportRuntime(this.getCurrentRuntimeMetadata())
|
|
279
|
+
});
|
|
779
280
|
}
|
|
780
281
|
resolveLegacyIflowRequestBody(request) {
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
return undefined;
|
|
786
|
-
}
|
|
787
|
-
const data = request.data;
|
|
788
|
-
if (data && typeof data === 'object') {
|
|
789
|
-
return data;
|
|
790
|
-
}
|
|
791
|
-
return {};
|
|
282
|
+
return resolveLegacyIflowRequestBodyFromRequest({
|
|
283
|
+
request,
|
|
284
|
+
isIflowRuntime: this.isIflowTransportRuntime(this.getCurrentRuntimeMetadata())
|
|
285
|
+
});
|
|
792
286
|
}
|
|
793
287
|
/**
|
|
794
288
|
* 允许子类在 Hook 运行完后对头部做最终调整
|
|
795
289
|
*/
|
|
796
290
|
async finalizeRequestHeaders(headers, request) {
|
|
797
|
-
const finalized = await this.protocolClient.finalizeHeaders(headers, request);
|
|
798
291
|
const runtimeMetadata = this.getCurrentRuntimeMetadata();
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
uaFromConfig: this.findHeaderValue(finalized, 'User-Agent'),
|
|
802
|
-
uaFromService: undefined,
|
|
803
|
-
inboundUserAgent: undefined,
|
|
804
|
-
defaultUserAgent: DEFAULT_USER_AGENT,
|
|
805
|
-
runtimeMetadata
|
|
806
|
-
});
|
|
807
|
-
if (typeof profileResolvedUa === 'string' && profileResolvedUa.trim()) {
|
|
808
|
-
this.assignHeader(finalized, 'User-Agent', profileResolvedUa.trim());
|
|
809
|
-
}
|
|
810
|
-
const profileAdjustedHeaders = familyProfile?.applyRequestHeaders?.({
|
|
811
|
-
headers: finalized,
|
|
292
|
+
return finalizeProviderRequestHeaders({
|
|
293
|
+
headers,
|
|
812
294
|
request,
|
|
295
|
+
finalizeHeaders: (baseHeaders, req) => this.protocolClient.finalizeHeaders(baseHeaders, req),
|
|
813
296
|
runtimeMetadata,
|
|
814
|
-
|
|
297
|
+
familyProfile: this.resolveFamilyProfile(runtimeMetadata),
|
|
298
|
+
providerType: this.providerType,
|
|
299
|
+
isIflow: this.isIflowTransportRuntime(runtimeMetadata)
|
|
815
300
|
});
|
|
816
|
-
if (profileAdjustedHeaders && typeof profileAdjustedHeaders === 'object') {
|
|
817
|
-
return profileAdjustedHeaders;
|
|
818
|
-
}
|
|
819
|
-
if (this.isIflowTransportRuntime(runtimeMetadata)) {
|
|
820
|
-
this.enforceIflowCliHeaders(finalized);
|
|
821
|
-
}
|
|
822
|
-
return finalized;
|
|
823
301
|
}
|
|
824
302
|
// 私有方法
|
|
825
303
|
validateConfig() {
|
|
826
304
|
const profile = this.serviceProfile;
|
|
827
305
|
const cfg = this.config.config;
|
|
828
|
-
const profileKey =
|
|
306
|
+
const profileKey = resolveProviderProfileKey({
|
|
307
|
+
moduleType: this.type,
|
|
308
|
+
providerType: this.providerType,
|
|
309
|
+
providerId: typeof cfg.providerId === 'string' ? cfg.providerId : undefined
|
|
310
|
+
});
|
|
829
311
|
const auth = this.config.config.auth;
|
|
830
|
-
const authMode =
|
|
312
|
+
const authMode = AuthModeUtils.normalizeAuthMode(auth.type);
|
|
831
313
|
// 验证认证类型
|
|
832
314
|
const supportedAuthTypes = [...profile.requiredAuth, ...profile.optionalAuth];
|
|
833
315
|
if (!supportedAuthTypes.includes(authMode)) {
|
|
@@ -835,670 +317,73 @@ export class HttpTransportProvider extends BaseProvider {
|
|
|
835
317
|
`Supported types: ${supportedAuthTypes.join(', ')}`);
|
|
836
318
|
}
|
|
837
319
|
}
|
|
838
|
-
buildRequestUrl() {
|
|
839
|
-
const baseUrl = this.getEffectiveBaseUrl();
|
|
840
|
-
const endpoint = this.getEffectiveEndpoint();
|
|
841
|
-
return `${baseUrl}${endpoint}`;
|
|
842
|
-
}
|
|
843
320
|
async buildRequestHeaders() {
|
|
844
|
-
const baseHeaders = {
|
|
845
|
-
'Content-Type': 'application/json'
|
|
846
|
-
};
|
|
847
321
|
const runtimeMetadata = this.getCurrentRuntimeMetadata();
|
|
848
|
-
const inboundMetadata = runtimeMetadata?.metadata;
|
|
849
|
-
const inboundUserAgent = typeof inboundMetadata?.userAgent === 'string' && inboundMetadata.userAgent.trim()
|
|
850
|
-
? inboundMetadata.userAgent.trim()
|
|
851
|
-
: undefined;
|
|
852
|
-
const inboundOriginator = typeof inboundMetadata?.clientOriginator === 'string' && inboundMetadata.clientOriginator.trim()
|
|
853
|
-
? inboundMetadata.clientOriginator.trim()
|
|
854
|
-
: undefined;
|
|
855
|
-
const inboundClientHeaders = this.extractClientHeaders(runtimeMetadata);
|
|
856
|
-
const normalizedClientHeaders = this.normalizeCodexClientHeaders(inboundClientHeaders);
|
|
857
322
|
const isAntigravity = this.isAntigravityTransportRuntime(runtimeMetadata);
|
|
858
|
-
// 服务特定头部
|
|
859
|
-
const serviceHeaders = this.serviceProfile.headers || {};
|
|
860
|
-
// 配置覆盖头部
|
|
861
|
-
const overrideHeaders = this.config.config.overrides?.headers || {};
|
|
862
323
|
const runtimeHeaders = this.getRuntimeProfile()?.headers || {};
|
|
863
|
-
|
|
864
|
-
if (this.isGeminiFamilyTransport() && !isAntigravity) {
|
|
865
|
-
// Google 客户端标识
|
|
866
|
-
this.assignHeader(baseHeaders, 'X-Goog-Api-Client', 'gl-node/22.17.0');
|
|
867
|
-
// 客户端元数据
|
|
868
|
-
const clientMetadata = this.buildClientMetadata(runtimeMetadata);
|
|
869
|
-
if (clientMetadata) {
|
|
870
|
-
this.assignHeader(baseHeaders, 'Client-Metadata', clientMetadata);
|
|
871
|
-
}
|
|
872
|
-
// Accept 编码
|
|
873
|
-
this.assignHeader(baseHeaders, 'Accept-Encoding', 'gzip, deflate, br');
|
|
874
|
-
// Accept 类型(用于流式响应)
|
|
875
|
-
const isStreaming = runtimeMetadata?.streaming === true;
|
|
876
|
-
this.assignHeader(baseHeaders, 'Accept', isStreaming ? 'text/event-stream' : 'application/json');
|
|
877
|
-
}
|
|
878
|
-
// OAuth:请求前确保令牌有效(提前刷新)
|
|
879
|
-
try {
|
|
880
|
-
const auth = this.config.config.auth;
|
|
881
|
-
if (this.normalizeAuthMode(auth.type) === 'oauth') {
|
|
882
|
-
const oauthAuth = auth;
|
|
883
|
-
const oauthProviderId = this.oauthProviderId || this.ensureOAuthProviderId(oauthAuth);
|
|
884
|
-
logOAuthDebug('[OAuth] [headers] ensureValid start (silent refresh only)');
|
|
885
|
-
try {
|
|
886
|
-
// 请求前仅尝试静默刷新,不主动打开浏览器;
|
|
887
|
-
// 真正令牌失效由 handleUpstreamInvalidOAuthToken 触发交互式修复。
|
|
888
|
-
await ensureValidOAuthToken(oauthProviderId, oauthAuth, {
|
|
889
|
-
forceReacquireIfRefreshFails: false,
|
|
890
|
-
openBrowser: false,
|
|
891
|
-
forceReauthorize: false
|
|
892
|
-
});
|
|
893
|
-
logOAuthDebug('[OAuth] [headers] ensureValid OK');
|
|
894
|
-
}
|
|
895
|
-
catch (error) {
|
|
896
|
-
const err = error;
|
|
897
|
-
const msg = err?.message ? String(err.message) : String(error);
|
|
898
|
-
const authErr = (error instanceof Error ? error : new Error(msg));
|
|
899
|
-
const needsInteractiveRepair = shouldTriggerInteractiveOAuthRepair(oauthProviderId, authErr);
|
|
900
|
-
if (needsInteractiveRepair) {
|
|
901
|
-
if (typeof authErr.statusCode !== 'number' && typeof authErr.status !== 'number') {
|
|
902
|
-
authErr.statusCode = 401;
|
|
903
|
-
authErr.status = 401;
|
|
904
|
-
}
|
|
905
|
-
if (typeof authErr.code !== 'string' || !authErr.code.trim()) {
|
|
906
|
-
authErr.code = 'AUTH_INVALID_TOKEN';
|
|
907
|
-
}
|
|
908
|
-
// 非阻塞:后台触发修复,不等待本请求。
|
|
909
|
-
void handleUpstreamInvalidOAuthToken(oauthProviderId, oauthAuth, authErr, {
|
|
910
|
-
allowBlocking: false
|
|
911
|
-
}).catch(() => {
|
|
912
|
-
// ignore background repair errors
|
|
913
|
-
});
|
|
914
|
-
authErr.__routecodexAuthPreflightFatal = true;
|
|
915
|
-
throw authErr;
|
|
916
|
-
}
|
|
917
|
-
// 非认证类的 ensureValid 错误只做日志,避免影响正常流量。
|
|
918
|
-
logOAuthDebug(`[OAuth] [headers] ensureValid skipped: ${msg}`);
|
|
919
|
-
}
|
|
920
|
-
try {
|
|
921
|
-
this.authProvider.getOAuthClient?.()?.loadToken?.();
|
|
922
|
-
}
|
|
923
|
-
catch {
|
|
924
|
-
// ignore
|
|
925
|
-
}
|
|
926
|
-
}
|
|
927
|
-
}
|
|
928
|
-
catch (error) {
|
|
929
|
-
if (error &&
|
|
930
|
-
typeof error === 'object' &&
|
|
931
|
-
error.__routecodexAuthPreflightFatal === true) {
|
|
932
|
-
throw error;
|
|
933
|
-
}
|
|
934
|
-
// bubble up in authHeaders build below
|
|
935
|
-
}
|
|
936
|
-
// 认证头部(如为 OAuth,若当前无有效 token 则尝试拉取/刷新一次再取 headers)
|
|
937
|
-
const providerAuth = this.config.config.auth;
|
|
938
|
-
const authRawType = typeof providerAuth.rawType === 'string'
|
|
939
|
-
? String(providerAuth.rawType).trim().toLowerCase()
|
|
940
|
-
: '';
|
|
941
|
-
if (authRawType === 'deepseek-account' && this.authProvider?.validateCredentials) {
|
|
942
|
-
await this.authProvider.validateCredentials();
|
|
943
|
-
}
|
|
944
|
-
let authHeaders = {};
|
|
945
|
-
authHeaders = this.authProvider?.buildHeaders() || {};
|
|
946
|
-
const finalHeaders = {
|
|
947
|
-
...baseHeaders,
|
|
948
|
-
...serviceHeaders,
|
|
949
|
-
...overrideHeaders,
|
|
950
|
-
...runtimeHeaders,
|
|
951
|
-
...authHeaders
|
|
952
|
-
};
|
|
953
|
-
// 保留客户端 Accept;无则默认为 application/json
|
|
954
|
-
const clientAccept = normalizedClientHeaders ? this.findHeaderValue(normalizedClientHeaders, 'Accept') : undefined;
|
|
955
|
-
if (clientAccept) {
|
|
956
|
-
this.assignHeader(finalHeaders, 'Accept', clientAccept);
|
|
957
|
-
}
|
|
958
|
-
else if (!this.findHeaderValue(finalHeaders, 'Accept')) {
|
|
959
|
-
this.assignHeader(finalHeaders, 'Accept', 'application/json');
|
|
960
|
-
}
|
|
961
|
-
// Header priority:
|
|
962
|
-
// - user/provider config (overrides/runtime) wins
|
|
963
|
-
// - otherwise inherit from inbound client headers
|
|
964
|
-
// - otherwise fall back to defaults
|
|
965
|
-
const uaFromConfig = this.findHeaderValue({ ...overrideHeaders, ...runtimeHeaders }, 'User-Agent');
|
|
966
|
-
const uaFromService = this.findHeaderValue(serviceHeaders, 'User-Agent');
|
|
967
|
-
// iFlow 特例:部分模型(例如 glm-4.7)对 UA 有强约束,必须模拟 iFlow CLI。
|
|
968
|
-
// 因此对 iflow:service/profile 的 UA 优先级应高于 inbound client userAgent,
|
|
969
|
-
// 否则客户端 UA 会把模拟头部冲掉,触发 HTTP 200 + status=435 "Model not support"。
|
|
324
|
+
const isGeminiFamily = this.isGeminiFamilyTransport();
|
|
970
325
|
const isIflow = this.isIflowTransportRuntime(runtimeMetadata);
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
326
|
+
return buildProviderRequestHeaders({
|
|
327
|
+
config: this.config.config,
|
|
328
|
+
authProvider: this.authProvider,
|
|
329
|
+
oauthProviderId: this.oauthProviderId,
|
|
330
|
+
serviceProfile: this.serviceProfile,
|
|
331
|
+
runtimeMetadata,
|
|
332
|
+
runtimeHeaders,
|
|
333
|
+
familyProfile: this.resolveFamilyProfile(runtimeMetadata),
|
|
334
|
+
isGeminiFamily,
|
|
335
|
+
isAntigravity,
|
|
336
|
+
isIflow,
|
|
337
|
+
providerType: this.providerType
|
|
978
338
|
});
|
|
979
|
-
const resolvedUa = profileResolvedUa ?? (isIflow
|
|
980
|
-
? (uaFromConfig ?? uaFromService ?? inboundUserAgent ?? DEFAULT_USER_AGENT)
|
|
981
|
-
: (uaFromConfig ?? inboundUserAgent ?? uaFromService ?? DEFAULT_USER_AGENT));
|
|
982
|
-
this.assignHeader(finalHeaders, 'User-Agent', resolvedUa);
|
|
983
|
-
// originator: do not invent one; only forward from config or inbound client.
|
|
984
|
-
// gcli2api alignment: Gemini-family upstreams do not expect/need originator; avoid leaking client identifiers.
|
|
985
|
-
if (!this.isGeminiFamilyTransport()) {
|
|
986
|
-
const originatorFromConfig = this.findHeaderValue({ ...overrideHeaders, ...runtimeHeaders }, 'originator');
|
|
987
|
-
const originatorFromService = this.findHeaderValue(serviceHeaders, 'originator');
|
|
988
|
-
const resolvedOriginator = originatorFromConfig ?? inboundOriginator ?? originatorFromService;
|
|
989
|
-
if (resolvedOriginator) {
|
|
990
|
-
this.assignHeader(finalHeaders, 'originator', resolvedOriginator);
|
|
991
|
-
}
|
|
992
|
-
}
|
|
993
|
-
if (!isAntigravity && normalizedClientHeaders) {
|
|
994
|
-
const conversationId = this.findHeaderValue(normalizedClientHeaders, 'conversation_id');
|
|
995
|
-
if (conversationId) {
|
|
996
|
-
this.assignHeader(finalHeaders, 'conversation_id', conversationId);
|
|
997
|
-
}
|
|
998
|
-
const sessionId = this.findHeaderValue(normalizedClientHeaders, 'session_id');
|
|
999
|
-
if (sessionId) {
|
|
1000
|
-
this.assignHeader(finalHeaders, 'session_id', sessionId);
|
|
1001
|
-
}
|
|
1002
|
-
}
|
|
1003
|
-
// Inbound metadata may already carry parsed session identifiers (e.g. when client sends
|
|
1004
|
-
// metadata.sessionId / metadata.conversationId instead of headers). Inject them only
|
|
1005
|
-
// if not already provided by config/runtime headers or inbound client headers.
|
|
1006
|
-
if (!isAntigravity && inboundMetadata && typeof inboundMetadata === 'object') {
|
|
1007
|
-
const meta = inboundMetadata;
|
|
1008
|
-
const metaSessionId = typeof meta.sessionId === 'string' && meta.sessionId.trim() ? meta.sessionId.trim() : '';
|
|
1009
|
-
const metaConversationId = typeof meta.conversationId === 'string' && meta.conversationId.trim() ? meta.conversationId.trim() : '';
|
|
1010
|
-
const resolvedSessionId = metaSessionId || metaConversationId;
|
|
1011
|
-
const resolvedConversationId = metaConversationId || metaSessionId;
|
|
1012
|
-
if (resolvedSessionId && !this.findHeaderValue(finalHeaders, 'session_id')) {
|
|
1013
|
-
this.assignHeader(finalHeaders, 'session_id', resolvedSessionId);
|
|
1014
|
-
}
|
|
1015
|
-
if (resolvedConversationId && !this.findHeaderValue(finalHeaders, 'conversation_id')) {
|
|
1016
|
-
this.assignHeader(finalHeaders, 'conversation_id', resolvedConversationId);
|
|
1017
|
-
}
|
|
1018
|
-
}
|
|
1019
|
-
const codexUaMode = this.isCodexUaMode();
|
|
1020
|
-
if (!isAntigravity && codexUaMode) {
|
|
1021
|
-
this.ensureCodexSessionHeaders(finalHeaders, runtimeMetadata);
|
|
1022
|
-
}
|
|
1023
|
-
if (isAntigravity) {
|
|
1024
|
-
this.deleteHeader(finalHeaders, 'session_id');
|
|
1025
|
-
this.deleteHeader(finalHeaders, 'conversation_id');
|
|
1026
|
-
}
|
|
1027
|
-
if (isIflow) {
|
|
1028
|
-
this.enforceIflowCliHeaders(finalHeaders);
|
|
1029
|
-
}
|
|
1030
|
-
return finalHeaders;
|
|
1031
|
-
}
|
|
1032
|
-
isCodexUaMode() {
|
|
1033
|
-
const raw = process.env.ROUTECODEX_UA_MODE ??
|
|
1034
|
-
process.env.RCC_UA_MODE ??
|
|
1035
|
-
'';
|
|
1036
|
-
const normalized = typeof raw === 'string' ? raw.trim().toLowerCase() : '';
|
|
1037
|
-
const runtime = this.getCurrentRuntimeMetadata();
|
|
1038
|
-
if (!runtime) {
|
|
1039
|
-
return false;
|
|
1040
|
-
}
|
|
1041
|
-
const providerType = runtime.providerType || this.providerType;
|
|
1042
|
-
const entryEndpoint = this.getEntryEndpointFromRuntime(runtime);
|
|
1043
|
-
// 显式 UA 模式(--codex / --ua codex):对所有 provider 激活
|
|
1044
|
-
if (normalized === 'codex') {
|
|
1045
|
-
return true;
|
|
1046
|
-
}
|
|
1047
|
-
// 隐式模式:未显式设置 UA 时,仅在 responses provider 且入口不是 /v1/responses 时激活
|
|
1048
|
-
if (providerType === 'responses' && entryEndpoint) {
|
|
1049
|
-
const lowered = entryEndpoint.trim().toLowerCase();
|
|
1050
|
-
if (!lowered.includes('/responses')) {
|
|
1051
|
-
return true;
|
|
1052
|
-
}
|
|
1053
|
-
}
|
|
1054
|
-
return false;
|
|
1055
|
-
}
|
|
1056
|
-
normalizeCodexClientHeaders(headers) {
|
|
1057
|
-
if (!headers) {
|
|
1058
|
-
return undefined;
|
|
1059
|
-
}
|
|
1060
|
-
if (!this.isCodexUaMode()) {
|
|
1061
|
-
return headers;
|
|
1062
|
-
}
|
|
1063
|
-
const normalizedHeaders = { ...headers };
|
|
1064
|
-
this.copyHeaderValue(normalizedHeaders, headers, 'anthropic-session-id', 'session_id');
|
|
1065
|
-
this.copyHeaderValue(normalizedHeaders, headers, 'anthropic-conversation-id', 'conversation_id');
|
|
1066
|
-
this.copyHeaderValue(normalizedHeaders, headers, 'anthropic-user-agent', 'User-Agent');
|
|
1067
|
-
this.copyHeaderValue(normalizedHeaders, headers, 'anthropic-originator', 'originator');
|
|
1068
|
-
return normalizedHeaders;
|
|
1069
|
-
}
|
|
1070
|
-
copyHeaderValue(target, source, from, to) {
|
|
1071
|
-
if (this.findHeaderValue(target, to)) {
|
|
1072
|
-
return;
|
|
1073
|
-
}
|
|
1074
|
-
const value = this.findHeaderValue(source, from);
|
|
1075
|
-
if (value) {
|
|
1076
|
-
target[to] = value;
|
|
1077
|
-
}
|
|
1078
|
-
}
|
|
1079
|
-
findHeaderValue(headers, target) {
|
|
1080
|
-
const lowered = typeof target === 'string' ? target.toLowerCase() : '';
|
|
1081
|
-
if (!lowered) {
|
|
1082
|
-
return undefined;
|
|
1083
|
-
}
|
|
1084
|
-
const normalizedTarget = this.normalizeHeaderKey(lowered);
|
|
1085
|
-
for (const [key, value] of Object.entries(headers)) {
|
|
1086
|
-
if (typeof value !== 'string') {
|
|
1087
|
-
continue;
|
|
1088
|
-
}
|
|
1089
|
-
const trimmed = value.trim();
|
|
1090
|
-
if (!trimmed) {
|
|
1091
|
-
continue;
|
|
1092
|
-
}
|
|
1093
|
-
const loweredKey = key.toLowerCase();
|
|
1094
|
-
if (loweredKey === lowered) {
|
|
1095
|
-
return trimmed;
|
|
1096
|
-
}
|
|
1097
|
-
if (this.normalizeHeaderKey(loweredKey) === normalizedTarget) {
|
|
1098
|
-
return trimmed;
|
|
1099
|
-
}
|
|
1100
|
-
}
|
|
1101
|
-
return undefined;
|
|
1102
|
-
}
|
|
1103
|
-
normalizeHeaderKey(value) {
|
|
1104
|
-
if (!value) {
|
|
1105
|
-
return '';
|
|
1106
|
-
}
|
|
1107
|
-
return value.replace(/[\s_-]+/g, '');
|
|
1108
|
-
}
|
|
1109
|
-
assignHeader(headers, target, value) {
|
|
1110
|
-
if (!value || !value.trim()) {
|
|
1111
|
-
return;
|
|
1112
|
-
}
|
|
1113
|
-
const lowered = target.toLowerCase();
|
|
1114
|
-
for (const key of Object.keys(headers)) {
|
|
1115
|
-
if (key.toLowerCase() === lowered) {
|
|
1116
|
-
headers[key] = value;
|
|
1117
|
-
return;
|
|
1118
|
-
}
|
|
1119
|
-
}
|
|
1120
|
-
headers[target] = value;
|
|
1121
|
-
}
|
|
1122
|
-
deleteHeader(headers, target) {
|
|
1123
|
-
const lowered = typeof target === 'string' ? target.toLowerCase() : '';
|
|
1124
|
-
if (!lowered) {
|
|
1125
|
-
return;
|
|
1126
|
-
}
|
|
1127
|
-
const normalizedTarget = this.normalizeHeaderKey(lowered);
|
|
1128
|
-
for (const key of Object.keys(headers)) {
|
|
1129
|
-
const loweredKey = key.toLowerCase();
|
|
1130
|
-
if (loweredKey === lowered) {
|
|
1131
|
-
delete headers[key];
|
|
1132
|
-
continue;
|
|
1133
|
-
}
|
|
1134
|
-
if (this.normalizeHeaderKey(loweredKey) === normalizedTarget) {
|
|
1135
|
-
delete headers[key];
|
|
1136
|
-
}
|
|
1137
|
-
}
|
|
1138
|
-
}
|
|
1139
|
-
ensureCodexSessionHeaders(headers, runtimeMetadata) {
|
|
1140
|
-
this.setHeaderIfMissing(headers, 'session_id', this.buildCodexIdentifier('session', runtimeMetadata));
|
|
1141
|
-
this.setHeaderIfMissing(headers, 'conversation_id', this.buildCodexIdentifier('conversation', runtimeMetadata));
|
|
1142
|
-
}
|
|
1143
|
-
setHeaderIfMissing(headers, target, value) {
|
|
1144
|
-
if (this.findHeaderValue(headers, target)) {
|
|
1145
|
-
return;
|
|
1146
|
-
}
|
|
1147
|
-
this.assignHeader(headers, target, value);
|
|
1148
|
-
}
|
|
1149
|
-
enforceIflowCliHeaders(headers) {
|
|
1150
|
-
const resolvedSessionId = this.findHeaderValue(headers, 'session-id') ??
|
|
1151
|
-
this.findHeaderValue(headers, 'session_id') ??
|
|
1152
|
-
'';
|
|
1153
|
-
const resolvedConversationId = this.findHeaderValue(headers, 'conversation-id') ??
|
|
1154
|
-
this.findHeaderValue(headers, 'conversation_id') ??
|
|
1155
|
-
resolvedSessionId;
|
|
1156
|
-
if (resolvedSessionId) {
|
|
1157
|
-
this.assignHeader(headers, 'session-id', resolvedSessionId);
|
|
1158
|
-
}
|
|
1159
|
-
if (resolvedConversationId) {
|
|
1160
|
-
this.assignHeader(headers, 'conversation-id', resolvedConversationId);
|
|
1161
|
-
}
|
|
1162
|
-
const bearerApiKey = this.extractBearerApiKey(headers);
|
|
1163
|
-
if (!bearerApiKey) {
|
|
1164
|
-
return;
|
|
1165
|
-
}
|
|
1166
|
-
const userAgent = this.findHeaderValue(headers, 'User-Agent') ?? 'iFlow-Cli';
|
|
1167
|
-
const timestamp = Date.now().toString();
|
|
1168
|
-
const signature = this.buildIflowSignature(userAgent, resolvedSessionId, timestamp, bearerApiKey);
|
|
1169
|
-
if (!signature) {
|
|
1170
|
-
return;
|
|
1171
|
-
}
|
|
1172
|
-
this.assignHeader(headers, 'x-iflow-timestamp', timestamp);
|
|
1173
|
-
this.assignHeader(headers, 'x-iflow-signature', signature);
|
|
1174
|
-
}
|
|
1175
|
-
extractBearerApiKey(headers) {
|
|
1176
|
-
const authorization = this.findHeaderValue(headers, 'Authorization');
|
|
1177
|
-
if (!authorization) {
|
|
1178
|
-
return undefined;
|
|
1179
|
-
}
|
|
1180
|
-
const matched = authorization.match(/^Bearer\s+(.+)$/i);
|
|
1181
|
-
if (!matched || !matched[1]) {
|
|
1182
|
-
return undefined;
|
|
1183
|
-
}
|
|
1184
|
-
const apiKey = matched[1].trim();
|
|
1185
|
-
return apiKey || undefined;
|
|
1186
|
-
}
|
|
1187
|
-
buildIflowSignature(userAgent, sessionId, timestamp, apiKey) {
|
|
1188
|
-
if (!apiKey) {
|
|
1189
|
-
return undefined;
|
|
1190
|
-
}
|
|
1191
|
-
const payload = `${userAgent}:${sessionId}:${timestamp}`;
|
|
1192
|
-
try {
|
|
1193
|
-
return createHmac('sha256', apiKey).update(payload, 'utf8').digest('hex');
|
|
1194
|
-
}
|
|
1195
|
-
catch {
|
|
1196
|
-
return undefined;
|
|
1197
|
-
}
|
|
1198
|
-
}
|
|
1199
|
-
buildCodexIdentifier(kind, runtimeMetadata) {
|
|
1200
|
-
const fallbackId = runtimeMetadata?.metadata && typeof runtimeMetadata.metadata === 'object'
|
|
1201
|
-
? runtimeMetadata.metadata.clientRequestId
|
|
1202
|
-
: undefined;
|
|
1203
|
-
const requestId = runtimeMetadata?.requestId ?? fallbackId;
|
|
1204
|
-
const routeName = runtimeMetadata?.routeName;
|
|
1205
|
-
const suffix = (requestId ?? `req-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`)
|
|
1206
|
-
.toString()
|
|
1207
|
-
.replace(/[^A-Za-z0-9_-]/g, '_');
|
|
1208
|
-
const parts = ['codex_cli', kind, suffix];
|
|
1209
|
-
if (routeName) {
|
|
1210
|
-
parts.push(routeName.replace(/[^A-Za-z0-9_-]/g, '_'));
|
|
1211
|
-
}
|
|
1212
|
-
return this.enforceCodexIdentifierLength(parts.join('_'));
|
|
1213
339
|
}
|
|
1214
340
|
isAntigravityTransportRuntime(runtimeMetadata) {
|
|
1215
|
-
|
|
1216
|
-
? this.config.config.providerId.trim().toLowerCase()
|
|
1217
|
-
: '';
|
|
1218
|
-
const fromRuntime = typeof runtimeMetadata?.providerId === 'string' && runtimeMetadata.providerId.trim()
|
|
1219
|
-
? runtimeMetadata.providerId.trim().toLowerCase()
|
|
1220
|
-
: '';
|
|
1221
|
-
const fromProviderKey = typeof runtimeMetadata?.providerKey === 'string' && runtimeMetadata.providerKey.trim()
|
|
1222
|
-
? runtimeMetadata.providerKey.trim().toLowerCase()
|
|
1223
|
-
: '';
|
|
1224
|
-
const fromOAuth = typeof this.oauthProviderId === 'string' ? this.oauthProviderId.trim().toLowerCase() : '';
|
|
1225
|
-
if (fromConfig === 'antigravity' || fromRuntime === 'antigravity' || fromOAuth === 'antigravity') {
|
|
1226
|
-
return true;
|
|
1227
|
-
}
|
|
1228
|
-
if (fromProviderKey.startsWith('antigravity.')) {
|
|
1229
|
-
return true;
|
|
1230
|
-
}
|
|
1231
|
-
return false;
|
|
341
|
+
return this.getRuntimeDetector().isAntigravity(runtimeMetadata);
|
|
1232
342
|
}
|
|
1233
343
|
isIflowTransportRuntime(runtimeMetadata) {
|
|
1234
|
-
|
|
1235
|
-
? this.config.config.providerId.trim().toLowerCase()
|
|
1236
|
-
: '';
|
|
1237
|
-
const fromRuntime = typeof runtimeMetadata?.providerId === 'string' && runtimeMetadata.providerId.trim()
|
|
1238
|
-
? runtimeMetadata.providerId.trim().toLowerCase()
|
|
1239
|
-
: '';
|
|
1240
|
-
const fromProviderKey = typeof runtimeMetadata?.providerKey === 'string' && runtimeMetadata.providerKey.trim()
|
|
1241
|
-
? runtimeMetadata.providerKey.trim().toLowerCase()
|
|
1242
|
-
: '';
|
|
1243
|
-
const fromOAuth = typeof this.oauthProviderId === 'string' ? this.oauthProviderId.trim().toLowerCase() : '';
|
|
1244
|
-
if (fromConfig === 'iflow' || fromRuntime === 'iflow' || fromOAuth === 'iflow') {
|
|
1245
|
-
return true;
|
|
1246
|
-
}
|
|
1247
|
-
if (fromProviderKey.startsWith('iflow.')) {
|
|
1248
|
-
return true;
|
|
1249
|
-
}
|
|
1250
|
-
return false;
|
|
1251
|
-
}
|
|
1252
|
-
enforceCodexIdentifierLength(value) {
|
|
1253
|
-
if (value.length <= CODEX_IDENTIFIER_MAX_LENGTH) {
|
|
1254
|
-
return value;
|
|
1255
|
-
}
|
|
1256
|
-
const hash = createHash('sha256').update(value).digest('hex').slice(0, 10);
|
|
1257
|
-
const keep = Math.max(1, CODEX_IDENTIFIER_MAX_LENGTH - hash.length - 1);
|
|
1258
|
-
return `${value.slice(0, keep)}_${hash}`;
|
|
344
|
+
return this.getRuntimeDetector().isIflow(runtimeMetadata);
|
|
1259
345
|
}
|
|
1260
346
|
getEffectiveBaseUrl() {
|
|
1261
|
-
const
|
|
1262
|
-
const
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
347
|
+
const cfg = this.config.config;
|
|
348
|
+
const profileKey = resolveProviderProfileKey({
|
|
349
|
+
moduleType: this.type,
|
|
350
|
+
providerType: this.providerType,
|
|
351
|
+
providerId: typeof cfg.providerId === 'string' ? cfg.providerId : undefined
|
|
352
|
+
});
|
|
353
|
+
return RuntimeEndpointResolver.resolveEffectiveBaseUrl({
|
|
354
|
+
runtime: this.getRuntimeProfile(),
|
|
355
|
+
overrideBaseUrl: this.config.config.overrides?.baseUrl,
|
|
356
|
+
configBaseUrl: this.config.config.baseUrl,
|
|
357
|
+
serviceDefaultBaseUrl: this.serviceProfile.defaultBaseUrl,
|
|
358
|
+
profileKey,
|
|
359
|
+
providerType: this.providerType
|
|
360
|
+
});
|
|
1268
361
|
}
|
|
1269
362
|
getBaseUrlCandidates(_context) {
|
|
1270
363
|
return undefined;
|
|
1271
364
|
}
|
|
1272
365
|
getEffectiveEndpoint() {
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
:
|
|
1277
|
-
|
|
1278
|
-
this.config.config.overrides?.endpoint ||
|
|
1279
|
-
this.serviceProfile.defaultEndpoint);
|
|
1280
|
-
}
|
|
1281
|
-
pickRuntimeBaseUrl(runtime) {
|
|
1282
|
-
if (!runtime) {
|
|
1283
|
-
return undefined;
|
|
1284
|
-
}
|
|
1285
|
-
if (typeof runtime.baseUrl === 'string' && runtime.baseUrl.trim()) {
|
|
1286
|
-
return runtime.baseUrl.trim();
|
|
1287
|
-
}
|
|
1288
|
-
if (typeof runtime.endpoint === 'string' && this.looksLikeAbsoluteUrl(runtime.endpoint)) {
|
|
1289
|
-
return runtime.endpoint.trim();
|
|
1290
|
-
}
|
|
1291
|
-
return undefined;
|
|
1292
|
-
}
|
|
1293
|
-
looksLikeAbsoluteUrl(value) {
|
|
1294
|
-
if (!value) {
|
|
1295
|
-
return false;
|
|
1296
|
-
}
|
|
1297
|
-
const trimmed = value.trim();
|
|
1298
|
-
return /^https?:\/\//i.test(trimmed) || trimmed.startsWith('//');
|
|
1299
|
-
}
|
|
1300
|
-
// (工具自动修复辅助函数已删除)
|
|
1301
|
-
getConfigExtensions() {
|
|
1302
|
-
const extensions = this.config.config.extensions;
|
|
1303
|
-
return extensions && typeof extensions === 'object'
|
|
1304
|
-
? extensions
|
|
1305
|
-
: {};
|
|
1306
|
-
}
|
|
1307
|
-
getEntryEndpointFromPayload(payload) {
|
|
1308
|
-
const runtimeMeta = extractProviderRuntimeMetadata(payload);
|
|
1309
|
-
const metadata = (runtimeMeta && typeof runtimeMeta.metadata === 'object')
|
|
1310
|
-
? runtimeMeta.metadata
|
|
1311
|
-
: payload.metadata;
|
|
1312
|
-
if (metadata && typeof metadata.entryEndpoint === 'string' && metadata.entryEndpoint.trim()) {
|
|
1313
|
-
return metadata.entryEndpoint;
|
|
1314
|
-
}
|
|
1315
|
-
return undefined;
|
|
1316
|
-
}
|
|
1317
|
-
getEntryEndpointFromRuntime(runtime) {
|
|
1318
|
-
if (!runtime || !runtime.metadata || typeof runtime.metadata !== 'object') {
|
|
1319
|
-
return undefined;
|
|
1320
|
-
}
|
|
1321
|
-
const meta = runtime.metadata;
|
|
1322
|
-
const value = meta.entryEndpoint;
|
|
1323
|
-
return typeof value === 'string' && value.trim().length ? value : undefined;
|
|
1324
|
-
}
|
|
1325
|
-
asResponseRecord(value) {
|
|
1326
|
-
if (isRecord(value)) {
|
|
1327
|
-
return value;
|
|
1328
|
-
}
|
|
1329
|
-
return {};
|
|
1330
|
-
}
|
|
1331
|
-
extractModel(record) {
|
|
1332
|
-
if (typeof record.model === 'string' && record.model.trim()) {
|
|
1333
|
-
return record.model;
|
|
1334
|
-
}
|
|
1335
|
-
if (record.data && typeof record.data.model === 'string' && record.data.model.trim()) {
|
|
1336
|
-
return record.data.model;
|
|
1337
|
-
}
|
|
1338
|
-
return undefined;
|
|
1339
|
-
}
|
|
1340
|
-
extractUsage(record) {
|
|
1341
|
-
if (record.usage && typeof record.usage === 'object') {
|
|
1342
|
-
return record.usage;
|
|
1343
|
-
}
|
|
1344
|
-
if (record.data && record.data.usage && typeof record.data.usage === 'object') {
|
|
1345
|
-
return record.data.usage;
|
|
1346
|
-
}
|
|
1347
|
-
return undefined;
|
|
1348
|
-
}
|
|
1349
|
-
getClientRequestIdFromContext(context) {
|
|
1350
|
-
const fromMetadata = this.extractClientId(context.metadata);
|
|
1351
|
-
if (fromMetadata) {
|
|
1352
|
-
return fromMetadata;
|
|
1353
|
-
}
|
|
1354
|
-
const runtimeMeta = context.runtimeMetadata?.metadata;
|
|
1355
|
-
return this.extractClientId(runtimeMeta);
|
|
1356
|
-
}
|
|
1357
|
-
extractClientId(source) {
|
|
1358
|
-
if (!source || typeof source !== 'object') {
|
|
1359
|
-
return undefined;
|
|
1360
|
-
}
|
|
1361
|
-
const value = source.clientRequestId;
|
|
1362
|
-
if (typeof value === 'string' && value.trim().length) {
|
|
1363
|
-
return value.trim();
|
|
1364
|
-
}
|
|
1365
|
-
return undefined;
|
|
366
|
+
return RuntimeEndpointResolver.resolveEffectiveEndpoint({
|
|
367
|
+
runtime: this.getRuntimeProfile(),
|
|
368
|
+
overrideEndpoint: this.config.config.overrides?.endpoint,
|
|
369
|
+
serviceDefaultEndpoint: this.serviceProfile.defaultEndpoint
|
|
370
|
+
});
|
|
1366
371
|
}
|
|
1367
372
|
createProviderContext() {
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
providerType:
|
|
1372
|
-
|
|
1373
|
-
profile: this.serviceProfile,
|
|
1374
|
-
routeName: runtime?.routeName,
|
|
1375
|
-
providerId: runtime?.providerId,
|
|
1376
|
-
providerKey: runtime?.providerKey,
|
|
1377
|
-
providerProtocol: runtime?.providerProtocol,
|
|
1378
|
-
metadata: runtime?.metadata,
|
|
1379
|
-
target: runtime?.target,
|
|
1380
|
-
runtimeMetadata: runtime,
|
|
1381
|
-
pipelineId: runtime?.pipelineId
|
|
1382
|
-
};
|
|
1383
|
-
}
|
|
1384
|
-
resolveProfileKey(config) {
|
|
1385
|
-
if (this.type === 'gemini-cli-http-provider') {
|
|
1386
|
-
return 'gemini-cli';
|
|
1387
|
-
}
|
|
1388
|
-
const direct = typeof config?.providerId === 'string' && config.providerId.trim()
|
|
1389
|
-
? config.providerId.trim().toLowerCase()
|
|
1390
|
-
: '';
|
|
1391
|
-
return direct || this.providerType;
|
|
1392
|
-
}
|
|
1393
|
-
normalizeAuthMode(type) {
|
|
1394
|
-
return typeof type === 'string' && type.toLowerCase().includes('oauth') ? 'oauth' : 'apikey';
|
|
1395
|
-
}
|
|
1396
|
-
resolveOAuthProviderId(type) {
|
|
1397
|
-
if (typeof type !== 'string') {
|
|
1398
|
-
return undefined;
|
|
1399
|
-
}
|
|
1400
|
-
const match = type.toLowerCase().match(/^([a-z0-9._-]+)-oauth$/);
|
|
1401
|
-
return match ? match[1] : undefined;
|
|
1402
|
-
}
|
|
1403
|
-
ensureOAuthProviderId(auth, extensions) {
|
|
1404
|
-
const fromExtension = typeof extensions?.oauthProviderId === 'string' && extensions.oauthProviderId.trim()
|
|
1405
|
-
? extensions.oauthProviderId.trim()
|
|
1406
|
-
: undefined;
|
|
1407
|
-
if (fromExtension) {
|
|
1408
|
-
return fromExtension;
|
|
1409
|
-
}
|
|
1410
|
-
const fromAuthField = typeof auth?.oauthProviderId === 'string' && auth.oauthProviderId.trim()
|
|
1411
|
-
? auth.oauthProviderId.trim()
|
|
1412
|
-
: undefined;
|
|
1413
|
-
if (fromAuthField) {
|
|
1414
|
-
return fromAuthField;
|
|
1415
|
-
}
|
|
1416
|
-
const providerId = this.resolveOAuthProviderId(auth?.rawType ?? auth?.type);
|
|
1417
|
-
if (providerId) {
|
|
1418
|
-
return providerId;
|
|
1419
|
-
}
|
|
1420
|
-
const fallback = this.resolveOAuthProviderId(auth?.type);
|
|
1421
|
-
if (fallback) {
|
|
1422
|
-
return fallback;
|
|
1423
|
-
}
|
|
1424
|
-
throw new Error(`OAuth auth.type must be declared as "<provider>-oauth" (received ${typeof auth?.rawType === 'string' ? auth.rawType : auth?.type ?? 'unknown'})`);
|
|
1425
|
-
}
|
|
1426
|
-
ensureOAuthProviderIdLegacy(type) {
|
|
1427
|
-
const providerId = this.resolveOAuthProviderId(type);
|
|
1428
|
-
if (!providerId) {
|
|
1429
|
-
throw new Error(`OAuth auth.type must be declared as "<provider>-oauth" (received ${typeof type === 'string' ? type : 'unknown'})`);
|
|
1430
|
-
}
|
|
1431
|
-
return providerId;
|
|
1432
|
-
}
|
|
1433
|
-
extractClientHeaders(source) {
|
|
1434
|
-
const normalize = (value) => {
|
|
1435
|
-
return this.normalizeClientHeaders(value);
|
|
1436
|
-
};
|
|
1437
|
-
if (!source || typeof source !== 'object') {
|
|
1438
|
-
return undefined;
|
|
1439
|
-
}
|
|
1440
|
-
const candidates = [];
|
|
1441
|
-
const metadataNode = source.metadata;
|
|
1442
|
-
if (metadataNode && typeof metadataNode === 'object') {
|
|
1443
|
-
const headersNode = metadataNode.clientHeaders;
|
|
1444
|
-
if (headersNode) {
|
|
1445
|
-
candidates.push(headersNode);
|
|
1446
|
-
}
|
|
1447
|
-
}
|
|
1448
|
-
const directNode = source.clientHeaders;
|
|
1449
|
-
if (directNode) {
|
|
1450
|
-
candidates.push(directNode);
|
|
1451
|
-
}
|
|
1452
|
-
for (const candidate of candidates) {
|
|
1453
|
-
const normalized = normalize(candidate);
|
|
1454
|
-
if (normalized) {
|
|
1455
|
-
return normalized;
|
|
1456
|
-
}
|
|
1457
|
-
}
|
|
1458
|
-
return undefined;
|
|
1459
|
-
}
|
|
1460
|
-
/**
|
|
1461
|
-
* 构建客户端元数据(用于风控和调试)
|
|
1462
|
-
*/
|
|
1463
|
-
buildClientMetadata(runtimeMetadata) {
|
|
1464
|
-
// Keep this string stable and minimal to match gcli2api snapshots.
|
|
1465
|
-
// Avoid embedding client identifiers (originator/session) into upstream headers.
|
|
1466
|
-
return 'ideType=IDE_UNSPECIFIED,platform=PLATFORM_UNSPECIFIED,pluginType=GEMINI';
|
|
1467
|
-
}
|
|
1468
|
-
/**
|
|
1469
|
-
* 构建请求类型(用于区分不同类型的请求)
|
|
1470
|
-
*/
|
|
1471
|
-
buildRequestType(runtimeMetadata) {
|
|
1472
|
-
const model = runtimeMetadata?.target;
|
|
1473
|
-
const modelId = model?.clientModelId || '';
|
|
1474
|
-
// 根据模型名称判断请求类型
|
|
1475
|
-
if (modelId.includes('image') || modelId.includes('imagen')) {
|
|
1476
|
-
return 'image_gen';
|
|
1477
|
-
}
|
|
1478
|
-
// 默认为 agent 类型
|
|
1479
|
-
return 'agent';
|
|
373
|
+
return createProviderRuntimeContext({
|
|
374
|
+
runtime: this.getCurrentRuntimeMetadata(),
|
|
375
|
+
serviceProfile: this.serviceProfile,
|
|
376
|
+
providerType: this.providerType
|
|
377
|
+
});
|
|
1480
378
|
}
|
|
1481
379
|
/**
|
|
1482
380
|
* 检查是否为 Gemini 系列传输
|
|
1483
381
|
*/
|
|
1484
382
|
isGeminiFamilyTransport() {
|
|
1485
|
-
|
|
1486
|
-
return providerType === 'gemini' ||
|
|
1487
|
-
providerType === 'gemini-cli' ||
|
|
1488
|
-
providerType === 'antigravity';
|
|
383
|
+
return this.getRuntimeDetector().isGeminiFamily();
|
|
1489
384
|
}
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
return undefined;
|
|
1493
|
-
}
|
|
1494
|
-
const normalized = {};
|
|
1495
|
-
for (const [key, raw] of Object.entries(value)) {
|
|
1496
|
-
if (typeof raw === 'string' && raw.trim()) {
|
|
1497
|
-
normalized[key] = raw;
|
|
1498
|
-
}
|
|
1499
|
-
}
|
|
1500
|
-
return Object.keys(normalized).length ? normalized : undefined;
|
|
385
|
+
getRuntimeDetector() {
|
|
386
|
+
return new RuntimeDetector(this.config, this.providerType, this.oauthProviderId);
|
|
1501
387
|
}
|
|
1502
388
|
}
|
|
1503
|
-
const CODEX_IDENTIFIER_MAX_LENGTH = 64;
|
|
1504
389
|
//# sourceMappingURL=http-transport-provider.js.map
|