@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
|
@@ -266,6 +266,7 @@ export function buildOpenAIChatFromAnthropic(payload) {
|
|
|
266
266
|
continue;
|
|
267
267
|
}
|
|
268
268
|
const textParts = [];
|
|
269
|
+
const imageBlocks = [];
|
|
269
270
|
const toolCalls = [];
|
|
270
271
|
const reasoningParts = [];
|
|
271
272
|
const toolResults = [];
|
|
@@ -284,6 +285,29 @@ export function buildOpenAIChatFromAnthropic(payload) {
|
|
|
284
285
|
reasoningParts.push(thinkingText);
|
|
285
286
|
}
|
|
286
287
|
}
|
|
288
|
+
else if (t === 'image') {
|
|
289
|
+
const source = block.source;
|
|
290
|
+
if (source && typeof source === 'object') {
|
|
291
|
+
const s = source;
|
|
292
|
+
const srcType = typeof s.type === 'string' ? s.type.toLowerCase() : '';
|
|
293
|
+
let url;
|
|
294
|
+
if (srcType === 'url' && typeof s.url === 'string') {
|
|
295
|
+
url = s.url;
|
|
296
|
+
}
|
|
297
|
+
else if (srcType === 'base64' && typeof s.data === 'string') {
|
|
298
|
+
const mediaType = typeof s.media_type === 'string' && s.media_type.trim().length
|
|
299
|
+
? s.media_type.trim()
|
|
300
|
+
: 'image/png';
|
|
301
|
+
url = `data:${mediaType};base64,${s.data}`;
|
|
302
|
+
}
|
|
303
|
+
if (url && url.trim().length) {
|
|
304
|
+
imageBlocks.push({
|
|
305
|
+
type: 'image_url',
|
|
306
|
+
image_url: { url: url.trim() }
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
287
311
|
else if (t === 'tool_use') {
|
|
288
312
|
const name = requireTrimmedString(block.name, 'tool_use.name');
|
|
289
313
|
const id = requireTrimmedString(block.id, 'tool_use.id');
|
|
@@ -310,10 +334,22 @@ export function buildOpenAIChatFromAnthropic(payload) {
|
|
|
310
334
|
}
|
|
311
335
|
const hasText = typeof normalized.contentText === 'string' && normalized.contentText.length > 0;
|
|
312
336
|
const hasReasoning = mergedReasoning.length > 0;
|
|
313
|
-
if (hasText || hasRawText || toolCalls.length > 0 || hasReasoning) {
|
|
337
|
+
if (hasText || hasRawText || toolCalls.length > 0 || hasReasoning || imageBlocks.length > 0) {
|
|
338
|
+
let contentNode = (hasText ? normalized.contentText : undefined) ?? combinedText ?? '';
|
|
339
|
+
if (imageBlocks.length > 0) {
|
|
340
|
+
const blocks = [];
|
|
341
|
+
const textPayload = (hasText ? normalized.contentText : undefined) ?? combinedText ?? '';
|
|
342
|
+
if (typeof textPayload === 'string' && textPayload.trim().length) {
|
|
343
|
+
blocks.push({ type: 'text', text: textPayload.trim() });
|
|
344
|
+
}
|
|
345
|
+
for (const img of imageBlocks) {
|
|
346
|
+
blocks.push(jsonClone(img));
|
|
347
|
+
}
|
|
348
|
+
contentNode = blocks;
|
|
349
|
+
}
|
|
314
350
|
const msg = {
|
|
315
351
|
role,
|
|
316
|
-
content:
|
|
352
|
+
content: contentNode
|
|
317
353
|
};
|
|
318
354
|
if (toolCalls.length)
|
|
319
355
|
msg.tool_calls = toolCalls;
|
|
@@ -336,6 +372,12 @@ export function buildOpenAIChatFromAnthropic(payload) {
|
|
|
336
372
|
request.top_p = body.top_p;
|
|
337
373
|
if (typeof body.stream === 'boolean')
|
|
338
374
|
request.stream = body.stream;
|
|
375
|
+
if (typeof body.id === 'string') {
|
|
376
|
+
request.request_id = body.id;
|
|
377
|
+
}
|
|
378
|
+
else if (typeof body.request_id === 'string') {
|
|
379
|
+
request.request_id = body.request_id;
|
|
380
|
+
}
|
|
339
381
|
if ('tool_choice' in body)
|
|
340
382
|
request.tool_choice = body.tool_choice;
|
|
341
383
|
const normalizedTools = mapAnthropicToolsToChat(body.tools);
|
|
@@ -684,7 +726,8 @@ export function buildAnthropicRequestFromOpenAIChat(chatReq) {
|
|
|
684
726
|
targetShape = mirrorShapes[mirrorIndex];
|
|
685
727
|
mirrorIndex += 1;
|
|
686
728
|
}
|
|
687
|
-
const
|
|
729
|
+
const contentNode = m.content;
|
|
730
|
+
const text = collectText(contentNode).trim();
|
|
688
731
|
if (role === 'system') {
|
|
689
732
|
if (!text) {
|
|
690
733
|
throw new Error('Anthropic bridge constraint violated: Chat system message must contain text');
|
|
@@ -709,6 +752,58 @@ export function buildAnthropicRequestFromOpenAIChat(chatReq) {
|
|
|
709
752
|
continue;
|
|
710
753
|
}
|
|
711
754
|
const blocks = [];
|
|
755
|
+
if (Array.isArray(contentNode)) {
|
|
756
|
+
// Preserve or synthesize image blocks where possible, and fall back to text for the rest.
|
|
757
|
+
for (const entry of contentNode) {
|
|
758
|
+
if (!entry || typeof entry !== 'object')
|
|
759
|
+
continue;
|
|
760
|
+
const node = entry;
|
|
761
|
+
const t = typeof node.type === 'string' ? node.type.toLowerCase() : '';
|
|
762
|
+
if (t === 'image' && node.source && typeof node.source === 'object') {
|
|
763
|
+
// Pass-through Anthropic image block as-is.
|
|
764
|
+
blocks.push({
|
|
765
|
+
type: 'image',
|
|
766
|
+
source: jsonClone(node.source)
|
|
767
|
+
});
|
|
768
|
+
continue;
|
|
769
|
+
}
|
|
770
|
+
if (t === 'image_url') {
|
|
771
|
+
let url = '';
|
|
772
|
+
const imageUrl = node.image_url;
|
|
773
|
+
if (typeof imageUrl === 'string') {
|
|
774
|
+
url = imageUrl;
|
|
775
|
+
}
|
|
776
|
+
else if (imageUrl && typeof imageUrl === 'object' && typeof imageUrl.url === 'string') {
|
|
777
|
+
url = imageUrl.url;
|
|
778
|
+
}
|
|
779
|
+
const trimmed = url.trim();
|
|
780
|
+
if (!trimmed.length)
|
|
781
|
+
continue;
|
|
782
|
+
const source = {};
|
|
783
|
+
if (trimmed.startsWith('data:')) {
|
|
784
|
+
const match = /^data:([^;,]+)?(?:;base64)?,(.*)$/s.exec(trimmed);
|
|
785
|
+
if (match) {
|
|
786
|
+
const mediaType = (match[1] || '').trim() || 'image/png';
|
|
787
|
+
source.type = 'base64';
|
|
788
|
+
source.media_type = mediaType;
|
|
789
|
+
source.data = match[2] || '';
|
|
790
|
+
}
|
|
791
|
+
else {
|
|
792
|
+
source.type = 'url';
|
|
793
|
+
source.url = trimmed;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
else {
|
|
797
|
+
source.type = 'url';
|
|
798
|
+
source.url = trimmed;
|
|
799
|
+
}
|
|
800
|
+
blocks.push({
|
|
801
|
+
type: 'image',
|
|
802
|
+
source
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
}
|
|
712
807
|
if (text) {
|
|
713
808
|
blocks.push({ type: 'text', text });
|
|
714
809
|
}
|
|
@@ -66,6 +66,59 @@ function collectText(value) {
|
|
|
66
66
|
}
|
|
67
67
|
return '';
|
|
68
68
|
}
|
|
69
|
+
function extractImageBlocksFromContent(content) {
|
|
70
|
+
const images = [];
|
|
71
|
+
const visit = (value) => {
|
|
72
|
+
if (!value)
|
|
73
|
+
return;
|
|
74
|
+
if (Array.isArray(value)) {
|
|
75
|
+
for (const entry of value)
|
|
76
|
+
visit(entry);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (typeof value !== 'object') {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const record = value;
|
|
83
|
+
const typeValue = typeof record.type === 'string' ? record.type.toLowerCase() : '';
|
|
84
|
+
if (typeValue === 'image' || typeValue === 'image_url' || typeValue === 'input_image') {
|
|
85
|
+
let url = '';
|
|
86
|
+
const imageUrl = record.image_url;
|
|
87
|
+
if (typeof imageUrl === 'string') {
|
|
88
|
+
url = imageUrl;
|
|
89
|
+
}
|
|
90
|
+
else if (imageUrl && typeof imageUrl === 'object' && typeof imageUrl.url === 'string') {
|
|
91
|
+
url = imageUrl.url;
|
|
92
|
+
}
|
|
93
|
+
else if (typeof record.url === 'string') {
|
|
94
|
+
url = record.url;
|
|
95
|
+
}
|
|
96
|
+
else if (typeof record.uri === 'string') {
|
|
97
|
+
url = record.uri;
|
|
98
|
+
}
|
|
99
|
+
else if (typeof record.data === 'string') {
|
|
100
|
+
url = record.data;
|
|
101
|
+
}
|
|
102
|
+
const trimmed = url.trim();
|
|
103
|
+
if (trimmed.length) {
|
|
104
|
+
let detail;
|
|
105
|
+
if (imageUrl && typeof imageUrl === 'object' && typeof imageUrl.detail === 'string') {
|
|
106
|
+
detail = imageUrl.detail.trim() || undefined;
|
|
107
|
+
}
|
|
108
|
+
else if (typeof record.detail === 'string') {
|
|
109
|
+
detail = record.detail.trim() || undefined;
|
|
110
|
+
}
|
|
111
|
+
images.push({ url: trimmed, detail });
|
|
112
|
+
}
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (Array.isArray(record.content)) {
|
|
116
|
+
visit(record.content);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
visit(content);
|
|
120
|
+
return images;
|
|
121
|
+
}
|
|
69
122
|
function extractUserTextFromEntry(entry) {
|
|
70
123
|
if (!entry || typeof entry !== 'object')
|
|
71
124
|
return '';
|
|
@@ -94,6 +147,7 @@ export function convertMessagesToBridgeInput(options) {
|
|
|
94
147
|
const role = coerceBridgeRole(m.role || 'user');
|
|
95
148
|
const content = m.content;
|
|
96
149
|
const collectedText = collectText(content);
|
|
150
|
+
const imageBlocks = extractImageBlocksFromContent(content);
|
|
97
151
|
const text = role === 'system' ? collectedText : collectedText.trim();
|
|
98
152
|
if (role === 'system') {
|
|
99
153
|
if (collectedText && collectedText.length) {
|
|
@@ -170,13 +224,29 @@ export function convertMessagesToBridgeInput(options) {
|
|
|
170
224
|
}
|
|
171
225
|
continue;
|
|
172
226
|
}
|
|
173
|
-
if (typeof text === 'string') {
|
|
227
|
+
if (typeof text === 'string' || imageBlocks.length) {
|
|
174
228
|
const tRole = role === 'assistant' ? 'output_text' : 'input_text';
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
}
|
|
179
|
-
|
|
229
|
+
const blocks = [];
|
|
230
|
+
if (typeof text === 'string' && text.length) {
|
|
231
|
+
blocks.push({ type: tRole, text });
|
|
232
|
+
}
|
|
233
|
+
for (const img of imageBlocks) {
|
|
234
|
+
const block = {
|
|
235
|
+
type: 'input_image',
|
|
236
|
+
image_url: img.url
|
|
237
|
+
};
|
|
238
|
+
if (img.detail) {
|
|
239
|
+
block.detail = img.detail;
|
|
240
|
+
}
|
|
241
|
+
blocks.push(block);
|
|
242
|
+
}
|
|
243
|
+
if (blocks.length) {
|
|
244
|
+
const entry = {
|
|
245
|
+
role,
|
|
246
|
+
content: blocks
|
|
247
|
+
};
|
|
248
|
+
input.push(entry);
|
|
249
|
+
}
|
|
180
250
|
if (role === 'user') {
|
|
181
251
|
const trimmed = typeof text === 'string' ? text.trim() : '';
|
|
182
252
|
if (trimmed.length) {
|
|
@@ -260,6 +330,7 @@ function processMessageBlocks(blocks, normalizeFunctionName, tools, toolNameById
|
|
|
260
330
|
const toolMessages = [];
|
|
261
331
|
let currentLastCall = lastToolCallId;
|
|
262
332
|
const reasoningSegments = [];
|
|
333
|
+
const images = [];
|
|
263
334
|
for (const block of blocks) {
|
|
264
335
|
if (!block || typeof block !== 'object')
|
|
265
336
|
continue;
|
|
@@ -282,6 +353,18 @@ function processMessageBlocks(blocks, normalizeFunctionName, tools, toolNameById
|
|
|
282
353
|
toolMessages.push(tm);
|
|
283
354
|
currentLastCall = nested.lastCallId;
|
|
284
355
|
reasoningSegments.push(...nested.reasoningSegments);
|
|
356
|
+
if (nested.images.length)
|
|
357
|
+
images.push(...nested.images);
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
if (type === 'input_image') {
|
|
361
|
+
const url = typeof block.image_url === 'string' ? block.image_url.trim() : '';
|
|
362
|
+
if (url) {
|
|
363
|
+
const detail = typeof block.detail === 'string' && block.detail.trim()
|
|
364
|
+
? block.detail.trim()
|
|
365
|
+
: undefined;
|
|
366
|
+
images.push({ url, detail });
|
|
367
|
+
}
|
|
285
368
|
continue;
|
|
286
369
|
}
|
|
287
370
|
if (type === 'function_call') {
|
|
@@ -344,7 +427,7 @@ function processMessageBlocks(blocks, normalizeFunctionName, tools, toolNameById
|
|
|
344
427
|
}
|
|
345
428
|
}
|
|
346
429
|
const text = textParts.length ? textParts.join('\n').trim() : null;
|
|
347
|
-
return { text, toolCalls, toolMessages, lastCallId: currentLastCall, reasoningSegments };
|
|
430
|
+
return { text, images, toolCalls, toolMessages, lastCallId: currentLastCall, reasoningSegments };
|
|
348
431
|
}
|
|
349
432
|
export function convertBridgeInputToChatMessages(options) {
|
|
350
433
|
const { input, tools, normalizeFunctionName, toolResultFallbackText } = options;
|
|
@@ -470,7 +553,29 @@ export function convertBridgeInputToChatMessages(options) {
|
|
|
470
553
|
for (const msg of nested.toolMessages)
|
|
471
554
|
messages.push(msg);
|
|
472
555
|
const normalizedRole = coerceBridgeRole((explicit.role ?? entry.role) || 'user');
|
|
473
|
-
if (
|
|
556
|
+
if (nested.images.length) {
|
|
557
|
+
const contentBlocks = [];
|
|
558
|
+
if (typeof nested.text === 'string' && nested.text.trim().length) {
|
|
559
|
+
contentBlocks.push({ type: 'text', text: nested.text });
|
|
560
|
+
}
|
|
561
|
+
for (const img of nested.images) {
|
|
562
|
+
const imgBlock = { type: 'image_url', image_url: { url: img.url } };
|
|
563
|
+
if (img.detail) {
|
|
564
|
+
imgBlock.image_url.detail = img.detail;
|
|
565
|
+
}
|
|
566
|
+
contentBlocks.push(imgBlock);
|
|
567
|
+
}
|
|
568
|
+
const msg = {
|
|
569
|
+
role: normalizedRole,
|
|
570
|
+
content: contentBlocks
|
|
571
|
+
};
|
|
572
|
+
const combinedReasoning = combineReasoningSegments(consumeEntryReasoning(), nested.reasoningSegments);
|
|
573
|
+
if (combinedReasoning.length) {
|
|
574
|
+
msg.reasoning_content = combinedReasoning.join('\n');
|
|
575
|
+
}
|
|
576
|
+
messages.push(msg);
|
|
577
|
+
}
|
|
578
|
+
else if (typeof nested.text === 'string') {
|
|
474
579
|
pushNormalizedChatMessage(messages, normalizedRole, nested.text, {
|
|
475
580
|
reasoningSegments: combineReasoningSegments(consumeEntryReasoning(), nested.reasoningSegments)
|
|
476
581
|
});
|
|
@@ -491,9 +596,31 @@ export function convertBridgeInputToChatMessages(options) {
|
|
|
491
596
|
for (const msg of nested.toolMessages)
|
|
492
597
|
messages.push(msg);
|
|
493
598
|
const normalizedRole = coerceBridgeRole(entry.role || 'user');
|
|
494
|
-
if (
|
|
599
|
+
if (nested.images.length) {
|
|
600
|
+
const contentBlocks = [];
|
|
601
|
+
if (typeof nested.text === 'string' && nested.text.trim().length) {
|
|
602
|
+
contentBlocks.push({ type: 'text', text: nested.text });
|
|
603
|
+
}
|
|
604
|
+
for (const img of nested.images) {
|
|
605
|
+
const imgBlock = { type: 'image_url', image_url: { url: img.url } };
|
|
606
|
+
if (img.detail) {
|
|
607
|
+
imgBlock.image_url.detail = img.detail;
|
|
608
|
+
}
|
|
609
|
+
contentBlocks.push(imgBlock);
|
|
610
|
+
}
|
|
611
|
+
const msg = {
|
|
612
|
+
role: normalizedRole,
|
|
613
|
+
content: contentBlocks
|
|
614
|
+
};
|
|
615
|
+
const combinedReasoning = combineReasoningSegments(consumeEntryReasoning(), nested.reasoningSegments);
|
|
616
|
+
if (combinedReasoning.length) {
|
|
617
|
+
msg.reasoning_content = combinedReasoning.join('\n');
|
|
618
|
+
}
|
|
619
|
+
messages.push(msg);
|
|
620
|
+
}
|
|
621
|
+
else if (typeof nested.text === 'string') {
|
|
495
622
|
pushNormalizedChatMessage(messages, normalizedRole, nested.text, {
|
|
496
|
-
reasoningSegments:
|
|
623
|
+
reasoningSegments: consumeEntryReasoning()
|
|
497
624
|
});
|
|
498
625
|
}
|
|
499
626
|
lastToolCallId = nested.lastCallId;
|
|
@@ -1,6 +1,41 @@
|
|
|
1
1
|
import { normalizeFunctionCallId } from './bridge-id-utils.js';
|
|
2
2
|
import { normalizeContentPart } from './output-content-normalizer.js';
|
|
3
3
|
import { expandResponsesMessageItem } from '../../sse/shared/responses-output-normalizer.js';
|
|
4
|
+
function buildToolOutputIndex(response) {
|
|
5
|
+
const ids = new Set();
|
|
6
|
+
try {
|
|
7
|
+
const primary = Array.isArray(response.tool_outputs)
|
|
8
|
+
? response.tool_outputs
|
|
9
|
+
: [];
|
|
10
|
+
for (const entry of primary) {
|
|
11
|
+
if (!entry || typeof entry !== 'object')
|
|
12
|
+
continue;
|
|
13
|
+
const raw = entry.tool_call_id ||
|
|
14
|
+
entry.call_id ||
|
|
15
|
+
entry.id;
|
|
16
|
+
if (typeof raw === 'string' && raw.trim().length) {
|
|
17
|
+
const trimmed = raw.trim();
|
|
18
|
+
// 记录原始 ID(例如 OpenAI 的 toolu_ 前缀),以兼容直接使用
|
|
19
|
+
// tool_call_id 的客户端;同时记录归一化后的 fc_ 形式,保证与
|
|
20
|
+
// buildFunctionCallOutput 中 normalizeFunctionCallId 的结果对齐。
|
|
21
|
+
ids.add(trimmed);
|
|
22
|
+
try {
|
|
23
|
+
const normalized = normalizeFunctionCallId({ callId: trimmed, fallback: trimmed });
|
|
24
|
+
if (normalized && normalized !== trimmed) {
|
|
25
|
+
ids.add(normalized);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// 归一化失败不应影响主流程
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// best-effort: 不因索引构建失败影响主流程
|
|
36
|
+
}
|
|
37
|
+
return ids;
|
|
38
|
+
}
|
|
4
39
|
function appendReasoningSegments(target, raw) {
|
|
5
40
|
if (typeof raw !== 'string' || !raw.length) {
|
|
6
41
|
return;
|
|
@@ -91,7 +126,13 @@ export function buildResponsesOutputFromChat(options) {
|
|
|
91
126
|
const usage = normalizeUsage(response.usage);
|
|
92
127
|
const outputTextMeta = response?.__responses_output_text_meta;
|
|
93
128
|
const outputText = resolveOutputText(convertedContent, outputTextMeta);
|
|
94
|
-
|
|
129
|
+
// 如果顶层 tool_outputs 已经为所有 tool_calls 提供了结果,说明这些函数调用
|
|
130
|
+
// 已在服务端(例如 server-side web_search)完成,不应再对客户端暴露
|
|
131
|
+
// required_action/submit_tool_outputs。此时只需返回 completed 状态即可,避免
|
|
132
|
+
// 再触发一轮工具回合。
|
|
133
|
+
const executedIds = buildToolOutputIndex(response);
|
|
134
|
+
const pendingToolCalls = normalizedToolCalls.filter((entry) => !executedIds.has(entry.id));
|
|
135
|
+
const hasNormalizedToolCalls = pendingToolCalls.length > 0;
|
|
95
136
|
if (hasNormalizedToolCalls) {
|
|
96
137
|
for (const item of outputItems) {
|
|
97
138
|
if (item.type === 'message') {
|
|
@@ -100,7 +141,7 @@ export function buildResponsesOutputFromChat(options) {
|
|
|
100
141
|
}
|
|
101
142
|
}
|
|
102
143
|
const requiredAction = hasNormalizedToolCalls
|
|
103
|
-
? buildRequiredActionFromNormalized(
|
|
144
|
+
? buildRequiredActionFromNormalized(pendingToolCalls)
|
|
104
145
|
: undefined;
|
|
105
146
|
const status = hasNormalizedToolCalls ? 'requires_action' : 'completed';
|
|
106
147
|
return {
|
package/node_modules/@jsonstudio/llms/dist/conversion/shared/responses-reasoning-registry.d.ts
CHANGED
|
@@ -6,3 +6,7 @@ export declare function registerResponsesReasoning(id: unknown, segments: string
|
|
|
6
6
|
export declare function consumeResponsesReasoning(id: unknown): string[] | undefined;
|
|
7
7
|
export declare function registerResponsesOutputTextMeta(id: unknown, meta: ResponsesOutputTextMeta | undefined): void;
|
|
8
8
|
export declare function consumeResponsesOutputTextMeta(id: unknown): ResponsesOutputTextMeta | undefined;
|
|
9
|
+
export declare function registerResponsesPayloadSnapshot(id: unknown, snapshot: Record<string, unknown> | undefined): void;
|
|
10
|
+
export declare function consumeResponsesPayloadSnapshot(id: unknown): Record<string, unknown> | undefined;
|
|
11
|
+
export declare function registerResponsesPassthrough(id: unknown, payload: Record<string, unknown> | undefined): void;
|
|
12
|
+
export declare function consumeResponsesPassthrough(id: unknown): Record<string, unknown> | undefined;
|
package/node_modules/@jsonstudio/llms/dist/conversion/shared/responses-reasoning-registry.js
CHANGED
|
@@ -11,10 +11,27 @@ function pruneEntry(id) {
|
|
|
11
11
|
const entry = registry.get(id);
|
|
12
12
|
if (!entry)
|
|
13
13
|
return;
|
|
14
|
-
if (!entry.reasoning && !entry.outputText) {
|
|
14
|
+
if (!entry.reasoning && !entry.outputText && !entry.payloadSnapshot && !entry.passthroughPayload) {
|
|
15
15
|
registry.delete(id);
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
+
function cloneSnapshot(snapshot) {
|
|
19
|
+
try {
|
|
20
|
+
const structuredCloneImpl = globalThis.structuredClone;
|
|
21
|
+
if (typeof structuredCloneImpl === 'function') {
|
|
22
|
+
return structuredCloneImpl(snapshot);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
/* ignore structuredClone failures */
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
return JSON.parse(JSON.stringify(snapshot));
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
18
35
|
export function registerResponsesReasoning(id, segments) {
|
|
19
36
|
if (typeof id !== 'string')
|
|
20
37
|
return;
|
|
@@ -59,3 +76,47 @@ export function consumeResponsesOutputTextMeta(id) {
|
|
|
59
76
|
pruneEntry(id);
|
|
60
77
|
return value;
|
|
61
78
|
}
|
|
79
|
+
export function registerResponsesPayloadSnapshot(id, snapshot) {
|
|
80
|
+
if (typeof id !== 'string')
|
|
81
|
+
return;
|
|
82
|
+
if (!snapshot || typeof snapshot !== 'object')
|
|
83
|
+
return;
|
|
84
|
+
const clone = cloneSnapshot(snapshot);
|
|
85
|
+
if (!clone)
|
|
86
|
+
return;
|
|
87
|
+
const entry = ensureEntry(id);
|
|
88
|
+
entry.payloadSnapshot = clone;
|
|
89
|
+
}
|
|
90
|
+
export function consumeResponsesPayloadSnapshot(id) {
|
|
91
|
+
if (typeof id !== 'string')
|
|
92
|
+
return undefined;
|
|
93
|
+
const entry = registry.get(id);
|
|
94
|
+
if (!entry?.payloadSnapshot)
|
|
95
|
+
return undefined;
|
|
96
|
+
const clone = cloneSnapshot(entry.payloadSnapshot) ?? entry.payloadSnapshot;
|
|
97
|
+
entry.payloadSnapshot = undefined;
|
|
98
|
+
pruneEntry(id);
|
|
99
|
+
return clone;
|
|
100
|
+
}
|
|
101
|
+
export function registerResponsesPassthrough(id, payload) {
|
|
102
|
+
if (typeof id !== 'string')
|
|
103
|
+
return;
|
|
104
|
+
if (!payload || typeof payload !== 'object')
|
|
105
|
+
return;
|
|
106
|
+
const clone = cloneSnapshot(payload);
|
|
107
|
+
if (!clone)
|
|
108
|
+
return;
|
|
109
|
+
const entry = ensureEntry(id);
|
|
110
|
+
entry.passthroughPayload = clone;
|
|
111
|
+
}
|
|
112
|
+
export function consumeResponsesPassthrough(id) {
|
|
113
|
+
if (typeof id !== 'string')
|
|
114
|
+
return undefined;
|
|
115
|
+
const entry = registry.get(id);
|
|
116
|
+
if (!entry?.passthroughPayload)
|
|
117
|
+
return undefined;
|
|
118
|
+
const clone = cloneSnapshot(entry.passthroughPayload) ?? entry.passthroughPayload;
|
|
119
|
+
entry.passthroughPayload = undefined;
|
|
120
|
+
pruneEntry(id);
|
|
121
|
+
return clone;
|
|
122
|
+
}
|
|
@@ -4,6 +4,7 @@ import { extractOutputSegments } from './output-content-normalizer.js';
|
|
|
4
4
|
import { sanitizeReasoningTaggedText } from './reasoning-utils.js';
|
|
5
5
|
import { createBridgeActionState, runBridgeActionPipeline } from './bridge-actions.js';
|
|
6
6
|
import { resolveBridgePolicy, resolvePolicyActions } from './bridge-policies.js';
|
|
7
|
+
import { registerResponsesPayloadSnapshot, registerResponsesPassthrough } from './responses-reasoning-registry.js';
|
|
7
8
|
function selectCallId(entry) {
|
|
8
9
|
const candidates = [
|
|
9
10
|
entry?.call_id,
|
|
@@ -153,13 +154,27 @@ function collectRawReasoningSegments(response) {
|
|
|
153
154
|
}
|
|
154
155
|
return segments;
|
|
155
156
|
}
|
|
157
|
+
function registerPassthroughSnapshot(payload) {
|
|
158
|
+
const ids = new Set();
|
|
159
|
+
const requestId = typeof payload?.request_id === 'string' ? payload.request_id.trim() : '';
|
|
160
|
+
const id = typeof payload?.id === 'string' ? payload.id.trim() : '';
|
|
161
|
+
if (requestId.length)
|
|
162
|
+
ids.add(requestId);
|
|
163
|
+
if (id.length)
|
|
164
|
+
ids.add(id);
|
|
165
|
+
for (const candidate of ids) {
|
|
166
|
+
registerResponsesPassthrough(candidate, payload);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
156
169
|
export function buildChatResponseFromResponses(payload) {
|
|
157
170
|
if (!payload || typeof payload !== 'object')
|
|
158
171
|
return payload;
|
|
159
172
|
const response = unwrapResponsesResponse(payload);
|
|
160
173
|
if (!response) {
|
|
161
|
-
if (Array.isArray(payload.choices))
|
|
174
|
+
if (Array.isArray(payload.choices)) {
|
|
175
|
+
registerPassthroughSnapshot(payload);
|
|
162
176
|
return payload;
|
|
177
|
+
}
|
|
163
178
|
return payload;
|
|
164
179
|
}
|
|
165
180
|
const id = typeof response.id === 'string' ? response.id : `resp_${Date.now()}`;
|
|
@@ -235,5 +250,12 @@ export function buildChatResponseFromResponses(payload) {
|
|
|
235
250
|
if (usage !== undefined) {
|
|
236
251
|
chat.usage = usage;
|
|
237
252
|
}
|
|
253
|
+
const requestId = typeof response.request_id === 'string'
|
|
254
|
+
? response.request_id
|
|
255
|
+
: (typeof response.id === 'string' ? response.id : undefined);
|
|
256
|
+
if (requestId) {
|
|
257
|
+
chat.request_id = requestId;
|
|
258
|
+
}
|
|
259
|
+
registerResponsesPayloadSnapshot(id, response);
|
|
238
260
|
return chat;
|
|
239
261
|
}
|
|
@@ -1,35 +1,25 @@
|
|
|
1
|
-
import os from 'node:os';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import fs from 'node:fs/promises';
|
|
4
1
|
import { writeSnapshotViaHooks } from './snapshot-hooks.js';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
return hint;
|
|
9
|
-
const ep = String(endpoint || '').toLowerCase();
|
|
10
|
-
if (ep.includes('/responses'))
|
|
11
|
-
return 'openai-responses';
|
|
12
|
-
if (ep.includes('/messages'))
|
|
13
|
-
return 'anthropic-messages';
|
|
14
|
-
if (ep.includes('/gemini'))
|
|
15
|
-
return 'gemini-chat';
|
|
16
|
-
return 'openai-chat';
|
|
17
|
-
}
|
|
18
|
-
async function ensureDir(dir) {
|
|
19
|
-
try {
|
|
20
|
-
await fs.mkdir(dir, { recursive: true });
|
|
2
|
+
function resolveBoolFromEnv(value, fallback) {
|
|
3
|
+
if (!value) {
|
|
4
|
+
return fallback;
|
|
21
5
|
}
|
|
22
|
-
|
|
23
|
-
|
|
6
|
+
const normalized = value.trim().toLowerCase();
|
|
7
|
+
if (['1', 'true', 'yes', 'on'].includes(normalized)) {
|
|
8
|
+
return true;
|
|
24
9
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
10
|
+
if (['0', 'false', 'no', 'off'].includes(normalized)) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
return fallback;
|
|
28
14
|
}
|
|
29
15
|
export function shouldRecordSnapshots() {
|
|
30
|
-
const
|
|
31
|
-
if (
|
|
32
|
-
return
|
|
16
|
+
const hubFlag = process.env.ROUTECODEX_HUB_SNAPSHOTS;
|
|
17
|
+
if (hubFlag && hubFlag.trim().length) {
|
|
18
|
+
return resolveBoolFromEnv(hubFlag, true);
|
|
19
|
+
}
|
|
20
|
+
const sharedFlag = process.env.ROUTECODEX_SNAPSHOT ?? process.env.ROUTECODEX_SNAPSHOTS;
|
|
21
|
+
if (sharedFlag && sharedFlag.trim().length) {
|
|
22
|
+
return resolveBoolFromEnv(sharedFlag, true);
|
|
33
23
|
}
|
|
34
24
|
return true;
|
|
35
25
|
}
|
|
@@ -37,26 +27,6 @@ export async function recordSnapshot(options) {
|
|
|
37
27
|
if (!shouldRecordSnapshots())
|
|
38
28
|
return;
|
|
39
29
|
const endpoint = options.endpoint || '/v1/chat/completions';
|
|
40
|
-
const folder = mapEndpointToFolder(endpoint, options.folderHint);
|
|
41
|
-
const dir = path.join(SNAPSHOT_BASE, folder);
|
|
42
|
-
try {
|
|
43
|
-
await ensureDir(dir);
|
|
44
|
-
const safeStage = sanitize(options.stage);
|
|
45
|
-
const safeRequestId = sanitize(options.requestId);
|
|
46
|
-
const file = path.join(dir, `${safeRequestId}_${safeStage}.json`);
|
|
47
|
-
const payload = {
|
|
48
|
-
meta: {
|
|
49
|
-
stage: options.stage,
|
|
50
|
-
timestamp: Date.now(),
|
|
51
|
-
endpoint
|
|
52
|
-
},
|
|
53
|
-
body: options.data
|
|
54
|
-
};
|
|
55
|
-
await fs.writeFile(file, JSON.stringify(payload, null, 2), 'utf-8');
|
|
56
|
-
}
|
|
57
|
-
catch (error) {
|
|
58
|
-
console.warn('[snapshot-utils] failed to write snapshot', error);
|
|
59
|
-
}
|
|
60
30
|
void writeSnapshotViaHooks({
|
|
61
31
|
endpoint,
|
|
62
32
|
stage: options.stage,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { FilterEngine } from '../../filters/index.js';
|
|
2
2
|
import { loadFieldMapConfig } from '../../filters/utils/fieldmap-loader.js';
|
|
3
|
+
import { normalizeChatResponseReasoningTools } from './reasoning-tool-normalizer.js';
|
|
3
4
|
import { createSnapshotWriter } from './snapshot-utils.js';
|
|
4
5
|
const REQUEST_FILTER_STAGES = [
|
|
5
6
|
'request_pre',
|
|
@@ -110,6 +111,7 @@ function applyLocalToolGovernance(chatRequest, rawPayload) {
|
|
|
110
111
|
}
|
|
111
112
|
const hasImageHint = detectImageHint(messages, rawPayload);
|
|
112
113
|
if (hasImageHint) {
|
|
114
|
+
// 有图片线索时不干预工具列表,保持由上游(Codex 等)决定 view_image 的暴露与使用。
|
|
113
115
|
return chatRequest;
|
|
114
116
|
}
|
|
115
117
|
const filteredTools = tools.filter((tool) => {
|
|
@@ -191,6 +193,16 @@ export async function runChatResponseToolFilters(chatJson, options = {}) {
|
|
|
191
193
|
snapshot(stage, payload);
|
|
192
194
|
};
|
|
193
195
|
recordStage('resp_process_tool_filters_input', chatJson);
|
|
196
|
+
try {
|
|
197
|
+
if (chatJson && typeof chatJson === 'object') {
|
|
198
|
+
normalizeChatResponseReasoningTools(chatJson, {
|
|
199
|
+
idPrefixBase: 'reasoning_choice'
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
// best-effort; do not block response flow on reasoning parsing issues
|
|
205
|
+
}
|
|
194
206
|
const engine = new FilterEngine();
|
|
195
207
|
const registeredStages = new Set();
|
|
196
208
|
const register = (filter) => {
|