@jsonstudio/rcc 0.89.168 → 0.89.524
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 +94 -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/commands/token-daemon.d.ts +2 -0
- package/dist/commands/token-daemon.js +183 -0
- package/dist/commands/token-daemon.js.map +1 -0
- 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/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/modules/llmswitch/bridge.d.ts +1 -1
- package/dist/modules/llmswitch/bridge.js +3 -2
- package/dist/modules/llmswitch/bridge.js.map +1 -1
- package/dist/modules/pipeline/utils/colored-logger.d.ts +2 -0
- package/dist/modules/pipeline/utils/colored-logger.js +22 -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/gemini-cli-userinfo-helper.js +12 -2
- package/dist/providers/auth/gemini-cli-userinfo-helper.js.map +1 -1
- package/dist/providers/auth/oauth-lifecycle.js +395 -24
- 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 +25 -0
- package/dist/providers/core/config/oauth-flows.js +92 -5
- package/dist/providers/core/config/oauth-flows.js.map +1 -1
- package/dist/providers/core/config/provider-oauth-configs.js +93 -2
- package/dist/providers/core/config/provider-oauth-configs.js.map +1 -1
- package/dist/providers/core/config/service-profiles.js +18 -10
- package/dist/providers/core/config/service-profiles.js.map +1 -1
- package/dist/providers/core/runtime/base-provider.d.ts +2 -0
- package/dist/providers/core/runtime/base-provider.js +135 -15
- package/dist/providers/core/runtime/base-provider.js.map +1 -1
- package/dist/providers/core/runtime/gemini-cli-http-provider.d.ts +8 -3
- package/dist/providers/core/runtime/gemini-cli-http-provider.js +332 -67
- package/dist/providers/core/runtime/gemini-cli-http-provider.js.map +1 -1
- package/dist/providers/core/runtime/http-request-executor.d.ts +1 -0
- package/dist/providers/core/runtime/http-request-executor.js +41 -1
- package/dist/providers/core/runtime/http-request-executor.js.map +1 -1
- package/dist/providers/core/runtime/http-transport-provider.d.ts +27 -0
- package/dist/providers/core/runtime/http-transport-provider.js +342 -69
- package/dist/providers/core/runtime/http-transport-provider.js.map +1 -1
- package/dist/providers/core/runtime/provider-error-classifier.d.ts +2 -2
- package/dist/providers/core/runtime/provider-error-classifier.js +14 -4
- package/dist/providers/core/runtime/provider-error-classifier.js.map +1 -1
- package/dist/providers/core/runtime/provider-factory.d.ts +1 -0
- package/dist/providers/core/runtime/provider-factory.js +37 -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 +56 -117
- package/dist/providers/core/runtime/responses-provider.js.map +1 -1
- package/dist/providers/core/runtime/vision-debug-utils.d.ts +13 -0
- package/dist/providers/core/runtime/vision-debug-utils.js +114 -0
- package/dist/providers/core/runtime/vision-debug-utils.js.map +1 -0
- package/dist/providers/core/strategies/oauth-auth-code-flow.js +82 -25
- 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 +31 -4
- 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.d.ts +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/handlers/sse-dispatcher.js +22 -2
- package/dist/server/handlers/sse-dispatcher.js.map +1 -1
- package/dist/server/runtime/http-server/index.d.ts +10 -0
- package/dist/server/runtime/http-server/index.js +551 -148
- package/dist/server/runtime/http-server/index.js.map +1 -1
- package/dist/server/runtime/http-server/request-executor.d.ts +14 -0
- package/dist/server/runtime/http-server/request-executor.js +638 -149
- package/dist/server/runtime/http-server/request-executor.js.map +1 -1
- package/dist/server/runtime/http-server/routes.d.ts +5 -0
- package/dist/server/runtime/http-server/routes.js +69 -0
- package/dist/server/runtime/http-server/routes.js.map +1 -1
- package/dist/server/runtime/http-server/runtime-manager.js +18 -0
- package/dist/server/runtime/http-server/runtime-manager.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/utf8-chunk-buffer.d.ts +43 -0
- package/dist/server/utils/utf8-chunk-buffer.js +132 -0
- package/dist/server/utils/utf8-chunk-buffer.js.map +1 -0
- 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/token-daemon/index.d.ts +7 -0
- package/dist/token-daemon/index.js +242 -0
- package/dist/token-daemon/index.js.map +1 -0
- package/dist/token-daemon/server-utils.d.ts +33 -0
- package/dist/token-daemon/server-utils.js +155 -0
- package/dist/token-daemon/server-utils.js.map +1 -0
- package/dist/token-daemon/token-daemon.d.ts +20 -0
- package/dist/token-daemon/token-daemon.js +144 -0
- package/dist/token-daemon/token-daemon.js.map +1 -0
- package/dist/token-daemon/token-types.d.ts +44 -0
- package/dist/token-daemon/token-types.js +18 -0
- package/dist/token-daemon/token-types.js.map +1 -0
- package/dist/token-daemon/token-utils.d.ts +17 -0
- package/dist/token-daemon/token-utils.js +153 -0
- package/dist/token-daemon/token-utils.js.map +1 -0
- package/dist/tools/semantic-replay.js +7 -6
- package/dist/tools/semantic-replay.js.map +1 -1
- package/dist/utils/debug-utils.js +14 -0
- package/dist/utils/debug-utils.js.map +1 -1
- package/dist/utils/error-handler-registry.d.ts +36 -0
- package/dist/utils/error-handler-registry.js +99 -12
- 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/README.md +2 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/codecs/gemini-openai-codec.js +152 -6
- 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/gemini-web-search.d.ts +17 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/gemini-web-search.js +68 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/glm-image-content.d.ts +2 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/glm-image-content.js +83 -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/glm-vision-prompt.d.ts +11 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/glm-vision-prompt.js +177 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/glm-web-search.d.ts +2 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/glm-web-search.js +63 -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 +46 -99
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/chat-gemini.json +17 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/chat-glm.json +196 -13
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/chat-iflow.json +194 -26
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/chat-lmstudio.json +43 -35
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/chat-qwen.json +20 -16
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/responses-c4m.json +42 -42
- package/node_modules/@jsonstudio/llms/dist/conversion/config/sample-config.json +1 -1
- 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 +869 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/compat/compat-types.d.ts +55 -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 +74 -5
- 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 +9 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/process/chat-process.js +213 -1
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/response/provider-response.d.ts +34 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/response/provider-response.js +84 -24
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/response/response-runtime.js +19 -2
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/response/server-side-tools.d.ts +26 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/response/server-side-tools.js +383 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/semantic-mappers/gemini-mapper.js +241 -14
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/semantic-mappers/responses-mapper.js +17 -1
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/standardized-bridge.js +14 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/types/standardized.d.ts +1 -0
- 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 +133 -5
- package/node_modules/@jsonstudio/llms/dist/conversion/shared/anthropic-message-utils.js +98 -3
- package/node_modules/@jsonstudio/llms/dist/conversion/shared/bridge-message-utils.js +137 -10
- package/node_modules/@jsonstudio/llms/dist/conversion/shared/responses-output-builder.js +43 -2
- 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/snapshot-utils.js +17 -47
- 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 +12 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/shared/tool-mapping.js +25 -2
- package/node_modules/@jsonstudio/llms/dist/index.d.ts +1 -0
- package/node_modules/@jsonstudio/llms/dist/index.js +1 -0
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/bootstrap.js +540 -36
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/classifier.js +12 -11
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/context-advisor.d.ts +19 -0
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/context-advisor.js +64 -0
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/engine.d.ts +26 -0
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/engine.js +450 -54
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/features.js +23 -458
- 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 +78 -0
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/provider-registry.js +7 -2
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/token-counter.js +14 -3
- 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 +86 -2
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/types.js +3 -1
- package/node_modules/@jsonstudio/llms/dist/servertool/engine.d.ts +27 -0
- package/node_modules/@jsonstudio/llms/dist/servertool/engine.js +60 -0
- package/node_modules/@jsonstudio/llms/dist/servertool/flow-types.d.ts +40 -0
- package/node_modules/@jsonstudio/llms/dist/servertool/flow-types.js +1 -0
- package/node_modules/@jsonstudio/llms/dist/servertool/handlers/vision.d.ts +1 -0
- package/node_modules/@jsonstudio/llms/dist/servertool/handlers/vision.js +194 -0
- package/node_modules/@jsonstudio/llms/dist/servertool/handlers/web-search.d.ts +1 -0
- package/node_modules/@jsonstudio/llms/dist/servertool/handlers/web-search.js +638 -0
- package/node_modules/@jsonstudio/llms/dist/servertool/orchestration-types.d.ts +33 -0
- package/node_modules/@jsonstudio/llms/dist/servertool/orchestration-types.js +1 -0
- package/node_modules/@jsonstudio/llms/dist/servertool/registry.d.ts +18 -0
- package/node_modules/@jsonstudio/llms/dist/servertool/registry.js +27 -0
- package/node_modules/@jsonstudio/llms/dist/servertool/server-side-tools.d.ts +8 -0
- package/node_modules/@jsonstudio/llms/dist/servertool/server-side-tools.js +208 -0
- package/node_modules/@jsonstudio/llms/dist/servertool/types.d.ts +88 -0
- package/node_modules/@jsonstudio/llms/dist/servertool/types.js +1 -0
- package/node_modules/@jsonstudio/llms/dist/servertool/vision-tool.d.ts +2 -0
- package/node_modules/@jsonstudio/llms/dist/servertool/vision-tool.js +185 -0
- package/node_modules/@jsonstudio/llms/dist/sse/json-to-sse/event-generators/responses.js +15 -3
- package/node_modules/@jsonstudio/llms/dist/sse/sse-to-json/builders/response-builder.js +6 -3
- package/node_modules/@jsonstudio/llms/dist/sse/sse-to-json/gemini-sse-to-json-converter.js +27 -1
- package/node_modules/@jsonstudio/llms/dist/sse/types/gemini-types.d.ts +20 -1
- package/node_modules/@jsonstudio/llms/dist/sse/types/responses-types.js +1 -1
- package/node_modules/@jsonstudio/llms/dist/telemetry/stats-center.d.ts +73 -0
- package/node_modules/@jsonstudio/llms/dist/telemetry/stats-center.js +280 -0
- package/node_modules/@jsonstudio/llms/package.json +2 -2
- package/package.json +11 -10
- 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 +2 -1
- package/scripts/publish-rcc.mjs +20 -4
- package/scripts/replay-codex-sample.mjs +13 -8
- package/scripts/tests/chat-pipeline-blackbox.mjs +1 -1
- package/scripts/tests/virtual-router-health.mjs +141 -6
- 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/dist/tools/replay-request.d.ts +0 -0
- package/dist/tools/replay-request.js +0 -2
- package/dist/tools/replay-request.js.map +0 -1
- package/scripts/check-glm-compat.mjs +0 -47
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import os from 'os';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import fs from 'fs/promises';
|
|
5
|
+
import { createProviderOAuthStrategy } from '../dist/providers/core/config/provider-oauth-configs.js';
|
|
6
|
+
|
|
7
|
+
async function resolveIflowTokenPath() {
|
|
8
|
+
const envFile = process.env.IFLOW_TOKEN_FILE;
|
|
9
|
+
if (envFile && envFile.trim()) {
|
|
10
|
+
const normalized = envFile.startsWith('~') ? envFile.replace(/^~\//, `${os.homedir()}/`) : envFile;
|
|
11
|
+
return { tokenPath: normalized, duplicates: [] };
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const authDir = path.join(os.homedir(), '.routecodex', 'auth');
|
|
15
|
+
const seq = 1;
|
|
16
|
+
const prefix = `iflow-oauth-${seq}`;
|
|
17
|
+
let entries = [];
|
|
18
|
+
try {
|
|
19
|
+
entries = await fs.readdir(authDir);
|
|
20
|
+
} catch {
|
|
21
|
+
// directory may not exist yet
|
|
22
|
+
}
|
|
23
|
+
const matches = entries
|
|
24
|
+
.filter((entry) => entry.endsWith('.json'))
|
|
25
|
+
.filter((entry) => entry === `${prefix}.json` || entry.startsWith(`${prefix}-`));
|
|
26
|
+
matches.sort();
|
|
27
|
+
if (matches.length > 0) {
|
|
28
|
+
const canonical = path.join(authDir, matches[0]);
|
|
29
|
+
const duplicates = matches.slice(1).map((name) => path.join(authDir, name));
|
|
30
|
+
return { tokenPath: canonical, duplicates };
|
|
31
|
+
}
|
|
32
|
+
const canonical = path.join(authDir, `${prefix}-primary.json`);
|
|
33
|
+
return { tokenPath: canonical, duplicates: [] };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function run() {
|
|
37
|
+
const { tokenPath, duplicates } = await resolveIflowTokenPath();
|
|
38
|
+
console.log(`[iflow-manual] Manual auth for: ${tokenPath}`);
|
|
39
|
+
|
|
40
|
+
// ensure token file exists
|
|
41
|
+
await fs.mkdir(path.dirname(tokenPath), { recursive: true });
|
|
42
|
+
try { await fs.access(tokenPath); } catch { await fs.writeFile(tokenPath, '{}', 'utf-8'); }
|
|
43
|
+
|
|
44
|
+
// Use device code flow but let user open the URL manually
|
|
45
|
+
const strategy = createProviderOAuthStrategy('iflow', {
|
|
46
|
+
flowType: 'device_code',
|
|
47
|
+
endpoints: {
|
|
48
|
+
deviceCodeUrl: 'https://iflow.cn/oauth/device/code',
|
|
49
|
+
tokenUrl: 'https://iflow.cn/oauth/token',
|
|
50
|
+
userInfoUrl: 'https://iflow.cn/api/oauth/getUserInfo'
|
|
51
|
+
},
|
|
52
|
+
client: { clientId: '10009311001', scopes: ['openid','profile','email','api'] }
|
|
53
|
+
}, tokenPath);
|
|
54
|
+
|
|
55
|
+
// Manually trigger device code flow
|
|
56
|
+
const deviceCodeData = await strategy.initiateDeviceCodeFlow();
|
|
57
|
+
console.log('Please open this URL in your browser:');
|
|
58
|
+
console.log(deviceCodeData.verification_uri);
|
|
59
|
+
console.log('User code:', deviceCodeData.user_code);
|
|
60
|
+
console.log('Press Enter when you have authorized...');
|
|
61
|
+
|
|
62
|
+
await new Promise(resolve => process.stdin.once('data', resolve));
|
|
63
|
+
|
|
64
|
+
const token = await strategy.pollForToken(deviceCodeData);
|
|
65
|
+
await strategy.saveToken(token);
|
|
66
|
+
|
|
67
|
+
// clean up duplicate token files for the same sequence
|
|
68
|
+
for (const dup of duplicates) {
|
|
69
|
+
if (dup === tokenPath) continue;
|
|
70
|
+
try {
|
|
71
|
+
await fs.unlink(dup);
|
|
72
|
+
console.log(`[iflow-manual] Removed duplicate token file: ${dup}`);
|
|
73
|
+
} catch {
|
|
74
|
+
// ignore
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
console.log(`[iflow-manual] Token saved to: ${tokenPath}`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
run().catch(err => { console.error('[iflow-manual] Error:', err); process.exit(1); });
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// iFlow token auth using direct device flow - no browser redirect
|
|
3
|
+
// Usage: ILOW_TOKEN_FILE="~/.routecodex/auth/iflow-oauth-1-xxx.json" node scripts/auth-iflow-token-direct.mjs
|
|
4
|
+
|
|
5
|
+
import os from 'os';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import fs from 'fs/promises';
|
|
8
|
+
|
|
9
|
+
async function resolveIflowTokenPath() {
|
|
10
|
+
const envFile = process.env.IFLOW_TOKEN_FILE;
|
|
11
|
+
if (envFile && envFile.trim()) {
|
|
12
|
+
const normalized = envFile.startsWith('~') ? envFile.replace(/^~\//, `${os.homedir()}/`) : envFile;
|
|
13
|
+
return { tokenPath: normalized, duplicates: [] };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const authDir = path.join(os.homedir(), '.routecodex', 'auth');
|
|
17
|
+
const seq = 1;
|
|
18
|
+
const prefix = `iflow-oauth-${seq}`;
|
|
19
|
+
let entries = [];
|
|
20
|
+
try {
|
|
21
|
+
entries = await fs.readdir(authDir);
|
|
22
|
+
} catch {
|
|
23
|
+
// directory may not exist yet
|
|
24
|
+
}
|
|
25
|
+
const matches = entries
|
|
26
|
+
.filter((entry) => entry.endsWith('.json'))
|
|
27
|
+
.filter((entry) => entry === `${prefix}.json` || entry.startsWith(`${prefix}-`));
|
|
28
|
+
matches.sort();
|
|
29
|
+
if (matches.length > 0) {
|
|
30
|
+
const canonical = path.join(authDir, matches[0]);
|
|
31
|
+
const duplicates = matches.slice(1).map((name) => path.join(authDir, name));
|
|
32
|
+
return { tokenPath: canonical, duplicates };
|
|
33
|
+
}
|
|
34
|
+
const canonical = path.join(authDir, `${prefix}-primary.json`);
|
|
35
|
+
return { tokenPath: canonical, duplicates: [] };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function run() {
|
|
39
|
+
const { tokenPath, duplicates } = await resolveIflowTokenPath();
|
|
40
|
+
console.log(`[iflow-auth-direct] Starting device flow for: ${tokenPath}`);
|
|
41
|
+
|
|
42
|
+
// ensure token file exists so re-auth can recreate after delete
|
|
43
|
+
await fs.mkdir(path.dirname(tokenPath), { recursive: true });
|
|
44
|
+
try {
|
|
45
|
+
await fs.access(tokenPath);
|
|
46
|
+
} catch {
|
|
47
|
+
await fs.writeFile(tokenPath, '{}', 'utf-8');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const { createProviderOAuthStrategy } = await import('../dist/providers/core/config/provider-oauth-configs.js');
|
|
51
|
+
|
|
52
|
+
// Use device code flow instead of auth code flow
|
|
53
|
+
const strategy = createProviderOAuthStrategy('iflow', {
|
|
54
|
+
flowType: 'device_code',
|
|
55
|
+
endpoints: {
|
|
56
|
+
deviceCodeUrl: 'https://iflow.cn/oauth/device/code',
|
|
57
|
+
tokenUrl: 'https://iflow.cn/oauth/token',
|
|
58
|
+
userInfoUrl: 'https://iflow.cn/api/oauth/getUserInfo'
|
|
59
|
+
},
|
|
60
|
+
client: {
|
|
61
|
+
clientId: process.env.IFLOW_CLIENT_ID || 'iflow-desktop-client',
|
|
62
|
+
scopes: ['openid','profile','email','api']
|
|
63
|
+
}
|
|
64
|
+
}, tokenPath);
|
|
65
|
+
|
|
66
|
+
console.log('[iflow-auth-direct] Opening browser for device code flow...');
|
|
67
|
+
const token = await strategy.authenticate({ openBrowser: true });
|
|
68
|
+
await strategy.saveToken(token);
|
|
69
|
+
|
|
70
|
+
// clean up duplicate token files for the same sequence
|
|
71
|
+
for (const dup of duplicates) {
|
|
72
|
+
if (dup === tokenPath) continue;
|
|
73
|
+
try {
|
|
74
|
+
await fs.unlink(dup);
|
|
75
|
+
console.log(`[iflow-auth-direct] Removed duplicate token file: ${dup}`);
|
|
76
|
+
} catch {
|
|
77
|
+
// ignore
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
console.log(`[iflow-auth-direct] Token saved to: ${tokenPath}`);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
run().catch(err => {
|
|
85
|
+
console.error('[iflow-auth-direct] Error:', err);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
});
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// iFlow token authentication script for specific token file
|
|
3
|
+
// Usage: ILOW_TOKEN_FILE="~/.routecodex/auth/iflow-oauth-1-xxx.json" node scripts/auth-iflow-token.mjs
|
|
4
|
+
|
|
5
|
+
import os from 'os';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import fs from 'fs/promises';
|
|
8
|
+
|
|
9
|
+
async function resolveIflowTokenPath() {
|
|
10
|
+
const envFile = process.env.IFLOW_TOKEN_FILE;
|
|
11
|
+
if (envFile && envFile.trim()) {
|
|
12
|
+
const normalized = envFile.startsWith('~') ? envFile.replace(/^~\//, `${os.homedir()}/`) : envFile;
|
|
13
|
+
return { tokenPath: normalized, duplicates: [] };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const authDir = path.join(os.homedir(), '.routecodex', 'auth');
|
|
17
|
+
const seq = 1;
|
|
18
|
+
const prefix = `iflow-oauth-${seq}`;
|
|
19
|
+
let entries = [];
|
|
20
|
+
try {
|
|
21
|
+
entries = await fs.readdir(authDir);
|
|
22
|
+
} catch {
|
|
23
|
+
// directory may not exist yet
|
|
24
|
+
}
|
|
25
|
+
const matches = entries
|
|
26
|
+
.filter((entry) => entry.endsWith('.json'))
|
|
27
|
+
.filter((entry) => entry === `${prefix}.json` || entry.startsWith(`${prefix}-`));
|
|
28
|
+
matches.sort();
|
|
29
|
+
if (matches.length > 0) {
|
|
30
|
+
const canonical = path.join(authDir, matches[0]);
|
|
31
|
+
const duplicates = matches.slice(1).map((name) => path.join(authDir, name));
|
|
32
|
+
return { tokenPath: canonical, duplicates };
|
|
33
|
+
}
|
|
34
|
+
const canonical = path.join(authDir, `${prefix}-primary.json`);
|
|
35
|
+
return { tokenPath: canonical, duplicates: [] };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function run() {
|
|
39
|
+
const { tokenPath, duplicates } = await resolveIflowTokenPath();
|
|
40
|
+
console.log(`[iflow-auth] Authenticating token: ${tokenPath}`);
|
|
41
|
+
|
|
42
|
+
// ensure token file exists so re-auth can recreate after delete
|
|
43
|
+
await fs.mkdir(path.dirname(tokenPath), { recursive: true });
|
|
44
|
+
try {
|
|
45
|
+
await fs.access(tokenPath);
|
|
46
|
+
} catch {
|
|
47
|
+
await fs.writeFile(tokenPath, '{}', 'utf-8');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const { ensureValidOAuthToken } = await import('../dist/providers/auth/oauth-lifecycle.js');
|
|
51
|
+
|
|
52
|
+
await ensureValidOAuthToken('iflow', {
|
|
53
|
+
type: 'iflow-oauth',
|
|
54
|
+
tokenFile: tokenPath
|
|
55
|
+
}, {
|
|
56
|
+
forceReauthorize: true,
|
|
57
|
+
openBrowser: true
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// clean up duplicate token files for the same sequence
|
|
61
|
+
for (const dup of duplicates) {
|
|
62
|
+
if (dup === tokenPath) continue;
|
|
63
|
+
try {
|
|
64
|
+
await fs.unlink(dup);
|
|
65
|
+
console.log(`[iflow-auth] Removed duplicate token file: ${dup}`);
|
|
66
|
+
} catch {
|
|
67
|
+
// ignore
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
console.log(`[iflow-auth] Token saved to: ${tokenPath}`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
run().catch(err => {
|
|
75
|
+
console.error('[iflow-auth] Error:', err);
|
|
76
|
+
process.exit(1);
|
|
77
|
+
});
|
|
@@ -15,23 +15,11 @@ async function ensureDir(p) {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
async function main() {
|
|
18
|
-
const SRC = path.resolve(process.cwd(), 'src/providers/compat');
|
|
19
|
-
const DIST = path.resolve(process.cwd(), 'dist/providers/compat');
|
|
20
18
|
const PROMPT_SRC = path.resolve(process.cwd(), 'src/config/system-prompts');
|
|
21
19
|
const PROMPT_DIST = path.resolve(process.cwd(), 'dist/config/system-prompts');
|
|
22
|
-
const copied = [];
|
|
23
20
|
const promptCopied = [];
|
|
24
21
|
try {
|
|
25
|
-
|
|
26
|
-
if (file.endsWith('.json') && file.includes(`${path.sep}config${path.sep}`)) {
|
|
27
|
-
const rel = path.relative(SRC, file);
|
|
28
|
-
const dest = path.join(DIST, rel);
|
|
29
|
-
await ensureDir(path.dirname(dest));
|
|
30
|
-
await fs.copyFile(file, dest);
|
|
31
|
-
copied.push(rel);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
// copy system prompt artifacts
|
|
22
|
+
// copy system prompt artifacts only; provider compat assets are owned by llmswitch-core
|
|
35
23
|
try {
|
|
36
24
|
for await (const file of walk(PROMPT_SRC)) {
|
|
37
25
|
const stats = await fs.stat(file);
|
|
@@ -46,8 +34,8 @@ async function main() {
|
|
|
46
34
|
} catch (promptErr) {
|
|
47
35
|
if (promptErr && promptErr.code !== 'ENOENT') throw promptErr;
|
|
48
36
|
}
|
|
49
|
-
// 不再复制
|
|
50
|
-
console.log(`[copy-compat-assets]
|
|
37
|
+
// 不再复制 provider compat 资产;兼容层由 sharedmodule/llmswitch-core 提供
|
|
38
|
+
console.log(`[copy-compat-assets] prompts copied: ${promptCopied.length}`);
|
|
51
39
|
} catch (err) {
|
|
52
40
|
console.error('[copy-compat-assets] failed:', err?.message || String(err));
|
|
53
41
|
process.exit(1);
|
package/scripts/pack-mode.mjs
CHANGED
|
@@ -59,11 +59,12 @@ try {
|
|
|
59
59
|
if (args.name === 'routecodex' || args.name === 'rcc') {
|
|
60
60
|
mutated.bundledDependencies = [];
|
|
61
61
|
mutated.bundleDependencies = [];
|
|
62
|
+
const llmsVersion = original.dependencies?.['@jsonstudio/llms'] || '^0.6.230';
|
|
62
63
|
mutated.dependencies = {
|
|
63
64
|
...(original.dependencies || {}),
|
|
64
65
|
"ajv": original.dependencies?.ajv || "^8.17.1",
|
|
65
66
|
"zod": original.dependencies?.zod || "^3.23.8",
|
|
66
|
-
"@jsonstudio/llms":
|
|
67
|
+
"@jsonstudio/llms": llmsVersion
|
|
67
68
|
};
|
|
68
69
|
}
|
|
69
70
|
fs.writeFileSync(pkgPath, JSON.stringify(mutated, null, 2));
|
package/scripts/publish-rcc.mjs
CHANGED
|
@@ -7,10 +7,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
7
7
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
8
8
|
const PROJECT_ROOT = path.resolve(__dirname, '..');
|
|
9
9
|
const PACK_SCRIPT = path.join(PROJECT_ROOT, 'scripts', 'pack-mode.mjs');
|
|
10
|
-
const
|
|
11
|
-
const version = packageJson.version;
|
|
12
|
-
const tarballName = `jsonstudio-rcc-${version}.tgz`;
|
|
13
|
-
const tarballPath = path.join(PROJECT_ROOT, tarballName);
|
|
10
|
+
const pkgPath = path.join(PROJECT_ROOT, 'package.json');
|
|
14
11
|
|
|
15
12
|
function run(command, args, options = {}) {
|
|
16
13
|
const res = spawnSync(command, args, { stdio: 'inherit', ...options });
|
|
@@ -20,11 +17,30 @@ function run(command, args, options = {}) {
|
|
|
20
17
|
}
|
|
21
18
|
|
|
22
19
|
try {
|
|
20
|
+
// 1) 使用 release 模式构建 dist(依赖 npm 上的 @jsonstudio/llms)
|
|
21
|
+
run('npm', ['run', 'build:min'], {
|
|
22
|
+
cwd: PROJECT_ROOT,
|
|
23
|
+
env: { ...process.env, BUILD_MODE: 'release' }
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// 2) 通过 pack-mode 生成 rcc tarball(内部会临时切换 package.json.name/bin 并确保 llms 为 release 包)
|
|
23
27
|
run(process.execPath, [PACK_SCRIPT, '--name', '@jsonstudio/rcc', '--bin', 'rcc'], { cwd: PROJECT_ROOT });
|
|
28
|
+
|
|
29
|
+
// 构建过程中版本号可能被 bump(gen-build-info 会 auto-bump),因此需要在 pack 之后重新读取版本号
|
|
30
|
+
const updatedPkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
31
|
+
const version = updatedPkg.version;
|
|
32
|
+
const tarballName = `jsonstudio-rcc-${version}.tgz`;
|
|
33
|
+
const tarballPath = path.join(PROJECT_ROOT, tarballName);
|
|
34
|
+
|
|
24
35
|
if (!fs.existsSync(tarballPath)) {
|
|
25
36
|
throw new Error(`tarball not found: ${tarballPath}`);
|
|
26
37
|
}
|
|
38
|
+
|
|
39
|
+
// 3) 发布 npm 包
|
|
27
40
|
run('npm', ['publish', tarballName], { cwd: PROJECT_ROOT });
|
|
41
|
+
|
|
42
|
+
// 4) pack-mode 会在内部检测 dev 链接并调用 ensure-llmswitch-mode 恢复 dev 模式,
|
|
43
|
+
// 因此此处不再额外修改 BUILD_MODE 或重新 link。后续本地如需 dev build,可单独运行 `npm run build:dev`。
|
|
28
44
|
} catch (err) {
|
|
29
45
|
console.error('[publish-rcc] failed:', err.message);
|
|
30
46
|
process.exit(1);
|
|
@@ -39,21 +39,26 @@ function readJson(file) {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
function extractEndpoint(doc) {
|
|
42
|
-
return doc?.data?.url || doc?.endpoint || '/v1/responses';
|
|
42
|
+
return doc?.data?.url || doc?.url || doc?.endpoint || '/v1/responses';
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
function extractBody(doc) {
|
|
46
|
-
const
|
|
47
|
-
if (!
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
const bodyNode = doc?.data?.body || doc?.body;
|
|
47
|
+
if (!bodyNode) {
|
|
48
|
+
if (typeof doc?.data?.data === 'object') return doc.data.data;
|
|
49
|
+
if (typeof doc?.body?.data === 'object') return doc.body.data;
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
if (typeof bodyNode.body === 'object') return bodyNode.body;
|
|
53
|
+
if (typeof bodyNode === 'object') return bodyNode;
|
|
54
|
+
if (typeof doc?.data?.data === 'object') return doc.data.data;
|
|
55
|
+
if (typeof doc?.body?.data === 'object') return doc.body.data;
|
|
51
56
|
return undefined;
|
|
52
57
|
}
|
|
53
58
|
|
|
54
59
|
function detectStream(doc, requestBody) {
|
|
55
|
-
if (doc?.data?.meta?.stream === true) return true;
|
|
56
|
-
if (doc?.data?.body?.metadata?.stream === true) return true;
|
|
60
|
+
if (doc?.data?.meta?.stream === true || doc?.meta?.stream === true) return true;
|
|
61
|
+
if (doc?.data?.body?.metadata?.stream === true || doc?.body?.metadata?.stream === true) return true;
|
|
57
62
|
if (requestBody?.stream === true) return true;
|
|
58
63
|
return false;
|
|
59
64
|
}
|
|
@@ -191,7 +191,7 @@ function resolveGoldenExpectations(sample) {
|
|
|
191
191
|
if (sample.meta?.endpoint && sample.meta?.requestId) {
|
|
192
192
|
const reqId = sample.meta.requestId;
|
|
193
193
|
const endpoint = sample.meta.endpoint;
|
|
194
|
-
const baseDir = path.join(os.homedir(), '.routecodex', '
|
|
194
|
+
const baseDir = path.join(os.homedir(), '.routecodex', 'codex-samples');
|
|
195
195
|
const folder = endpoint.includes('/messages')
|
|
196
196
|
? 'anthropic-messages'
|
|
197
197
|
: endpoint.includes('/responses')
|
|
@@ -13,7 +13,7 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
|
13
13
|
|
|
14
14
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
15
15
|
const ROOT = path.resolve(__dirname, '../..');
|
|
16
|
-
const CORE_DIST = path.join(ROOT, 'sharedmodule', 'llmswitch-core', 'dist', '
|
|
16
|
+
const CORE_DIST = path.join(ROOT, 'sharedmodule', 'llmswitch-core', 'dist', 'router', 'virtual-router');
|
|
17
17
|
|
|
18
18
|
async function loadCoreModule(rel) {
|
|
19
19
|
const file = path.join(CORE_DIST, rel);
|
|
@@ -21,16 +21,19 @@ async function loadCoreModule(rel) {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
const { VirtualRouterEngine } = await loadCoreModule('engine.js');
|
|
24
|
+
const { bootstrapVirtualRouterConfig } = await loadCoreModule('bootstrap.js');
|
|
24
25
|
const { providerErrorCenter } = await loadCoreModule('error-center.js');
|
|
25
26
|
const { VirtualRouterError } = await loadCoreModule('types.js');
|
|
26
27
|
|
|
27
28
|
function parseArgs(argv) {
|
|
28
|
-
const args = { out: null };
|
|
29
|
+
const args = { out: null, config: null };
|
|
29
30
|
const list = [...argv];
|
|
30
31
|
while (list.length) {
|
|
31
32
|
const cur = list.shift();
|
|
32
33
|
if (cur === '--out' || cur === '--output') {
|
|
33
34
|
args.out = list.shift() || null;
|
|
35
|
+
} else if (cur === '--config') {
|
|
36
|
+
args.config = list.shift() || null;
|
|
34
37
|
} else if (cur === '--help' || cur === '-h') {
|
|
35
38
|
args.help = true;
|
|
36
39
|
}
|
|
@@ -57,9 +60,18 @@ function createRouterConfig() {
|
|
|
57
60
|
'charlie.sim-model': buildProviderProfile('charlie.sim-model', 'https://charlie.local/v1')
|
|
58
61
|
};
|
|
59
62
|
const routing = {
|
|
60
|
-
default:
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
default: [
|
|
64
|
+
{ id: 'default-primary', priority: 200, targets: ['alpha.sim-model', 'bravo.sim-model'] },
|
|
65
|
+
{ id: 'default-backup', backup: true, priority: 100, targets: ['charlie.sim-model'] }
|
|
66
|
+
],
|
|
67
|
+
coding: [
|
|
68
|
+
{ id: 'coding-primary', priority: 200, targets: ['bravo.sim-model', 'charlie.sim-model'] },
|
|
69
|
+
{ id: 'coding-backup', backup: true, priority: 100, targets: ['alpha.sim-model'] }
|
|
70
|
+
],
|
|
71
|
+
thinking: [
|
|
72
|
+
{ id: 'thinking-primary', priority: 200, targets: ['charlie.sim-model'] },
|
|
73
|
+
{ id: 'thinking-backup', backup: true, priority: 100, targets: ['bravo.sim-model'] }
|
|
74
|
+
]
|
|
63
75
|
};
|
|
64
76
|
return {
|
|
65
77
|
routing,
|
|
@@ -227,16 +239,128 @@ async function scenarioScheduler(sim) {
|
|
|
227
239
|
sim.runRoute('thinking');
|
|
228
240
|
}
|
|
229
241
|
|
|
242
|
+
async function scenarioPriorityPools(sim) {
|
|
243
|
+
const first = sim.runRoute('thinking');
|
|
244
|
+
if (first !== 'charlie.sim-model') {
|
|
245
|
+
throw new Error(`expected primary thinking pool hit charlie.sim-model, got ${first}`);
|
|
246
|
+
}
|
|
247
|
+
sim.engine.handleProviderFailure({
|
|
248
|
+
providerKey: 'charlie.sim-model',
|
|
249
|
+
reason: 'priority-test',
|
|
250
|
+
fatal: true,
|
|
251
|
+
affectsHealth: true,
|
|
252
|
+
cooldownOverrideMs: 60_000
|
|
253
|
+
});
|
|
254
|
+
const second = sim.runRoute('thinking');
|
|
255
|
+
if (second !== 'bravo.sim-model') {
|
|
256
|
+
throw new Error(`expected thinking backup pool hit bravo.sim-model, got ${second}`);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
230
260
|
async function scenarioRoutingDirectives(sim) {
|
|
231
261
|
sim.runRoute('baseline', '普通请求');
|
|
232
262
|
sim.runRoute('forced-thinking', '请仔细分析这个问题 <**thinking**>');
|
|
233
263
|
sim.runRoute('forced-provider', '请强制使用这个provider <**charlie.sim-model**> 来回答');
|
|
234
264
|
}
|
|
235
265
|
|
|
266
|
+
async function scenarioRealConfig(configPath) {
|
|
267
|
+
const resolvedPath = path.resolve(configPath);
|
|
268
|
+
console.log(`\n=== Scenario: real-config (${resolvedPath}) ===`);
|
|
269
|
+
const source = JSON.parse(await fs.readFile(resolvedPath, 'utf-8'));
|
|
270
|
+
const section = source.virtualrouter && typeof source.virtualrouter === 'object' ? source.virtualrouter : source;
|
|
271
|
+
const { config } = bootstrapVirtualRouterConfig(section);
|
|
272
|
+
const engine = new VirtualRouterEngine();
|
|
273
|
+
engine.initialize(config);
|
|
274
|
+
const thinkingPools = config.routing.thinking ?? [];
|
|
275
|
+
const primaryPools = thinkingPools.filter((tier) => !tier.backup);
|
|
276
|
+
const backupPools = thinkingPools.filter((tier) => tier.backup);
|
|
277
|
+
|
|
278
|
+
const runThinking = (label) => {
|
|
279
|
+
const reqId = `real-config-${label}-${Date.now()}`;
|
|
280
|
+
const request = {
|
|
281
|
+
model: 'gpt-5.2-codex',
|
|
282
|
+
messages: [
|
|
283
|
+
{ role: 'system', content: 'diagnostic' },
|
|
284
|
+
{ role: 'user', content: `深入思考:${label}` }
|
|
285
|
+
]
|
|
286
|
+
};
|
|
287
|
+
const metadata = {
|
|
288
|
+
requestId: reqId,
|
|
289
|
+
entryEndpoint: '/v1/responses',
|
|
290
|
+
processMode: 'chat',
|
|
291
|
+
stream: false,
|
|
292
|
+
direction: 'request',
|
|
293
|
+
providerProtocol: 'openai-responses'
|
|
294
|
+
};
|
|
295
|
+
const result = engine.route(request, metadata);
|
|
296
|
+
console.log(
|
|
297
|
+
JSON.stringify(
|
|
298
|
+
{
|
|
299
|
+
stage: 'real-config-route',
|
|
300
|
+
label,
|
|
301
|
+
providerKey: result.decision.providerKey,
|
|
302
|
+
route: result.decision.routeName,
|
|
303
|
+
poolId: result.decision.poolId
|
|
304
|
+
},
|
|
305
|
+
null,
|
|
306
|
+
2
|
|
307
|
+
)
|
|
308
|
+
);
|
|
309
|
+
return result.decision.providerKey;
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
const markUnavailable = (targets, reason) => {
|
|
313
|
+
for (const key of targets || []) {
|
|
314
|
+
engine.handleProviderFailure({
|
|
315
|
+
providerKey: key,
|
|
316
|
+
fatal: true,
|
|
317
|
+
affectsHealth: true,
|
|
318
|
+
reason,
|
|
319
|
+
cooldownOverrideMs: 60_000
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
// Primary hit
|
|
325
|
+
const firstProvider = runThinking('primary-hit');
|
|
326
|
+
const primaryTargets = primaryPools.flatMap((pool) => pool.targets ?? []);
|
|
327
|
+
const backupTargets = backupPools.flatMap((pool) => pool.targets ?? []);
|
|
328
|
+
if (primaryTargets.length === 0) {
|
|
329
|
+
console.warn('[real-config] No explicit primary thinking pool configured.');
|
|
330
|
+
} else if (!primaryTargets.includes(firstProvider)) {
|
|
331
|
+
console.warn('[real-config] First provider is not part of primary tier:', firstProvider);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Drain primary
|
|
335
|
+
markUnavailable(primaryTargets, 'primary-exhausted');
|
|
336
|
+
const secondProvider = runThinking('backup-hit');
|
|
337
|
+
if (backupTargets.length && !backupTargets.includes(secondProvider)) {
|
|
338
|
+
throw new Error(
|
|
339
|
+
`[real-config] Expected backup pool provider after draining primary, got ${secondProvider}`
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Drain backup -> should fall to default
|
|
344
|
+
markUnavailable(backupTargets, 'backup-exhausted');
|
|
345
|
+
const thirdProvider = runThinking('default-fallback');
|
|
346
|
+
const usedRoute = engine.getStatus().routes;
|
|
347
|
+
console.log(
|
|
348
|
+
JSON.stringify(
|
|
349
|
+
{
|
|
350
|
+
stage: 'real-config-summary',
|
|
351
|
+
thirdProvider,
|
|
352
|
+
routes: usedRoute
|
|
353
|
+
},
|
|
354
|
+
null,
|
|
355
|
+
2
|
|
356
|
+
)
|
|
357
|
+
);
|
|
358
|
+
}
|
|
359
|
+
|
|
236
360
|
async function main() {
|
|
237
361
|
const args = parseArgs(process.argv.slice(2));
|
|
238
362
|
if (args.help) {
|
|
239
|
-
console.log('Usage: node scripts/tests/virtual-router-health.mjs [--out summary.json]');
|
|
363
|
+
console.log('Usage: node scripts/tests/virtual-router-health.mjs [--out summary.json] [--config ~/.routecodex/config.json]');
|
|
240
364
|
return;
|
|
241
365
|
}
|
|
242
366
|
|
|
@@ -247,6 +371,7 @@ async function main() {
|
|
|
247
371
|
['upstream', scenarioUpstream],
|
|
248
372
|
['timeout', scenarioTimeout],
|
|
249
373
|
['scheduler', scenarioScheduler],
|
|
374
|
+
['priority-pools', scenarioPriorityPools],
|
|
250
375
|
['routing-directives', scenarioRoutingDirectives]
|
|
251
376
|
];
|
|
252
377
|
|
|
@@ -260,6 +385,16 @@ async function main() {
|
|
|
260
385
|
});
|
|
261
386
|
}
|
|
262
387
|
|
|
388
|
+
if (args.config) {
|
|
389
|
+
try {
|
|
390
|
+
await scenarioRealConfig(args.config);
|
|
391
|
+
summary.push({ name: 'real-config', status: 'ok', lastHealth: null });
|
|
392
|
+
} catch (error) {
|
|
393
|
+
console.error('[real-config] failed:', error);
|
|
394
|
+
summary.push({ name: 'real-config', status: 'failed', error: error?.message || String(error), lastHealth: null });
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
263
398
|
if (args.out) {
|
|
264
399
|
const outFile = path.resolve(process.cwd(), args.out);
|
|
265
400
|
await fs.mkdir(path.dirname(outFile), { recursive: true });
|
|
@@ -13,18 +13,19 @@ const ROOT = path.resolve(__dirname, '../..');
|
|
|
13
13
|
|
|
14
14
|
const HOME = os.homedir();
|
|
15
15
|
const PROVIDER_ROOT = path.join(HOME, '.routecodex', 'provider');
|
|
16
|
-
const
|
|
17
|
-
const
|
|
16
|
+
const RUNTIME_SNAPSHOT_ROOT = path.join(HOME, '.routecodex', 'codex-samples');
|
|
17
|
+
const GOLDEN_ROOT = path.join(HOME, '.routecodex', 'golden_samples');
|
|
18
|
+
const PROVIDER_GOLDEN_ROOT = path.join(GOLDEN_ROOT, 'provider_golden_samples');
|
|
18
19
|
const CI_GOLDENS_ROOT = path.join(ROOT, 'samples', 'ci-goldens');
|
|
19
20
|
const CUSTOM_SAMPLE_ROOTS = [
|
|
20
|
-
path.join(
|
|
21
|
+
path.join(GOLDEN_ROOT, 'new'),
|
|
21
22
|
CI_GOLDENS_ROOT
|
|
22
23
|
];
|
|
23
24
|
const TEMP_ROOT = path.join(process.cwd(), 'tmp', 'provider-captures');
|
|
24
25
|
const STAGE_DIRS = {
|
|
25
|
-
'openai-chat': path.join(
|
|
26
|
-
'openai-responses': path.join(
|
|
27
|
-
'anthropic-messages': path.join(
|
|
26
|
+
'openai-chat': path.join(RUNTIME_SNAPSHOT_ROOT, 'openai-chat'),
|
|
27
|
+
'openai-responses': path.join(RUNTIME_SNAPSHOT_ROOT, 'openai-responses'),
|
|
28
|
+
'anthropic-messages': path.join(RUNTIME_SNAPSHOT_ROOT, 'anthropic-messages')
|
|
28
29
|
};
|
|
29
30
|
const ENTRY_STAGE_MATRIX = {
|
|
30
31
|
'openai-chat': {
|
|
@@ -437,7 +438,7 @@ function spawnServer(configPath, port) {
|
|
|
437
438
|
}
|
|
438
439
|
|
|
439
440
|
async function captureProvider(providerEntry, entryType, port, options, sanitizedProviderId) {
|
|
440
|
-
const stageDir = path.join(
|
|
441
|
+
const stageDir = path.join(RUNTIME_SNAPSHOT_ROOT, ENTRY_DEFS[entryType].stageDir);
|
|
441
442
|
const suffix = '_req_outbound_stage2_format_build.json';
|
|
442
443
|
const before = snapshotStageFiles(stageDir, suffix);
|
|
443
444
|
const baseUrl = `http://127.0.0.1:${port}`;
|