@jsonstudio/rcc 0.89.164 → 0.89.333
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 +18 -15
- package/dist/build-info.js +3 -3
- package/dist/build-info.js.map +1 -1
- package/dist/cli.js +32 -0
- package/dist/cli.js.map +1 -1
- package/dist/client/gemini-cli/gemini-cli-protocol-client.js +28 -5
- package/dist/client/gemini-cli/gemini-cli-protocol-client.js.map +1 -1
- package/dist/error-handling/quiet-error-handling-center.d.ts +9 -0
- package/dist/error-handling/quiet-error-handling-center.js +141 -0
- package/dist/error-handling/quiet-error-handling-center.js.map +1 -0
- package/dist/error-handling/route-error-hub.js +8 -2
- package/dist/error-handling/route-error-hub.js.map +1 -1
- package/dist/modules/pipeline/utils/colored-logger.d.ts +2 -0
- package/dist/modules/pipeline/utils/colored-logger.js +20 -3
- package/dist/modules/pipeline/utils/colored-logger.js.map +1 -1
- package/dist/providers/auth/antigravity-userinfo-helper.d.ts +10 -0
- package/dist/providers/auth/antigravity-userinfo-helper.js +140 -0
- package/dist/providers/auth/antigravity-userinfo-helper.js.map +1 -0
- package/dist/providers/auth/oauth-lifecycle.js +140 -8
- package/dist/providers/auth/oauth-lifecycle.js.map +1 -1
- package/dist/providers/auth/token-scanner/index.d.ts +32 -0
- package/dist/providers/auth/token-scanner/index.js +86 -0
- package/dist/providers/auth/token-scanner/index.js.map +1 -0
- package/dist/providers/auth/tokenfile-auth.d.ts +17 -0
- package/dist/providers/auth/tokenfile-auth.js +27 -5
- package/dist/providers/auth/tokenfile-auth.js.map +1 -1
- package/dist/providers/core/api/provider-types.d.ts +10 -0
- package/dist/providers/core/config/oauth-flows.d.ts +2 -0
- package/dist/providers/core/config/oauth-flows.js.map +1 -1
- package/dist/providers/core/config/provider-oauth-configs.js +85 -0
- package/dist/providers/core/config/provider-oauth-configs.js.map +1 -1
- package/dist/providers/core/config/service-profiles.js +15 -1
- package/dist/providers/core/config/service-profiles.js.map +1 -1
- package/dist/providers/core/runtime/base-provider.d.ts +8 -1
- package/dist/providers/core/runtime/base-provider.js +176 -108
- package/dist/providers/core/runtime/base-provider.js.map +1 -1
- package/dist/providers/core/runtime/gemini-cli-http-provider.d.ts +9 -5
- package/dist/providers/core/runtime/gemini-cli-http-provider.js +271 -69
- package/dist/providers/core/runtime/gemini-cli-http-provider.js.map +1 -1
- package/dist/providers/core/runtime/gemini-http-provider.d.ts +1 -2
- package/dist/providers/core/runtime/gemini-http-provider.js +0 -12
- package/dist/providers/core/runtime/gemini-http-provider.js.map +1 -1
- package/dist/providers/core/runtime/http-request-executor.d.ts +42 -0
- package/dist/providers/core/runtime/http-request-executor.js +133 -0
- package/dist/providers/core/runtime/http-request-executor.js.map +1 -0
- package/dist/providers/core/runtime/http-transport-provider.d.ts +32 -12
- package/dist/providers/core/runtime/http-transport-provider.js +464 -426
- package/dist/providers/core/runtime/http-transport-provider.js.map +1 -1
- package/dist/providers/core/runtime/provider-error-classifier.d.ts +25 -0
- package/dist/providers/core/runtime/provider-error-classifier.js +149 -0
- package/dist/providers/core/runtime/provider-error-classifier.js.map +1 -0
- package/dist/providers/core/runtime/provider-error-types.d.ts +23 -0
- package/dist/providers/core/runtime/provider-error-types.js +2 -0
- package/dist/providers/core/runtime/provider-error-types.js.map +1 -0
- package/dist/providers/core/runtime/provider-factory.d.ts +1 -0
- package/dist/providers/core/runtime/provider-factory.js +43 -8
- package/dist/providers/core/runtime/provider-factory.js.map +1 -1
- package/dist/providers/core/runtime/responses-provider.d.ts +3 -3
- package/dist/providers/core/runtime/responses-provider.js +48 -114
- package/dist/providers/core/runtime/responses-provider.js.map +1 -1
- package/dist/providers/core/strategies/oauth-auth-code-flow.js +11 -3
- package/dist/providers/core/strategies/oauth-auth-code-flow.js.map +1 -1
- package/dist/providers/core/utils/http-client.d.ts +5 -0
- package/dist/providers/core/utils/http-client.js +29 -3
- package/dist/providers/core/utils/http-client.js.map +1 -1
- package/dist/providers/core/utils/provider-error-reporter.js +8 -2
- package/dist/providers/core/utils/provider-error-reporter.js.map +1 -1
- package/dist/providers/core/utils/snapshot-writer.js +5 -1
- package/dist/providers/core/utils/snapshot-writer.js.map +1 -1
- package/dist/providers/profile/provider-profile-loader.js +8 -4
- package/dist/providers/profile/provider-profile-loader.js.map +1 -1
- package/dist/runtime/runtime-flags.d.ts +4 -0
- package/dist/runtime/runtime-flags.js +32 -0
- package/dist/runtime/runtime-flags.js.map +1 -0
- package/dist/server/handlers/handler-utils.js +29 -2
- package/dist/server/handlers/handler-utils.js.map +1 -1
- package/dist/server/handlers/messages-handler.js +27 -26
- package/dist/server/handlers/messages-handler.js.map +1 -1
- package/dist/server/handlers/responses-handler.js +35 -1
- package/dist/server/handlers/responses-handler.js.map +1 -1
- package/dist/server/runtime/http-server/index.d.ts +1 -0
- package/dist/server/runtime/http-server/index.js +39 -4
- package/dist/server/runtime/http-server/index.js.map +1 -1
- package/dist/server/runtime/http-server/request-executor.d.ts +4 -0
- package/dist/server/runtime/http-server/request-executor.js +99 -4
- package/dist/server/runtime/http-server/request-executor.js.map +1 -1
- package/dist/server/utils/sse-request-parser.d.ts +1 -0
- package/dist/server/utils/sse-request-parser.js +17 -6
- package/dist/server/utils/sse-request-parser.js.map +1 -1
- package/dist/server/utils/warmup-detector.d.ts +7 -0
- package/dist/server/utils/warmup-detector.js +125 -0
- package/dist/server/utils/warmup-detector.js.map +1 -0
- package/dist/server/utils/warmup-storm-tracker.d.ts +9 -0
- package/dist/server/utils/warmup-storm-tracker.js +61 -0
- package/dist/server/utils/warmup-storm-tracker.js.map +1 -0
- package/dist/utils/debug-utils.js +14 -0
- package/dist/utils/debug-utils.js.map +1 -1
- package/dist/utils/error-handler-registry.js +6 -5
- package/dist/utils/error-handler-registry.js.map +1 -1
- package/dist/utils/error-handling-utils.js +4 -3
- package/dist/utils/error-handling-utils.js.map +1 -1
- package/dist/utils/log-helpers.d.ts +6 -0
- package/dist/utils/log-helpers.js +90 -0
- package/dist/utils/log-helpers.js.map +1 -0
- package/dist/utils/logger.d.ts +8 -0
- package/dist/utils/logger.js +55 -2
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/snapshot-writer.js +2 -6
- package/dist/utils/snapshot-writer.js.map +1 -1
- package/node_modules/@jsonstudio/llms/dist/conversion/codecs/gemini-openai-codec.js +15 -1
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/auto-thinking.d.ts +6 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/auto-thinking.js +25 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/field-mapping.d.ts +14 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/field-mapping.js +155 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/glm-tool-extraction.d.ts +2 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/glm-tool-extraction.js +264 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/qwen-transform.d.ts +3 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/qwen-transform.js +209 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/request-rules.d.ts +24 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/request-rules.js +63 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/response-blacklist.d.ts +14 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/response-blacklist.js +85 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/response-normalize.d.ts +5 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/response-normalize.js +121 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/response-validate.d.ts +5 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/response-validate.js +76 -0
- package/{dist/providers/compat/utils/snapshot-writer.d.ts → node_modules/@jsonstudio/llms/dist/conversion/compat/actions/snapshot.d.ts} +2 -2
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/snapshot.js +21 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/tool-schema.d.ts +6 -0
- package/{dist/providers/compat/glm/utils/tool-schema-helpers.js → node_modules/@jsonstudio/llms/dist/conversion/compat/actions/tool-schema.js} +6 -1
- package/{dist/providers/compat/filters → node_modules/@jsonstudio/llms/dist/conversion/compat/actions}/universal-shape-filter.d.ts +17 -22
- package/{dist/providers/compat/filters → node_modules/@jsonstudio/llms/dist/conversion/compat/actions}/universal-shape-filter.js +35 -99
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/chat-glm.json +187 -13
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/chat-iflow.json +177 -9
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/chat-lmstudio.json +10 -2
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/chat-qwen.json +14 -10
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/compat/compat-engine.d.ts +7 -2
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/compat/compat-engine.js +5 -665
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/compat/compat-pipeline-executor.d.ts +9 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/compat/compat-pipeline-executor.js +845 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/compat/compat-types.d.ts +47 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/hub-pipeline.d.ts +2 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/hub-pipeline.js +35 -1
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage3_compat/index.js +2 -2
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/target-utils.js +3 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/response/response-runtime.js +19 -2
- package/node_modules/@jsonstudio/llms/dist/conversion/responses/responses-host-policy.d.ts +6 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/responses/responses-host-policy.js +14 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/responses/responses-openai-bridge.js +51 -2
- package/node_modules/@jsonstudio/llms/dist/conversion/shared/anthropic-message-utils.js +6 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/shared/responses-reasoning-registry.d.ts +4 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/shared/responses-reasoning-registry.js +62 -1
- package/node_modules/@jsonstudio/llms/dist/conversion/shared/responses-response-utils.js +23 -1
- package/node_modules/@jsonstudio/llms/dist/conversion/shared/tool-canonicalizer.d.ts +2 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/shared/tool-filter-pipeline.js +11 -0
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/bootstrap.js +251 -12
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/classifier.js +11 -4
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/context-advisor.d.ts +21 -0
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/context-advisor.js +76 -0
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/engine.d.ts +11 -0
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/engine.js +187 -28
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/features.js +22 -457
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/health-manager.js +2 -7
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/message-utils.d.ts +7 -0
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/message-utils.js +66 -0
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/provider-registry.js +6 -2
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/token-estimator.d.ts +2 -0
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/token-estimator.js +16 -0
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/token-file-scanner.d.ts +15 -0
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/token-file-scanner.js +56 -0
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/tool-signals.d.ts +13 -0
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/tool-signals.js +403 -0
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/types.d.ts +21 -1
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/types.js +1 -0
- package/node_modules/@jsonstudio/llms/package.json +2 -2
- package/package.json +13 -11
- package/scripts/README.md +26 -12
- package/scripts/auth-antigravity-token.mjs +64 -0
- package/scripts/auth-gemini-cli-token.mjs +96 -0
- package/scripts/auth-iflow-manual.mjs +81 -0
- package/scripts/auth-iflow-token-direct.mjs +87 -0
- package/scripts/auth-iflow-token.mjs +77 -0
- package/scripts/copy-compat-assets.mjs +3 -15
- package/scripts/install-verify.mjs +1 -0
- package/scripts/pack-mode.mjs +30 -1
- package/scripts/publish-rcc.mjs +31 -0
- package/scripts/replay-codex-sample.mjs +13 -8
- package/scripts/tests/chat-pipeline-blackbox.mjs +1 -1
- package/scripts/tools/capture-provider-goldens.mjs +8 -7
- package/scripts/verify-client-headers.mjs +224 -0
- package/dist/providers/compat/base-compatibility.d.ts +0 -27
- package/dist/providers/compat/base-compatibility.js +0 -143
- package/dist/providers/compat/base-compatibility.js.map +0 -1
- package/dist/providers/compat/compat-directory-loader.d.ts +0 -4
- package/dist/providers/compat/compat-directory-loader.js +0 -85
- package/dist/providers/compat/compat-directory-loader.js.map +0 -1
- package/dist/providers/compat/compatibility-adapter.d.ts +0 -18
- package/dist/providers/compat/compatibility-adapter.js +0 -104
- package/dist/providers/compat/compatibility-adapter.js.map +0 -1
- package/dist/providers/compat/compatibility-factory.d.ts +0 -57
- package/dist/providers/compat/compatibility-factory.js +0 -155
- package/dist/providers/compat/compatibility-factory.js.map +0 -1
- package/dist/providers/compat/compatibility-interface.d.ts +0 -35
- package/dist/providers/compat/compatibility-interface.js +0 -2
- package/dist/providers/compat/compatibility-interface.js.map +0 -1
- package/dist/providers/compat/compatibility-manager.d.ts +0 -85
- package/dist/providers/compat/compatibility-manager.js +0 -368
- package/dist/providers/compat/compatibility-manager.js.map +0 -1
- package/dist/providers/compat/config/config-compatibility.d.ts +0 -28
- package/dist/providers/compat/config/config-compatibility.js +0 -95
- package/dist/providers/compat/config/config-compatibility.js.map +0 -1
- package/dist/providers/compat/field-mapping.d.ts +0 -102
- package/dist/providers/compat/field-mapping.js +0 -447
- package/dist/providers/compat/field-mapping.js.map +0 -1
- package/dist/providers/compat/filters/blacklist-sanitizer.d.ts +0 -45
- package/dist/providers/compat/filters/blacklist-sanitizer.js +0 -133
- package/dist/providers/compat/filters/blacklist-sanitizer.js.map +0 -1
- package/dist/providers/compat/filters/response-blacklist-sanitizer.d.ts +0 -28
- package/dist/providers/compat/filters/response-blacklist-sanitizer.js +0 -138
- package/dist/providers/compat/filters/response-blacklist-sanitizer.js.map +0 -1
- package/dist/providers/compat/filters/universal-shape-filter.js.map +0 -1
- package/dist/providers/compat/glm/config/blacklist-rules.json +0 -22
- package/dist/providers/compat/glm/config/field-mappings.json +0 -92
- package/dist/providers/compat/glm/config/response-blacklist.json +0 -7
- package/dist/providers/compat/glm/config/shape-filters.json +0 -37
- package/dist/providers/compat/glm/field-mapping/field-mapping-processor.d.ts +0 -28
- package/dist/providers/compat/glm/field-mapping/field-mapping-processor.js +0 -306
- package/dist/providers/compat/glm/field-mapping/field-mapping-processor.js.map +0 -1
- package/dist/providers/compat/glm/functions/glm-processor.d.ts +0 -50
- package/dist/providers/compat/glm/functions/glm-processor.js +0 -134
- package/dist/providers/compat/glm/functions/glm-processor.js.map +0 -1
- package/dist/providers/compat/glm/glm-compatibility.d.ts +0 -34
- package/dist/providers/compat/glm/glm-compatibility.js +0 -117
- package/dist/providers/compat/glm/glm-compatibility.js.map +0 -1
- package/dist/providers/compat/glm/hooks/base-hook.d.ts +0 -21
- package/dist/providers/compat/glm/hooks/base-hook.js +0 -53
- package/dist/providers/compat/glm/hooks/base-hook.js.map +0 -1
- package/dist/providers/compat/glm/hooks/glm-request-validation-hook.d.ts +0 -24
- package/dist/providers/compat/glm/hooks/glm-request-validation-hook.js +0 -268
- package/dist/providers/compat/glm/hooks/glm-request-validation-hook.js.map +0 -1
- package/dist/providers/compat/glm/hooks/glm-response-normalization-hook.d.ts +0 -21
- package/dist/providers/compat/glm/hooks/glm-response-normalization-hook.js +0 -171
- package/dist/providers/compat/glm/hooks/glm-response-normalization-hook.js.map +0 -1
- package/dist/providers/compat/glm/hooks/glm-response-validation-hook.d.ts +0 -25
- package/dist/providers/compat/glm/hooks/glm-response-validation-hook.js +0 -236
- package/dist/providers/compat/glm/hooks/glm-response-validation-hook.js.map +0 -1
- package/dist/providers/compat/glm/hooks/glm-tool-cleaning-hook.d.ts +0 -26
- package/dist/providers/compat/glm/hooks/glm-tool-cleaning-hook.js +0 -186
- package/dist/providers/compat/glm/hooks/glm-tool-cleaning-hook.js.map +0 -1
- package/dist/providers/compat/glm/index.d.ts +0 -24
- package/dist/providers/compat/glm/index.js +0 -29
- package/dist/providers/compat/glm/index.js.map +0 -1
- package/dist/providers/compat/glm/utils/tool-schema-helpers.d.ts +0 -3
- package/dist/providers/compat/glm/utils/tool-schema-helpers.js.map +0 -1
- package/dist/providers/compat/iflow/config/field-mappings.json +0 -92
- package/dist/providers/compat/iflow/config/shape-filters.json +0 -37
- package/dist/providers/compat/iflow/field-mapping/iflow-field-mapping-processor.d.ts +0 -34
- package/dist/providers/compat/iflow/field-mapping/iflow-field-mapping-processor.js +0 -386
- package/dist/providers/compat/iflow/field-mapping/iflow-field-mapping-processor.js.map +0 -1
- package/dist/providers/compat/iflow/functions/iflow-processor.d.ts +0 -53
- package/dist/providers/compat/iflow/functions/iflow-processor.js +0 -215
- package/dist/providers/compat/iflow/functions/iflow-processor.js.map +0 -1
- package/dist/providers/compat/iflow/hooks/base-hook.d.ts +0 -23
- package/dist/providers/compat/iflow/hooks/base-hook.js +0 -59
- package/dist/providers/compat/iflow/hooks/base-hook.js.map +0 -1
- package/dist/providers/compat/iflow/hooks/iflow-request-validation-hook.d.ts +0 -23
- package/dist/providers/compat/iflow/hooks/iflow-request-validation-hook.js +0 -279
- package/dist/providers/compat/iflow/hooks/iflow-request-validation-hook.js.map +0 -1
- package/dist/providers/compat/iflow/hooks/iflow-response-normalization-hook.d.ts +0 -20
- package/dist/providers/compat/iflow/hooks/iflow-response-normalization-hook.js +0 -180
- package/dist/providers/compat/iflow/hooks/iflow-response-normalization-hook.js.map +0 -1
- package/dist/providers/compat/iflow/hooks/iflow-response-validation-hook.d.ts +0 -23
- package/dist/providers/compat/iflow/hooks/iflow-response-validation-hook.js +0 -232
- package/dist/providers/compat/iflow/hooks/iflow-response-validation-hook.js.map +0 -1
- package/dist/providers/compat/iflow/hooks/iflow-tool-cleaning-hook.d.ts +0 -25
- package/dist/providers/compat/iflow/hooks/iflow-tool-cleaning-hook.js +0 -216
- package/dist/providers/compat/iflow/hooks/iflow-tool-cleaning-hook.js.map +0 -1
- package/dist/providers/compat/iflow/iflow-compatibility.d.ts +0 -24
- package/dist/providers/compat/iflow/iflow-compatibility.js +0 -94
- package/dist/providers/compat/iflow/iflow-compatibility.js.map +0 -1
- package/dist/providers/compat/index.d.ts +0 -59
- package/dist/providers/compat/index.js +0 -83
- package/dist/providers/compat/index.js.map +0 -1
- package/dist/providers/compat/lmstudio-compatibility.d.ts +0 -44
- package/dist/providers/compat/lmstudio-compatibility.js +0 -193
- package/dist/providers/compat/lmstudio-compatibility.js.map +0 -1
- package/dist/providers/compat/passthrough-compatibility.d.ts +0 -29
- package/dist/providers/compat/passthrough-compatibility.js +0 -83
- package/dist/providers/compat/passthrough-compatibility.js.map +0 -1
- package/dist/providers/compat/profiles/chat/glm/index.d.ts +0 -6
- package/dist/providers/compat/profiles/chat/glm/index.js +0 -6
- package/dist/providers/compat/profiles/chat/glm/index.js.map +0 -1
- package/dist/providers/compat/profiles/chat/iflow/index.d.ts +0 -6
- package/dist/providers/compat/profiles/chat/iflow/index.js +0 -6
- package/dist/providers/compat/profiles/chat/iflow/index.js.map +0 -1
- package/dist/providers/compat/profiles/chat/lmstudio/index.d.ts +0 -6
- package/dist/providers/compat/profiles/chat/lmstudio/index.js +0 -6
- package/dist/providers/compat/profiles/chat/lmstudio/index.js.map +0 -1
- package/dist/providers/compat/profiles/chat/qwen/index.d.ts +0 -6
- package/dist/providers/compat/profiles/chat/qwen/index.js +0 -6
- package/dist/providers/compat/profiles/chat/qwen/index.js.map +0 -1
- package/dist/providers/compat/profiles/compat/passthrough/index.d.ts +0 -6
- package/dist/providers/compat/profiles/compat/passthrough/index.js +0 -6
- package/dist/providers/compat/profiles/compat/passthrough/index.js.map +0 -1
- package/dist/providers/compat/profiles/responses/c4m/index.d.ts +0 -6
- package/dist/providers/compat/profiles/responses/c4m/index.js +0 -6
- package/dist/providers/compat/profiles/responses/c4m/index.js.map +0 -1
- package/dist/providers/compat/profiles/responses/default/index.d.ts +0 -6
- package/dist/providers/compat/profiles/responses/default/index.js +0 -6
- package/dist/providers/compat/profiles/responses/default/index.js.map +0 -1
- package/dist/providers/compat/profiles/responses/fai/index.d.ts +0 -6
- package/dist/providers/compat/profiles/responses/fai/index.js +0 -6
- package/dist/providers/compat/profiles/responses/fai/index.js.map +0 -1
- package/dist/providers/compat/profiles/responses/fc/index.d.ts +0 -6
- package/dist/providers/compat/profiles/responses/fc/index.js +0 -6
- package/dist/providers/compat/profiles/responses/fc/index.js.map +0 -1
- package/dist/providers/compat/qwen/index.d.ts +0 -4
- package/dist/providers/compat/qwen/index.js +0 -6
- package/dist/providers/compat/qwen/index.js.map +0 -1
- package/dist/providers/compat/qwen-compatibility.d.ts +0 -52
- package/dist/providers/compat/qwen-compatibility.js +0 -330
- package/dist/providers/compat/qwen-compatibility.js.map +0 -1
- package/dist/providers/compat/register-compat-module.d.ts +0 -8
- package/dist/providers/compat/register-compat-module.js +0 -53
- package/dist/providers/compat/register-compat-module.js.map +0 -1
- package/dist/providers/compat/responses/c4m-responses-compatibility.d.ts +0 -27
- package/dist/providers/compat/responses/c4m-responses-compatibility.js +0 -197
- package/dist/providers/compat/responses/c4m-responses-compatibility.js.map +0 -1
- package/dist/providers/compat/standard-compatibility-utils.d.ts +0 -1
- package/dist/providers/compat/standard-compatibility-utils.js +0 -77
- package/dist/providers/compat/standard-compatibility-utils.js.map +0 -1
- package/dist/providers/compat/standard-compatibility.d.ts +0 -31
- package/dist/providers/compat/standard-compatibility.js +0 -118
- package/dist/providers/compat/standard-compatibility.js.map +0 -1
- package/dist/providers/compat/utils/snapshot-writer.js +0 -62
- package/dist/providers/compat/utils/snapshot-writer.js.map +0 -1
- package/scripts/check-glm-compat.mjs +0 -47
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { VirtualRouterError, VirtualRouterErrorCode } from './types.js';
|
|
1
|
+
import { DEFAULT_MODEL_CONTEXT_TOKENS, VirtualRouterError, VirtualRouterErrorCode } from './types.js';
|
|
2
|
+
import { scanOAuthTokenFiles } from './token-file-scanner.js';
|
|
2
3
|
const DEFAULT_CLASSIFIER = {
|
|
3
4
|
longContextThresholdTokens: 180000,
|
|
4
5
|
thinkingKeywords: ['think step', 'analysis', 'reasoning', '仔细分析', '深度思考'],
|
|
@@ -8,6 +9,11 @@ const DEFAULT_CLASSIFIER = {
|
|
|
8
9
|
};
|
|
9
10
|
const DEFAULT_LOAD_BALANCING = { strategy: 'round-robin' };
|
|
10
11
|
const DEFAULT_HEALTH = { failureThreshold: 3, cooldownMs: 30_000, fatalCooldownMs: 300_000 };
|
|
12
|
+
const DEFAULT_CONTEXT_ROUTING = {
|
|
13
|
+
warnRatio: 0.9,
|
|
14
|
+
hardLimit: false,
|
|
15
|
+
fallbackRoute: 'longcontext'
|
|
16
|
+
};
|
|
11
17
|
/**
|
|
12
18
|
* 将用户提供的 Virtual Router 配置(或包含 virtualrouter 字段的整体配置)
|
|
13
19
|
* 规范化为 VirtualRouterConfig,供 HubPipeline / VirtualRouterEngine 直接使用。
|
|
@@ -31,12 +37,14 @@ export function bootstrapVirtualRouterConfig(input) {
|
|
|
31
37
|
const classifier = normalizeClassifier(section.classifier);
|
|
32
38
|
const loadBalancing = section.loadBalancing ?? DEFAULT_LOAD_BALANCING;
|
|
33
39
|
const health = section.health ?? DEFAULT_HEALTH;
|
|
40
|
+
const contextRouting = section.contextRouting ?? DEFAULT_CONTEXT_ROUTING;
|
|
34
41
|
const config = {
|
|
35
42
|
routing,
|
|
36
43
|
providers: providerProfiles,
|
|
37
44
|
classifier,
|
|
38
45
|
loadBalancing,
|
|
39
|
-
health
|
|
46
|
+
health,
|
|
47
|
+
contextRouting
|
|
40
48
|
};
|
|
41
49
|
return {
|
|
42
50
|
config,
|
|
@@ -56,7 +64,8 @@ function extractVirtualRouterSection(input) {
|
|
|
56
64
|
const classifier = (section.classifier ?? root.classifier);
|
|
57
65
|
const loadBalancing = normalizeLoadBalancing(section.loadBalancing ?? root.loadBalancing);
|
|
58
66
|
const health = normalizeHealth(section.health ?? root.health);
|
|
59
|
-
|
|
67
|
+
const contextRouting = normalizeContextRouting(section.contextRouting ?? root.contextRouting);
|
|
68
|
+
return { providers, routing, classifier, loadBalancing, health, contextRouting };
|
|
60
69
|
}
|
|
61
70
|
function buildProviderRuntimeEntries(providers) {
|
|
62
71
|
const runtimeEntries = {};
|
|
@@ -100,7 +109,11 @@ function buildProviderRuntimeEntries(providers) {
|
|
|
100
109
|
outboundProfile: normalizedProvider.outboundProfile,
|
|
101
110
|
compatibilityProfile: normalizedProvider.compatibilityProfile,
|
|
102
111
|
processMode: normalizedProvider.processMode,
|
|
103
|
-
responsesConfig: normalizedProvider.responsesConfig
|
|
112
|
+
responsesConfig: normalizedProvider.responsesConfig,
|
|
113
|
+
streaming: normalizedProvider.streaming,
|
|
114
|
+
modelStreaming: normalizedProvider.modelStreaming,
|
|
115
|
+
modelContextTokens: normalizedProvider.modelContextTokens,
|
|
116
|
+
defaultContextTokens: normalizedProvider.defaultContextTokens
|
|
104
117
|
};
|
|
105
118
|
}
|
|
106
119
|
}
|
|
@@ -146,6 +159,10 @@ function buildProviderProfiles(targetKeys, runtimeEntries) {
|
|
|
146
159
|
if (!runtime) {
|
|
147
160
|
throw new VirtualRouterError(`Routing target ${targetKey} references unknown runtime key ${runtimeKey}`, VirtualRouterErrorCode.CONFIG_ERROR);
|
|
148
161
|
}
|
|
162
|
+
const streamingPref = runtime.modelStreaming?.[parsed.modelId] !== undefined
|
|
163
|
+
? runtime.modelStreaming?.[parsed.modelId]
|
|
164
|
+
: runtime.streaming;
|
|
165
|
+
const contextTokens = resolveContextTokens(runtime, parsed.modelId);
|
|
149
166
|
profiles[targetKey] = {
|
|
150
167
|
providerKey: targetKey,
|
|
151
168
|
providerType: runtime.providerType,
|
|
@@ -156,15 +173,30 @@ function buildProviderProfiles(targetKeys, runtimeEntries) {
|
|
|
156
173
|
runtimeKey,
|
|
157
174
|
modelId: parsed.modelId,
|
|
158
175
|
processMode: runtime.processMode || 'chat',
|
|
159
|
-
responsesConfig: runtime.responsesConfig
|
|
176
|
+
responsesConfig: runtime.responsesConfig,
|
|
177
|
+
streaming: streamingPref,
|
|
178
|
+
maxContextTokens: contextTokens
|
|
160
179
|
};
|
|
161
180
|
targetRuntime[targetKey] = {
|
|
162
181
|
...runtime,
|
|
163
|
-
modelId: parsed.modelId
|
|
182
|
+
modelId: parsed.modelId,
|
|
183
|
+
streaming: streamingPref,
|
|
184
|
+
maxContextTokens: contextTokens
|
|
164
185
|
};
|
|
165
186
|
}
|
|
166
187
|
return { profiles, targetRuntime };
|
|
167
188
|
}
|
|
189
|
+
function resolveContextTokens(runtime, modelId) {
|
|
190
|
+
const specific = runtime.modelContextTokens?.[modelId];
|
|
191
|
+
if (typeof specific === 'number' && Number.isFinite(specific) && specific > 0) {
|
|
192
|
+
return Math.floor(specific);
|
|
193
|
+
}
|
|
194
|
+
const fallback = runtime.defaultContextTokens ?? runtime.maxContextTokens;
|
|
195
|
+
if (typeof fallback === 'number' && Number.isFinite(fallback) && fallback > 0) {
|
|
196
|
+
return Math.floor(fallback);
|
|
197
|
+
}
|
|
198
|
+
return DEFAULT_MODEL_CONTEXT_TOKENS;
|
|
199
|
+
}
|
|
168
200
|
function normalizeRouting(source) {
|
|
169
201
|
const routing = {};
|
|
170
202
|
for (const [routeName, entries] of Object.entries(source)) {
|
|
@@ -209,8 +241,12 @@ function normalizeProvider(providerId, raw) {
|
|
|
209
241
|
: '';
|
|
210
242
|
const headers = normalizeHeaders(provider.headers);
|
|
211
243
|
const compatibilityProfile = resolveCompatibilityProfile(providerId, provider);
|
|
212
|
-
const
|
|
244
|
+
const responsesNode = asRecord(provider.responses);
|
|
245
|
+
const responsesConfig = normalizeResponsesConfig(provider, responsesNode);
|
|
213
246
|
const processMode = normalizeProcessMode(provider.process);
|
|
247
|
+
const streaming = resolveProviderStreamingPreference(provider, responsesNode);
|
|
248
|
+
const modelStreaming = normalizeModelStreaming(provider);
|
|
249
|
+
const { modelContextTokens, defaultContextTokens } = normalizeModelContextTokens(provider);
|
|
214
250
|
return {
|
|
215
251
|
providerId,
|
|
216
252
|
providerType,
|
|
@@ -219,20 +255,105 @@ function normalizeProvider(providerId, raw) {
|
|
|
219
255
|
outboundProfile: mapOutboundProfile(providerType),
|
|
220
256
|
compatibilityProfile,
|
|
221
257
|
processMode,
|
|
222
|
-
responsesConfig
|
|
258
|
+
responsesConfig,
|
|
259
|
+
streaming,
|
|
260
|
+
modelStreaming,
|
|
261
|
+
modelContextTokens,
|
|
262
|
+
defaultContextTokens
|
|
223
263
|
};
|
|
224
264
|
}
|
|
225
|
-
function
|
|
226
|
-
const
|
|
227
|
-
if (!
|
|
265
|
+
function normalizeModelStreaming(provider) {
|
|
266
|
+
const modelsNode = asRecord(provider.models);
|
|
267
|
+
if (!modelsNode) {
|
|
228
268
|
return undefined;
|
|
229
269
|
}
|
|
230
|
-
const
|
|
270
|
+
const normalized = {};
|
|
271
|
+
for (const [modelId, modelRaw] of Object.entries(modelsNode)) {
|
|
272
|
+
if (!modelRaw || typeof modelRaw !== 'object') {
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
const preference = resolveStreamingPreference(modelRaw);
|
|
276
|
+
if (preference) {
|
|
277
|
+
normalized[modelId] = preference;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return Object.keys(normalized).length ? normalized : undefined;
|
|
281
|
+
}
|
|
282
|
+
function normalizeModelContextTokens(provider) {
|
|
283
|
+
const modelsNode = asRecord(provider.models);
|
|
284
|
+
const normalized = {};
|
|
285
|
+
for (const [modelId, modelRaw] of Object.entries(modelsNode)) {
|
|
286
|
+
if (!modelRaw || typeof modelRaw !== 'object') {
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
const candidate = readContextTokens(modelRaw);
|
|
290
|
+
if (candidate) {
|
|
291
|
+
normalized[modelId] = candidate;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
const configNode = asRecord(provider.config);
|
|
295
|
+
const defaultsNode = asRecord(configNode?.userConfigDefaults);
|
|
296
|
+
const defaultCandidate = readContextTokens(provider) ??
|
|
297
|
+
readContextTokens(configNode) ??
|
|
298
|
+
readContextTokens(defaultsNode);
|
|
299
|
+
return {
|
|
300
|
+
modelContextTokens: Object.keys(normalized).length ? normalized : undefined,
|
|
301
|
+
defaultContextTokens: defaultCandidate
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
function resolveStreamingPreference(model) {
|
|
305
|
+
return (coerceStreamingPreference(model.streaming) ??
|
|
306
|
+
coerceStreamingPreference(model.stream) ??
|
|
307
|
+
coerceStreamingPreference(model.supportsStreaming));
|
|
308
|
+
}
|
|
309
|
+
function coerceStreamingPreference(value) {
|
|
310
|
+
if (typeof value === 'string') {
|
|
311
|
+
const normalized = value.trim().toLowerCase();
|
|
312
|
+
if (normalized === 'always' || normalized === 'auto' || normalized === 'never') {
|
|
313
|
+
return normalized;
|
|
314
|
+
}
|
|
315
|
+
if (normalized === 'true') {
|
|
316
|
+
return 'always';
|
|
317
|
+
}
|
|
318
|
+
if (normalized === 'false') {
|
|
319
|
+
return 'never';
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
if (typeof value === 'boolean') {
|
|
323
|
+
return value ? 'always' : 'never';
|
|
324
|
+
}
|
|
325
|
+
if (value && typeof value === 'object') {
|
|
326
|
+
const record = value;
|
|
327
|
+
if (record.mode !== undefined) {
|
|
328
|
+
return coerceStreamingPreference(record.mode);
|
|
329
|
+
}
|
|
330
|
+
if (record.value !== undefined) {
|
|
331
|
+
return coerceStreamingPreference(record.value);
|
|
332
|
+
}
|
|
333
|
+
if (record.enabled !== undefined) {
|
|
334
|
+
return coerceStreamingPreference(record.enabled);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
return undefined;
|
|
338
|
+
}
|
|
339
|
+
function normalizeResponsesConfig(provider, node) {
|
|
340
|
+
const source = node ?? asRecord(provider.responses);
|
|
341
|
+
if (!source) {
|
|
342
|
+
return undefined;
|
|
343
|
+
}
|
|
344
|
+
const rawStyle = typeof source.toolCallIdStyle === 'string' ? source.toolCallIdStyle.trim().toLowerCase() : undefined;
|
|
231
345
|
if (rawStyle === 'fc' || rawStyle === 'preserve') {
|
|
232
346
|
return { toolCallIdStyle: rawStyle };
|
|
233
347
|
}
|
|
234
348
|
return undefined;
|
|
235
349
|
}
|
|
350
|
+
function resolveProviderStreamingPreference(provider, responsesNode) {
|
|
351
|
+
const configNode = asRecord(provider.config);
|
|
352
|
+
const configResponses = configNode ? asRecord(configNode.responses) : undefined;
|
|
353
|
+
return (coerceStreamingPreference(provider.streaming ?? provider.stream ?? provider.supportsStreaming ?? provider.streamingPreference) ??
|
|
354
|
+
coerceStreamingPreference(responsesNode?.streaming ?? responsesNode?.stream ?? responsesNode?.supportsStreaming) ??
|
|
355
|
+
coerceStreamingPreference(configResponses?.streaming ?? configResponses?.stream));
|
|
356
|
+
}
|
|
236
357
|
function resolveCompatibilityProfile(providerId, provider) {
|
|
237
358
|
if (typeof provider.compatibilityProfile === 'string' && provider.compatibilityProfile.trim()) {
|
|
238
359
|
return provider.compatibilityProfile.trim();
|
|
@@ -259,6 +380,26 @@ function normalizeProcessMode(value) {
|
|
|
259
380
|
}
|
|
260
381
|
return 'chat';
|
|
261
382
|
}
|
|
383
|
+
function normalizeContextRouting(input) {
|
|
384
|
+
if (!input || typeof input !== 'object') {
|
|
385
|
+
return { ...DEFAULT_CONTEXT_ROUTING };
|
|
386
|
+
}
|
|
387
|
+
const record = input;
|
|
388
|
+
const warnCandidate = coerceRatio(record.warnRatio) ??
|
|
389
|
+
coerceRatio(record?.warn_ratio);
|
|
390
|
+
const hardLimitCandidate = coerceBoolean(record.hardLimit) ??
|
|
391
|
+
coerceBoolean(record?.hard_limit);
|
|
392
|
+
const fallbackCandidate = readOptionalString(record.fallbackRoute) ??
|
|
393
|
+
readOptionalString(record?.fallback_route);
|
|
394
|
+
const warnRatio = clampWarnRatio(warnCandidate ?? DEFAULT_CONTEXT_ROUTING.warnRatio);
|
|
395
|
+
const hardLimit = typeof hardLimitCandidate === 'boolean' ? hardLimitCandidate : DEFAULT_CONTEXT_ROUTING.hardLimit;
|
|
396
|
+
const fallbackRoute = fallbackCandidate ?? DEFAULT_CONTEXT_ROUTING.fallbackRoute;
|
|
397
|
+
return {
|
|
398
|
+
warnRatio,
|
|
399
|
+
hardLimit,
|
|
400
|
+
fallbackRoute
|
|
401
|
+
};
|
|
402
|
+
}
|
|
262
403
|
function extractProviderAuthEntries(providerId, raw) {
|
|
263
404
|
const provider = asRecord(raw);
|
|
264
405
|
const auth = asRecord(provider.auth);
|
|
@@ -389,6 +530,25 @@ function extractProviderAuthEntries(providerId, raw) {
|
|
|
389
530
|
else if (typeof apiKeyField === 'string' && apiKeyField.trim()) {
|
|
390
531
|
pushEntry(undefined, buildAuthCandidate(baseTypeSource, { value: apiKeyField.trim() }));
|
|
391
532
|
}
|
|
533
|
+
// 自动多 token 扫描:仅在未显式声明多 key、且为受支持的 OAuth 提供方时触发
|
|
534
|
+
if (!entries.length && baseType === 'oauth') {
|
|
535
|
+
const oauthProviderId = baseTypeInfo.oauthProviderId;
|
|
536
|
+
if (oauthProviderId && MULTI_TOKEN_OAUTH_PROVIDERS.has(oauthProviderId)) {
|
|
537
|
+
const tokenFiles = scanOAuthTokenFiles(oauthProviderId);
|
|
538
|
+
for (const match of tokenFiles) {
|
|
539
|
+
const alias = match.alias && match.alias !== 'default'
|
|
540
|
+
? `${match.sequence}-${match.alias}`
|
|
541
|
+
: String(match.sequence);
|
|
542
|
+
const authConfig = {
|
|
543
|
+
...defaults,
|
|
544
|
+
type: baseTypeSource ?? `${oauthProviderId}-oauth`,
|
|
545
|
+
tokenFile: match.filePath,
|
|
546
|
+
oauthProviderId
|
|
547
|
+
};
|
|
548
|
+
pushEntry(alias, authConfig);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
}
|
|
392
552
|
if (!entries.length) {
|
|
393
553
|
const fallbackExtras = {
|
|
394
554
|
value: readOptionalString(auth.value),
|
|
@@ -552,6 +712,7 @@ function mergeScopes(primary, fallback) {
|
|
|
552
712
|
}
|
|
553
713
|
return merged.size ? Array.from(merged) : undefined;
|
|
554
714
|
}
|
|
715
|
+
const MULTI_TOKEN_OAUTH_PROVIDERS = new Set(['iflow']);
|
|
555
716
|
function interpretAuthType(value) {
|
|
556
717
|
if (typeof value !== 'string') {
|
|
557
718
|
return { type: 'apiKey' };
|
|
@@ -595,6 +756,47 @@ function normalizeLoadBalancing(input) {
|
|
|
595
756
|
? { strategy, weights: weightsEntries }
|
|
596
757
|
: { strategy };
|
|
597
758
|
}
|
|
759
|
+
function coerceRatio(value) {
|
|
760
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
761
|
+
return value;
|
|
762
|
+
}
|
|
763
|
+
if (typeof value === 'string') {
|
|
764
|
+
const trimmed = value.trim();
|
|
765
|
+
if (!trimmed) {
|
|
766
|
+
return undefined;
|
|
767
|
+
}
|
|
768
|
+
const parsed = Number(trimmed);
|
|
769
|
+
if (Number.isFinite(parsed)) {
|
|
770
|
+
return parsed;
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
return undefined;
|
|
774
|
+
}
|
|
775
|
+
function clampWarnRatio(value) {
|
|
776
|
+
if (!Number.isFinite(value)) {
|
|
777
|
+
return DEFAULT_CONTEXT_ROUTING.warnRatio;
|
|
778
|
+
}
|
|
779
|
+
const clamped = Math.max(0.1, Math.min(value, 0.99));
|
|
780
|
+
return Number.isFinite(clamped) ? clamped : DEFAULT_CONTEXT_ROUTING.warnRatio;
|
|
781
|
+
}
|
|
782
|
+
function coerceBoolean(value) {
|
|
783
|
+
if (typeof value === 'boolean') {
|
|
784
|
+
return value;
|
|
785
|
+
}
|
|
786
|
+
if (typeof value === 'string') {
|
|
787
|
+
const normalized = value.trim().toLowerCase();
|
|
788
|
+
if (!normalized) {
|
|
789
|
+
return undefined;
|
|
790
|
+
}
|
|
791
|
+
if (['true', '1', 'yes', 'y'].includes(normalized)) {
|
|
792
|
+
return true;
|
|
793
|
+
}
|
|
794
|
+
if (['false', '0', 'no', 'n'].includes(normalized)) {
|
|
795
|
+
return false;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
return undefined;
|
|
799
|
+
}
|
|
598
800
|
function normalizeHealth(input) {
|
|
599
801
|
if (!input || typeof input !== 'object')
|
|
600
802
|
return undefined;
|
|
@@ -609,6 +811,43 @@ function normalizeHealth(input) {
|
|
|
609
811
|
? { failureThreshold, cooldownMs, fatalCooldownMs }
|
|
610
812
|
: { failureThreshold, cooldownMs };
|
|
611
813
|
}
|
|
814
|
+
function readContextTokens(record) {
|
|
815
|
+
if (!record) {
|
|
816
|
+
return undefined;
|
|
817
|
+
}
|
|
818
|
+
const keys = [
|
|
819
|
+
'maxContextTokens',
|
|
820
|
+
'max_context_tokens',
|
|
821
|
+
'maxContext',
|
|
822
|
+
'max_context',
|
|
823
|
+
'contextTokens',
|
|
824
|
+
'context_tokens'
|
|
825
|
+
];
|
|
826
|
+
for (const key of keys) {
|
|
827
|
+
const value = record[key];
|
|
828
|
+
const parsed = normalizePositiveInteger(value);
|
|
829
|
+
if (parsed) {
|
|
830
|
+
return parsed;
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
return undefined;
|
|
834
|
+
}
|
|
835
|
+
function normalizePositiveInteger(value) {
|
|
836
|
+
if (typeof value === 'number' && Number.isFinite(value) && value > 0) {
|
|
837
|
+
return Math.floor(value);
|
|
838
|
+
}
|
|
839
|
+
if (typeof value === 'string') {
|
|
840
|
+
const trimmed = value.trim();
|
|
841
|
+
if (!trimmed) {
|
|
842
|
+
return undefined;
|
|
843
|
+
}
|
|
844
|
+
const parsed = Number(trimmed);
|
|
845
|
+
if (Number.isFinite(parsed) && parsed > 0) {
|
|
846
|
+
return Math.floor(parsed);
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
return undefined;
|
|
850
|
+
}
|
|
612
851
|
function normalizeHeaders(input) {
|
|
613
852
|
if (!input || typeof input !== 'object') {
|
|
614
853
|
return undefined;
|
|
@@ -12,12 +12,19 @@ export class RoutingClassifier {
|
|
|
12
12
|
classify(features) {
|
|
13
13
|
const lastToolCategory = features.lastAssistantToolCategory;
|
|
14
14
|
const reachedLongContext = features.estimatedTokens >= (this.config.longContextThresholdTokens ?? DEFAULT_LONG_CONTEXT_THRESHOLD);
|
|
15
|
-
const
|
|
16
|
-
containsKeywords(features.userTextSample, this.config.thinkingKeywords ?? []);
|
|
15
|
+
const latestMessageFromUser = features.latestMessageFromUser === true;
|
|
17
16
|
const codingContinuation = lastToolCategory === 'write';
|
|
18
17
|
const thinkingContinuation = lastToolCategory === 'read';
|
|
19
18
|
const searchContinuation = lastToolCategory === 'search';
|
|
20
19
|
const toolsContinuation = lastToolCategory === 'other';
|
|
20
|
+
if (latestMessageFromUser) {
|
|
21
|
+
const reasoning = 'thinking:user-input';
|
|
22
|
+
const evaluations = {
|
|
23
|
+
thinking: { triggered: true, reason: reasoning }
|
|
24
|
+
};
|
|
25
|
+
const candidates = this.ensureDefaultCandidate(['thinking']);
|
|
26
|
+
return this.buildResult('thinking', reasoning, evaluations, candidates);
|
|
27
|
+
}
|
|
21
28
|
const evaluationMap = {
|
|
22
29
|
vision: {
|
|
23
30
|
triggered: features.hasVisionTool && features.hasImageAttachment,
|
|
@@ -36,8 +43,8 @@ export class RoutingClassifier {
|
|
|
36
43
|
reason: 'coding:last-tool-write'
|
|
37
44
|
},
|
|
38
45
|
thinking: {
|
|
39
|
-
triggered: thinkingContinuation ||
|
|
40
|
-
reason: thinkingContinuation ? 'thinking:last-tool-read' : 'thinking:
|
|
46
|
+
triggered: thinkingContinuation || latestMessageFromUser,
|
|
47
|
+
reason: thinkingContinuation ? 'thinking:last-tool-read' : 'thinking:user-input'
|
|
41
48
|
},
|
|
42
49
|
tools: {
|
|
43
50
|
triggered: toolsContinuation || features.hasTools || features.hasToolCallResponses,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type ProviderProfile, type VirtualRouterContextRoutingConfig } from './types.js';
|
|
2
|
+
export interface ContextUsageSnapshot {
|
|
3
|
+
ratio: number;
|
|
4
|
+
limit: number;
|
|
5
|
+
}
|
|
6
|
+
export interface ContextAdvisorResult {
|
|
7
|
+
safe: string[];
|
|
8
|
+
risky: string[];
|
|
9
|
+
overflow: string[];
|
|
10
|
+
usage: Record<string, ContextUsageSnapshot>;
|
|
11
|
+
estimatedTokens: number;
|
|
12
|
+
allOverflow: boolean;
|
|
13
|
+
}
|
|
14
|
+
export declare class ContextAdvisor {
|
|
15
|
+
private warnRatio;
|
|
16
|
+
private hardLimit;
|
|
17
|
+
configure(config?: VirtualRouterContextRoutingConfig | null): void;
|
|
18
|
+
classify(pool: string[], estimatedTokens: number, resolveProfile: (key: string) => ProviderProfile): ContextAdvisorResult;
|
|
19
|
+
prefersFallback(result: ContextAdvisorResult): boolean;
|
|
20
|
+
allowsOverflow(): boolean;
|
|
21
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { DEFAULT_MODEL_CONTEXT_TOKENS } from './types.js';
|
|
2
|
+
const DEFAULT_WARN_RATIO = 0.9;
|
|
3
|
+
export class ContextAdvisor {
|
|
4
|
+
warnRatio = DEFAULT_WARN_RATIO;
|
|
5
|
+
hardLimit = false;
|
|
6
|
+
configure(config) {
|
|
7
|
+
if (config && typeof config.warnRatio === 'number' && Number.isFinite(config.warnRatio)) {
|
|
8
|
+
this.warnRatio = clampWarnRatio(config.warnRatio);
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
this.warnRatio = DEFAULT_WARN_RATIO;
|
|
12
|
+
}
|
|
13
|
+
this.hardLimit = Boolean(config?.hardLimit);
|
|
14
|
+
}
|
|
15
|
+
classify(pool, estimatedTokens, resolveProfile) {
|
|
16
|
+
const normalizedTokens = typeof estimatedTokens === 'number' && Number.isFinite(estimatedTokens) && estimatedTokens > 0
|
|
17
|
+
? estimatedTokens
|
|
18
|
+
: 0;
|
|
19
|
+
const safe = [];
|
|
20
|
+
const risky = [];
|
|
21
|
+
const overflow = [];
|
|
22
|
+
const usage = {};
|
|
23
|
+
for (const providerKey of pool) {
|
|
24
|
+
let limit = DEFAULT_MODEL_CONTEXT_TOKENS;
|
|
25
|
+
try {
|
|
26
|
+
const profile = resolveProfile(providerKey);
|
|
27
|
+
if (profile?.maxContextTokens && Number.isFinite(profile.maxContextTokens)) {
|
|
28
|
+
limit = profile.maxContextTokens;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
limit = DEFAULT_MODEL_CONTEXT_TOKENS;
|
|
33
|
+
}
|
|
34
|
+
if (!limit || limit <= 0) {
|
|
35
|
+
limit = DEFAULT_MODEL_CONTEXT_TOKENS;
|
|
36
|
+
}
|
|
37
|
+
const ratio = limit > 0 ? normalizedTokens / limit : 0;
|
|
38
|
+
usage[providerKey] = { ratio, limit };
|
|
39
|
+
if (normalizedTokens === 0 || ratio < this.warnRatio) {
|
|
40
|
+
safe.push(providerKey);
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (ratio < 1) {
|
|
44
|
+
risky.push(providerKey);
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
overflow.push(providerKey);
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
safe,
|
|
51
|
+
risky,
|
|
52
|
+
overflow,
|
|
53
|
+
usage,
|
|
54
|
+
estimatedTokens: normalizedTokens,
|
|
55
|
+
allOverflow: safe.length === 0 && risky.length === 0 && overflow.length > 0
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
prefersFallback(result) {
|
|
59
|
+
if (result.safe.length > 0) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
if (result.risky.length > 0) {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
return result.allOverflow;
|
|
66
|
+
}
|
|
67
|
+
allowsOverflow() {
|
|
68
|
+
return !this.hardLimit;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function clampWarnRatio(value) {
|
|
72
|
+
if (!Number.isFinite(value)) {
|
|
73
|
+
return DEFAULT_WARN_RATIO;
|
|
74
|
+
}
|
|
75
|
+
return Math.max(0.1, Math.min(0.99, value));
|
|
76
|
+
}
|
|
@@ -6,6 +6,8 @@ export declare class VirtualRouterEngine {
|
|
|
6
6
|
private readonly healthManager;
|
|
7
7
|
private loadBalancer;
|
|
8
8
|
private classifier;
|
|
9
|
+
private readonly contextAdvisor;
|
|
10
|
+
private contextRouting;
|
|
9
11
|
private routeStats;
|
|
10
12
|
private readonly debug;
|
|
11
13
|
private healthConfig;
|
|
@@ -29,6 +31,11 @@ export declare class VirtualRouterEngine {
|
|
|
29
31
|
private selectProvider;
|
|
30
32
|
private incrementRouteStat;
|
|
31
33
|
private providerHealthConfig;
|
|
34
|
+
private initializeRouteQueue;
|
|
35
|
+
private resolveFallbackRoute;
|
|
36
|
+
private maybeDeferToFallback;
|
|
37
|
+
private buildContextCandidatePools;
|
|
38
|
+
private describeAttempt;
|
|
32
39
|
private resolveStickyKey;
|
|
33
40
|
private mapProviderError;
|
|
34
41
|
private deriveReason;
|
|
@@ -36,4 +43,8 @@ export declare class VirtualRouterEngine {
|
|
|
36
43
|
private sortByPriority;
|
|
37
44
|
private routeWeight;
|
|
38
45
|
private buildHitReason;
|
|
46
|
+
private decorateWithDetail;
|
|
47
|
+
private formatVirtualRouterHit;
|
|
48
|
+
private resolveRouteColor;
|
|
49
|
+
private describeContextUsage;
|
|
39
50
|
}
|