@jsonstudio/rcc 0.89.1205 → 0.89.1457
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 +53 -1412
- package/configsamples/config.json +426 -0
- package/configsamples/config.reference.json +58 -0
- package/configsamples/provider/crs/config.v1.json +46 -0
- package/configsamples/provider/glm/config.v1.json +81 -0
- package/configsamples/provider/glm-anthropic/config.v1.json +45 -0
- package/configsamples/provider/iflow/config.v1.json +74 -0
- package/configsamples/provider/kimi/config.v1.json +41 -0
- package/configsamples/provider/lmstudio/config.v1.json +101 -0
- package/configsamples/provider/mimo/config.v1.json +35 -0
- package/configsamples/provider/modelscope/config.v1.json +96 -0
- package/configsamples/provider/qwen/config.v1.json +38 -0
- package/configsamples/provider/tab/config.v1.json +50 -0
- package/configsamples/provider/tabglm/config.v1.json +49 -0
- package/dist/build-info.js +2 -2
- package/dist/cli/commands/code.js +12 -6
- package/dist/cli/commands/code.js.map +1 -1
- package/dist/cli/commands/config.d.ts +2 -1
- package/dist/cli/commands/config.js +77 -103
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/examples.js +6 -6
- package/dist/cli/commands/examples.js.map +1 -1
- package/dist/cli/commands/init.d.ts +28 -0
- package/dist/cli/commands/init.js +94 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/port.js +10 -2
- package/dist/cli/commands/port.js.map +1 -1
- package/dist/cli/commands/restart.js +5 -2
- package/dist/cli/commands/restart.js.map +1 -1
- package/dist/cli/commands/start.js +25 -22
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/commands/status.js +1 -0
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/stop.js +1 -0
- package/dist/cli/commands/stop.js.map +1 -1
- package/dist/cli/config/bundled-docs.d.ts +20 -0
- package/dist/cli/config/bundled-docs.js +91 -0
- package/dist/cli/config/bundled-docs.js.map +1 -0
- package/dist/cli/config/init-config.d.ts +37 -0
- package/dist/cli/config/init-config.js +212 -0
- package/dist/cli/config/init-config.js.map +1 -0
- package/dist/cli/config/init-provider-catalog.d.ts +8 -0
- package/dist/cli/config/init-provider-catalog.js +187 -0
- package/dist/cli/config/init-provider-catalog.js.map +1 -0
- package/dist/cli/register/init-command.d.ts +3 -0
- package/dist/cli/register/init-command.js +5 -0
- package/dist/cli/register/init-command.js.map +1 -0
- package/dist/cli.js +28 -3
- package/dist/cli.js.map +1 -1
- package/dist/client/gemini/gemini-protocol-client.js +2 -1
- package/dist/client/gemini/gemini-protocol-client.js.map +1 -1
- package/dist/client/gemini-cli/gemini-cli-protocol-client.js +40 -16
- package/dist/client/gemini-cli/gemini-cli-protocol-client.js.map +1 -1
- package/dist/client/openai/chat-protocol-client.js +2 -1
- package/dist/client/openai/chat-protocol-client.js.map +1 -1
- package/dist/client/responses/responses-protocol-client.js +2 -1
- package/dist/client/responses/responses-protocol-client.js.map +1 -1
- package/dist/config/risk-control-config.d.ts +94 -0
- package/dist/config/risk-control-config.js +196 -0
- package/dist/config/risk-control-config.js.map +1 -0
- package/dist/constants/index.d.ts +6 -0
- package/dist/constants/index.js +13 -0
- package/dist/constants/index.js.map +1 -1
- package/dist/docs/daemon-admin-ui.html +2113 -190
- package/dist/error-handling/quiet-error-handling-center.js +46 -8
- package/dist/error-handling/quiet-error-handling-center.js.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/manager/modules/health/index.d.ts +1 -1
- package/dist/manager/modules/quota/antigravity-quota-manager.d.ts +70 -0
- package/dist/manager/modules/quota/antigravity-quota-manager.js +442 -0
- package/dist/manager/modules/quota/antigravity-quota-manager.js.map +1 -0
- package/dist/manager/modules/quota/index.d.ts +3 -127
- package/dist/manager/modules/quota/index.js +2 -1093
- package/dist/manager/modules/quota/index.js.map +1 -1
- package/dist/manager/modules/quota/provider-key-normalization.d.ts +3 -0
- package/dist/manager/modules/quota/provider-key-normalization.js +155 -0
- package/dist/manager/modules/quota/provider-key-normalization.js.map +1 -0
- package/dist/manager/modules/quota/provider-quota-daemon.cooldown.d.ts +9 -0
- package/dist/manager/modules/quota/provider-quota-daemon.cooldown.js +115 -0
- package/dist/manager/modules/quota/provider-quota-daemon.cooldown.js.map +1 -0
- package/dist/manager/modules/quota/provider-quota-daemon.d.ts +77 -0
- package/dist/manager/modules/quota/provider-quota-daemon.events.d.ts +12 -0
- package/dist/manager/modules/quota/provider-quota-daemon.events.js +239 -0
- package/dist/manager/modules/quota/provider-quota-daemon.events.js.map +1 -0
- package/dist/manager/modules/quota/provider-quota-daemon.js +404 -0
- package/dist/manager/modules/quota/provider-quota-daemon.js.map +1 -0
- package/dist/manager/modules/quota/provider-quota-daemon.model-backoff.d.ts +11 -0
- package/dist/manager/modules/quota/provider-quota-daemon.model-backoff.js +192 -0
- package/dist/manager/modules/quota/provider-quota-daemon.model-backoff.js.map +1 -0
- package/dist/manager/modules/quota/provider-quota-daemon.snapshot.d.ts +8 -0
- package/dist/manager/modules/quota/provider-quota-daemon.snapshot.js +96 -0
- package/dist/manager/modules/quota/provider-quota-daemon.snapshot.js.map +1 -0
- package/dist/manager/modules/quota/provider-quota-daemon.view.d.ts +19 -0
- package/dist/manager/modules/quota/provider-quota-daemon.view.js +37 -0
- package/dist/manager/modules/quota/provider-quota-daemon.view.js.map +1 -0
- package/dist/manager/modules/routing/index.d.ts +1 -0
- package/dist/manager/modules/routing/index.js +11 -25
- package/dist/manager/modules/routing/index.js.map +1 -1
- package/dist/manager/quota/provider-quota-center.d.ts +2 -0
- package/dist/manager/quota/provider-quota-center.js +80 -82
- package/dist/manager/quota/provider-quota-center.js.map +1 -1
- package/dist/modules/llmswitch/bridge.d.ts +16 -18
- package/dist/modules/llmswitch/bridge.js +293 -94
- package/dist/modules/llmswitch/bridge.js.map +1 -1
- package/dist/modules/llmswitch/core-loader.d.ts +4 -2
- package/dist/modules/llmswitch/core-loader.js +32 -20
- package/dist/modules/llmswitch/core-loader.js.map +1 -1
- package/dist/modules/pipeline/utils/colored-logger.js +3 -2
- package/dist/modules/pipeline/utils/colored-logger.js.map +1 -1
- package/dist/modules/pipeline/utils/debug-logger.js +1 -1
- package/dist/modules/pipeline/utils/debug-logger.js.map +1 -1
- package/dist/providers/auth/antigravity-userinfo-helper.d.ts +2 -1
- package/dist/providers/auth/antigravity-userinfo-helper.js +25 -4
- package/dist/providers/auth/antigravity-userinfo-helper.js.map +1 -1
- package/dist/providers/auth/iflow-cookie-auth.js +0 -2
- package/dist/providers/auth/iflow-cookie-auth.js.map +1 -1
- package/dist/providers/auth/oauth-lifecycle.js +2 -23
- package/dist/providers/auth/oauth-lifecycle.js.map +1 -1
- package/dist/providers/auth/tokenfile-auth.d.ts +2 -0
- package/dist/providers/auth/tokenfile-auth.js +33 -1
- package/dist/providers/auth/tokenfile-auth.js.map +1 -1
- package/dist/providers/core/config/camoufox-launcher.d.ts +5 -0
- package/dist/providers/core/config/camoufox-launcher.js +40 -4
- package/dist/providers/core/config/camoufox-launcher.js.map +1 -1
- package/dist/providers/core/config/service-profiles.js +7 -18
- package/dist/providers/core/config/service-profiles.js.map +1 -1
- package/dist/providers/core/runtime/antigravity-quota-client.js +6 -3
- package/dist/providers/core/runtime/antigravity-quota-client.js.map +1 -1
- package/dist/providers/core/runtime/base-provider.d.ts +2 -7
- package/dist/providers/core/runtime/base-provider.js +84 -165
- package/dist/providers/core/runtime/base-provider.js.map +1 -1
- package/dist/providers/core/runtime/gemini-cli-http-provider.d.ts +7 -0
- package/dist/providers/core/runtime/gemini-cli-http-provider.js +368 -97
- package/dist/providers/core/runtime/gemini-cli-http-provider.js.map +1 -1
- package/dist/providers/core/runtime/http-request-executor.d.ts +3 -0
- package/dist/providers/core/runtime/http-request-executor.js +110 -38
- package/dist/providers/core/runtime/http-request-executor.js.map +1 -1
- package/dist/providers/core/runtime/http-transport-provider.d.ts +17 -0
- package/dist/providers/core/runtime/http-transport-provider.js +165 -16
- package/dist/providers/core/runtime/http-transport-provider.js.map +1 -1
- package/dist/providers/core/runtime/provider-error-classifier.js +10 -0
- package/dist/providers/core/runtime/provider-error-classifier.js.map +1 -1
- package/dist/providers/core/runtime/provider-factory.js +7 -5
- package/dist/providers/core/runtime/provider-factory.js.map +1 -1
- package/dist/providers/core/runtime/provider-runtime-metadata.d.ts +6 -0
- package/dist/providers/core/runtime/provider-runtime-metadata.js.map +1 -1
- package/dist/providers/core/runtime/rate-limit-manager.d.ts +1 -12
- package/dist/providers/core/runtime/rate-limit-manager.js +4 -77
- package/dist/providers/core/runtime/rate-limit-manager.js.map +1 -1
- package/dist/providers/core/runtime/responses-provider.d.ts +1 -7
- package/dist/providers/core/runtime/responses-provider.js +12 -93
- package/dist/providers/core/runtime/responses-provider.js.map +1 -1
- package/dist/providers/core/strategies/oauth-auth-code-flow.js +12 -8
- package/dist/providers/core/strategies/oauth-auth-code-flow.js.map +1 -1
- package/dist/providers/core/utils/http-client.js +36 -46
- package/dist/providers/core/utils/http-client.js.map +1 -1
- package/dist/providers/core/utils/provider-error-logger.d.ts +1 -1
- package/dist/providers/core/utils/provider-error-reporter.d.ts +3 -1
- package/dist/providers/core/utils/provider-error-reporter.js +3 -0
- package/dist/providers/core/utils/provider-error-reporter.js.map +1 -1
- package/dist/providers/core/utils/snapshot-writer.js +1 -4
- package/dist/providers/core/utils/snapshot-writer.js.map +1 -1
- package/dist/providers/mock/mock-provider-runtime.js +57 -27
- package/dist/providers/mock/mock-provider-runtime.js.map +1 -1
- package/dist/scripts/camoufox/launch-auth.mjs +193 -58
- package/dist/server/handlers/handler-utils.js +8 -3
- package/dist/server/handlers/handler-utils.js.map +1 -1
- package/dist/server/handlers/responses-handler.js +1 -1
- package/dist/server/handlers/responses-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/auth-handler.d.ts +2 -0
- package/dist/server/runtime/http-server/daemon-admin/auth-handler.js +103 -0
- package/dist/server/runtime/http-server/daemon-admin/auth-handler.js.map +1 -0
- package/dist/server/runtime/http-server/daemon-admin/auth-session.d.ts +5 -0
- package/dist/server/runtime/http-server/daemon-admin/auth-session.js +77 -0
- package/dist/server/runtime/http-server/daemon-admin/auth-session.js.map +1 -0
- package/dist/server/runtime/http-server/daemon-admin/auth-store.d.ts +18 -0
- package/dist/server/runtime/http-server/daemon-admin/auth-store.js +89 -0
- package/dist/server/runtime/http-server/daemon-admin/auth-store.js.map +1 -0
- package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js +1 -2
- package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/providers-handler.js +226 -24
- package/dist/server/runtime/http-server/daemon-admin/providers-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/quota-handler.js +47 -8
- package/dist/server/runtime/http-server/daemon-admin/quota-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/restart-handler.js +1 -1
- package/dist/server/runtime/http-server/daemon-admin/restart-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/stats-handler.js +1 -1
- package/dist/server/runtime/http-server/daemon-admin/stats-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/status-handler.js +68 -4
- package/dist/server/runtime/http-server/daemon-admin/status-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin-routes.d.ts +3 -4
- package/dist/server/runtime/http-server/daemon-admin-routes.js +9 -14
- package/dist/server/runtime/http-server/daemon-admin-routes.js.map +1 -1
- package/dist/server/runtime/http-server/executor-metadata.js +1 -1
- package/dist/server/runtime/http-server/executor-metadata.js.map +1 -1
- package/dist/server/runtime/http-server/executor-response.js +0 -16
- package/dist/server/runtime/http-server/executor-response.js.map +1 -1
- package/dist/server/runtime/http-server/hub-shadow-compare.js +110 -34
- package/dist/server/runtime/http-server/hub-shadow-compare.js.map +1 -1
- package/dist/server/runtime/http-server/index.d.ts +5 -3
- package/dist/server/runtime/http-server/index.js +281 -136
- package/dist/server/runtime/http-server/index.js.map +1 -1
- package/dist/server/runtime/http-server/middleware.js +19 -1
- package/dist/server/runtime/http-server/middleware.js.map +1 -1
- package/dist/server/runtime/http-server/request-executor.js +59 -24
- package/dist/server/runtime/http-server/request-executor.js.map +1 -1
- package/dist/server/runtime/http-server/routes.js +12 -3
- package/dist/server/runtime/http-server/routes.js.map +1 -1
- package/dist/server/runtime/http-server/session-dir.d.ts +2 -0
- package/dist/server/runtime/http-server/session-dir.js +59 -0
- package/dist/server/runtime/http-server/session-dir.js.map +1 -0
- package/dist/server/runtime/http-server/types.d.ts +0 -4
- package/dist/server/utils/utf8-chunk-buffer.js +6 -3
- package/dist/server/utils/utf8-chunk-buffer.js.map +1 -1
- package/dist/server/utils/warmup-storm-tracker.js +1 -1
- package/dist/server/utils/warmup-storm-tracker.js.map +1 -1
- package/dist/server-factory.d.ts +6 -28
- package/dist/server-factory.js +8 -93
- package/dist/server-factory.js.map +1 -1
- package/dist/token-daemon/index.js +2 -2
- package/dist/token-daemon/index.js.map +1 -1
- package/dist/token-daemon/provider-registry.js +0 -1
- package/dist/token-daemon/provider-registry.js.map +1 -1
- package/dist/token-daemon/server-utils.js +8 -9
- package/dist/token-daemon/server-utils.js.map +1 -1
- package/dist/token-daemon/token-utils.js +1 -1
- package/dist/token-daemon/token-utils.js.map +1 -1
- package/dist/tools/semantic-replay.js +2 -2
- package/dist/tools/semantic-replay.js.map +1 -1
- package/dist/tools/stats-request-events.d.ts +1 -1
- package/dist/tools/stats-usage.js +6 -3
- package/dist/tools/stats-usage.js.map +1 -1
- package/dist/utils/llms-engine-shadow.d.ts +19 -0
- package/dist/utils/llms-engine-shadow.js +209 -0
- package/dist/utils/llms-engine-shadow.js.map +1 -0
- package/dist/utils/runtime-versions.js +2 -1
- package/dist/utils/runtime-versions.js.map +1 -1
- package/dist/utils/strip-internal-keys.d.ts +12 -0
- package/dist/utils/strip-internal-keys.js +28 -0
- package/dist/utils/strip-internal-keys.js.map +1 -0
- package/docs/ARCHITECTURE.md +402 -0
- package/docs/CHAT_PROCESS_PROTOCOL_AND_PIPELINE.md +221 -0
- package/docs/CODEX_AND_CLAUDE_CODE.md +69 -0
- package/docs/CONFIG_ARCHITECTURE.md +517 -0
- package/docs/ERROR_HANDLING_AUDIT.md +0 -0
- package/docs/GCLI2API_PARITY_GAPS.md +98 -0
- package/docs/INSTALLATION_AND_QUICKSTART.md +74 -0
- package/docs/INSTRUCTION_MARKUP.md +89 -0
- package/docs/MODULE_ENHANCEMENT_SYSTEM.md +666 -0
- package/docs/PORTS.md +36 -0
- package/docs/PROVIDERS_BUILTIN.md +111 -0
- package/docs/PROVIDER_TYPES.md +55 -0
- package/docs/SERVERTOOL_CLOCK_DESIGN.md +233 -0
- package/docs/USAGE_HANDLING_ANALYSIS.md +335 -0
- package/docs/USER_CONFIG_PARSER_CHANGES.md +175 -0
- package/docs/V3_INBOUND_OUTBOUND_DESIGN.md +86 -0
- package/docs/VIRTUAL_ROUTER_PRIORITY_AND_HEALTH.md +125 -0
- package/docs/anthropic-request-golden-samples.md +50 -0
- package/docs/antigravity-gemini-format-cleanup.md +102 -0
- package/docs/antigravity-routing-contract.md +31 -0
- package/docs/ccr-alignment-enhancetool.md +105 -0
- package/docs/chat-glm-500-analysis.md +79 -0
- package/docs/chat-request-golden-samples.md +42 -0
- package/docs/chat-semantic-expansion-plan.md +84 -0
- package/docs/cli-command-inventory.md +76 -0
- package/docs/codex-samples-replay.md +50 -0
- package/docs/daemon-admin-api-design.md +350 -0
- package/docs/daemon-admin-module-structure.md +169 -0
- package/docs/daemon-admin-ui.html +3394 -0
- package/docs/debug-system-design.md +734 -0
- package/docs/debugging/gemini-sse-root-cause.md +52 -0
- package/docs/debugging/sse_encoding_failure_analysis.md +53 -0
- package/docs/dry-run/README.md +721 -0
- package/docs/error-handling-v2.md +92 -0
- package/docs/exec-command-guard-policy.example.v1.json +42 -0
- package/docs/fixes/gemini-protocol-mapping.md +57 -0
- package/docs/fixes/oauth-portal-timing-fix.md +202 -0
- package/docs/fixes/web-search-hop3-fix.md +265 -0
- package/docs/glm-api-reference.md +390 -0
- package/docs/glm-chat-completions.md +1779 -0
- package/docs/glm-history-inline-images.md +44 -0
- package/docs/golden-ci-library.md +66 -0
- package/docs/lmstudio-dry-run-summary.md +203 -0
- package/docs/lmstudio-tool-calling.md +214 -0
- package/docs/mapping-tables/anthropic-to-openai.json +290 -0
- package/docs/mapping-tables/iflow-to-openai.json +215 -0
- package/docs/mapping-tables/openai-passthrough.json +190 -0
- package/docs/mapping-tables/openai-to-iflow.json +227 -0
- package/docs/monitoring/Design.md +61 -0
- package/docs/multi-token-auth-guide.md +66 -0
- package/docs/oauth-authentication-guide.md +168 -0
- package/docs/oauth-iflow-implementation.md +153 -0
- package/docs/pipeline-routing-report.md +209 -0
- package/docs/plans/manager-daemon/PLAN.md +86 -0
- package/docs/plans/provider-config-v2-plan.md +176 -0
- package/docs/plans/provider-runtime-manager-plan.md +209 -0
- package/docs/plans/transparent-429-failover.md +89 -0
- package/docs/plans/unified-hub-framework-v1.md +245 -0
- package/docs/provider-config-v2-ui-design.md +181 -0
- package/docs/provider-quota-design.md +129 -0
- package/docs/providers/gemini-provider.md +62 -0
- package/docs/providers/lmstudio-v2-migration-report.md +102 -0
- package/docs/providers/provider-composite-design.md +142 -0
- package/docs/providers/provider-composite-testing.md +98 -0
- package/docs/providers/provider-type-only-migration.md +111 -0
- package/docs/rccx-wasm-migration.md +74 -0
- package/docs/refactoring/architecture-comparison-diagram.md +140 -0
- package/docs/refactoring/compatibility-v2-architecture-design.md +738 -0
- package/docs/refactoring/workflow-compatibility-refactoring-design.md +361 -0
- package/docs/reports/routing-classification-report.json +24 -0
- package/docs/reports/routing-classification-report.md +18 -0
- package/docs/reports/thinking-keywords-report.json +19 -0
- package/docs/responses/README.md +156 -0
- package/docs/responses-generic-provider.md +86 -0
- package/docs/responses-passthrough-provider-design.md +202 -0
- package/docs/routing-awrr-health-weighted-round-robin.md +179 -0
- package/docs/routing-instructions.md +393 -0
- package/docs/servertool-framework.md +65 -0
- package/docs/stop-message-auto.md +225 -0
- package/docs/streaming-flow.html +30 -0
- package/docs/streaming-flow.md +182 -0
- package/docs/token-daemon-preview.html +490 -0
- package/docs/token-refresh-daemon-plan.md +269 -0
- package/docs/transformation-tables/Gemini-FinishReason/345/256/214/346/225/264/350/275/254/346/215/242/350/241/250.json +233 -0
- package/docs/transformation-tables/README.md +225 -0
- package/docs/transformation-tables/claude-code-router-anthropic-to-gemini.json +283 -0
- package/docs/transformation-tables/claude-code-router-anthropic-to-openai.json +208 -0
- package/docs/transformation-tables/claude-code-router-openai-to-anthropic.json +261 -0
- package/docs/transformation-tables/claude-code-router-openai-to-gemini.json +208 -0
- package/docs/transformation-tables/claude-code-router-openai-to-lmstudio.json +182 -0
- package/docs/transformation-tables/claude-code-router-openai-to-ollama.json +250 -0
- package/docs/transformation-tables/claude-code-router-openai-to-textgenwebui.json +295 -0
- package/docs/transformation-tables/claude-code-router-provider-conversions.json +193 -0
- package/docs/transformation-tables//345/256/214/346/225/264/347/232/204/345/267/245/345/205/267/346/211/247/350/241/214/346/265/201/347/250/213/350/275/254/346/215/242/350/241/250.json +299 -0
- package/docs/transformation-tables//345/257/271/350/257/235/345/216/206/345/217/262/347/273/264/346/212/244/345/210/206/346/236/220.md +134 -0
- package/docs/transformation-tables//345/267/245/345/205/267/350/260/203/347/224/250/346/250/241/345/274/217/345/210/206/346/236/220.md +158 -0
- package/docs/transformation-tables//347/212/266/346/200/201/347/256/241/347/220/206/351/234/200/346/261/202/345/210/206/346/236/220.md +175 -0
- package/docs/transformation-tables//351/235/231/346/200/201/350/241/250vs/345/212/250/346/200/201/345/210/206/346/236/220.md +189 -0
- package/docs/transformation-tables//351/235/231/346/200/201/350/241/250/345/207/206/347/241/256/346/200/247/350/257/204/344/274/260.md +179 -0
- package/docs/transformation-tables//351/235/236/346/265/201/345/274/217/345/234/272/346/231/257/345/210/206/346/236/220.md +189 -0
- package/docs/v2-architecture/IMPLEMENTATION-ROADMAP.md +367 -0
- package/docs/v2-architecture/OPTIMIZED-DESIGN.md +827 -0
- package/docs/v2-architecture/PRERUN-CONNECTION-DESIGN.md +716 -0
- package/docs/v2-architecture/README.md +549 -0
- package/docs/verification/modelscope-verify.md +59 -0
- package/docs/verified-configs/README.md +60 -0
- package/docs/verified-configs/v0.45.0/README.md +244 -0
- package/docs/verified-configs/v0.45.0/lmstudio-5521-gpt-oss-20b-mlx.json +135 -0
- package/docs/verified-configs/v0.45.0/merged-config.5521.json +1205 -0
- package/docs/verified-configs/v0.45.0/merged-config.qwen-5522.json +1559 -0
- package/docs/verified-configs/v0.45.0/qwen-5522-qwen3-coder-plus-final.json +221 -0
- package/docs/verified-configs/v0.45.0/qwen-5522-qwen3-coder-plus-fixed.json +242 -0
- package/docs/verified-configs/v0.45.0/qwen-5522-qwen3-coder-plus.json +242 -0
- package/docs/web-search-service-design.md +322 -0
- package/package.json +26 -15
- package/scripts/build-core.mjs +3 -1
- package/scripts/camoufox/launch-auth.mjs +193 -58
- package/scripts/ci/repo-sanity.mjs +138 -0
- package/scripts/mock-provider/run-regressions.mjs +157 -1
- package/scripts/monitor-diff.mjs +126 -0
- package/scripts/pack-mode.mjs +19 -1
- package/scripts/pack-rcc.mjs +63 -0
- package/scripts/run-bg.sh +0 -14
- package/scripts/tests/ci-jest.mjs +119 -0
- package/scripts/tools-dev/responses-debug-client/README.md +23 -0
- package/scripts/tools-dev/responses-debug-client/payloads/poem.json +13 -0
- package/scripts/tools-dev/responses-debug-client/payloads/sample-no-tools.json +98 -0
- package/scripts/tools-dev/responses-debug-client/payloads/text.json +13 -0
- package/scripts/tools-dev/responses-debug-client/payloads/tool.json +27 -0
- package/scripts/tools-dev/responses-debug-client/run.mjs +65 -0
- package/scripts/tools-dev/responses-debug-client/src/index.ts +281 -0
- package/scripts/tools-dev/run-llmswitch-chat.mjs +53 -0
- package/scripts/tools-dev/server-tools-dev/run-web-fetch.mjs +65 -0
- package/scripts/unified-hub-shadow-compare.mjs +33 -13
- package/scripts/vendor-core.mjs +13 -3
- package/scripts/verify-e2e-toolcall.mjs +115 -26
- package/dist/modules/llmswitch/pipeline-registry.d.ts +0 -57
- package/dist/modules/llmswitch/pipeline-registry.js +0 -229
- package/dist/modules/llmswitch/pipeline-registry.js.map +0 -1
- package/dist/server/RouteCodexServer.d.ts +0 -13
- package/dist/server/RouteCodexServer.js +0 -25
- package/dist/server/RouteCodexServer.js.map +0 -1
- package/dist/v2/conversion/hub/snapshot-recorder.d.ts +0 -12
- package/dist/v2/conversion/hub/snapshot-recorder.js +0 -22
- package/dist/v2/conversion/hub/snapshot-recorder.js.map +0 -1
- package/scripts/test-fc-responses.mjs +0 -66
- package/scripts/test-guidance.mjs +0 -100
- package/scripts/test-iflow-web-search.mjs +0 -141
- package/scripts/test-iflow.mjs +0 -379
- package/scripts/test-tool-exec.mjs +0 -26
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Virtual Router: Priority + Health-Weighted Selection
|
|
2
|
+
|
|
3
|
+
This document describes how RouteCodex/llmswitch-core selects a `providerKey` from a route pool, with emphasis on:
|
|
4
|
+
|
|
5
|
+
- `mode: "priority"` pools (strict priority, failover only when needed)
|
|
6
|
+
- `mode: "round-robin"` pools (health-weighted AWRR)
|
|
7
|
+
- How quota/health signals affect selection order and weights
|
|
8
|
+
|
|
9
|
+
## Terms
|
|
10
|
+
|
|
11
|
+
- **providerKey**: `providerId.<keyAlias>.<modelId>` (example: `antigravity.gbplasu1.claude-sonnet-4-5-thinking`)
|
|
12
|
+
- **pool**: A `RoutePoolTier` (`routing.<routeName>[]`), containing `targets` and a `mode`
|
|
13
|
+
- **quotaView**: Host-injected view (`ProviderQuotaView`) that provides:
|
|
14
|
+
- `inPool`, `cooldownUntil`, `blacklistUntil`
|
|
15
|
+
- `priorityTier` (static)
|
|
16
|
+
- `selectionPenalty`, `lastErrorAtMs`, `consecutiveErrorCount` (soft health signals)
|
|
17
|
+
|
|
18
|
+
## Priority Pools (`mode: "priority"`)
|
|
19
|
+
|
|
20
|
+
Goal: always use the highest-priority candidate first, and only fall back when the current best becomes unavailable.
|
|
21
|
+
|
|
22
|
+
### Base priority (config order)
|
|
23
|
+
|
|
24
|
+
When targets do not carry explicit per-target priority metadata at runtime, the router derives a deterministic base score from the target list ordering:
|
|
25
|
+
|
|
26
|
+
- Treat each contiguous `(providerId, modelId)` block in `tier.targets` as a **target group**
|
|
27
|
+
- This matches how `bootstrapVirtualRouterConfig()` expands a single routing entry into multiple auth aliases
|
|
28
|
+
- Group base scores: `100, 90, 80, ...` (step `10`) by appearance order
|
|
29
|
+
- Inside a group (different aliases for the same provider+model), alias scores: `100, 99, 98, ...` (step `1`)
|
|
30
|
+
|
|
31
|
+
This makes it difficult for a single transient failure to instantly flip priority to the next target, while still allowing repeated errors to degrade a key.
|
|
32
|
+
|
|
33
|
+
### Error priority penalty (soft)
|
|
34
|
+
|
|
35
|
+
If `quotaView` provides `selectionPenalty` for a key, priority selection subtracts it from the derived base score:
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
effectivePriority = basePriority - selectionPenalty
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`selectionPenalty` is produced by the host quota daemon:
|
|
42
|
+
|
|
43
|
+
- `selectionPenalty = consecutiveErrorCount` when the last error is within `ROUTECODEX_QUOTA_ERROR_PRIORITY_WINDOW_MS` (default `10min`)
|
|
44
|
+
- Resets to `0` on a successful response
|
|
45
|
+
|
|
46
|
+
This is a *soft* preference signal (it does not exclude the key); exclusion is controlled by `inPool/cooldownUntil/blacklistUntil`.
|
|
47
|
+
|
|
48
|
+
### What “exhausted” means
|
|
49
|
+
|
|
50
|
+
In priority mode, a higher-priority key is considered exhausted only when it is **not selectable** due to:
|
|
51
|
+
|
|
52
|
+
- health manager unavailable (tripped/cooldown)
|
|
53
|
+
- quotaView exclusion (`inPool=false` / active `cooldownUntil` / active `blacklistUntil`)
|
|
54
|
+
- routing instructions / user exclusions
|
|
55
|
+
|
|
56
|
+
Only then will routing advance to the next candidate in priority order.
|
|
57
|
+
|
|
58
|
+
## Round-Robin Pools (`mode: "round-robin"`) — Health-Weighted AWRR
|
|
59
|
+
|
|
60
|
+
Goal: evenly distribute traffic across healthy keys, while reducing the hit rate of recently failing keys (without starving them).
|
|
61
|
+
|
|
62
|
+
Implementation: deterministic smooth weighted round-robin (no randomness).
|
|
63
|
+
|
|
64
|
+
### Health-weighted weights (AWRR)
|
|
65
|
+
|
|
66
|
+
If enabled (`loadBalancing.healthWeighted.enabled=true`) and `quotaView` provides error metadata, the router computes:
|
|
67
|
+
|
|
68
|
+
- `weight = baseWeight * multiplier`
|
|
69
|
+
- `multiplier` decreases with `consecutiveErrorCount`
|
|
70
|
+
- `multiplier` recovers over time using exponential decay (half-life)
|
|
71
|
+
- `multiplier` is floored by `minMultiplier` (prevents starvation)
|
|
72
|
+
|
|
73
|
+
Defaults live in:
|
|
74
|
+
|
|
75
|
+
- `sharedmodule/llmswitch-core/src/router/virtual-router/health-weighted.ts`
|
|
76
|
+
|
|
77
|
+
Key knobs (configurable under `loadBalancing.healthWeighted`):
|
|
78
|
+
|
|
79
|
+
- `baseWeight` (default `100`)
|
|
80
|
+
- `minMultiplier` (default `0.5`)
|
|
81
|
+
- `beta` (default `0.1`) — one error reduces weight by ~10%
|
|
82
|
+
- `halfLifeMs` (default `10min`)
|
|
83
|
+
- `recoverToBestOnRetry` — on router retries, prefer the healthiest key first
|
|
84
|
+
|
|
85
|
+
## Model-capacity 429 handling (host quota)
|
|
86
|
+
|
|
87
|
+
Some upstreams report `HTTP 429` with capacity semantics (e.g. “No capacity available for model …”).
|
|
88
|
+
This is not “quota depleted” locally; switching keys often does not help.
|
|
89
|
+
|
|
90
|
+
RouteCodex treats this as a *model-series* cooldown:
|
|
91
|
+
|
|
92
|
+
- On capacity-exhausted 429, host applies an immediate cooldown to the entire `${providerId}.${modelId}` series
|
|
93
|
+
- Default cooldown: `60s`
|
|
94
|
+
|
|
95
|
+
Implementation:
|
|
96
|
+
|
|
97
|
+
- `src/manager/modules/quota/provider-quota-daemon.model-backoff.ts`
|
|
98
|
+
|
|
99
|
+
## Context-weighted selection (preserve large windows)
|
|
100
|
+
|
|
101
|
+
Some clients have a fixed maximum usable context (e.g. `200k`). When multiple candidates are all "safe" for the current
|
|
102
|
+
request, we want to bias traffic toward smaller effective safe windows early, so that larger windows remain available
|
|
103
|
+
later when context grows.
|
|
104
|
+
|
|
105
|
+
This is implemented as an additional multiplier on top of existing weights (health-weighted / legacy), and is only
|
|
106
|
+
applied inside the same pool bucket and only for candidates in `ContextAdvisor.safe`.
|
|
107
|
+
|
|
108
|
+
Config (under `virtualrouter.loadBalancing.contextWeighted`):
|
|
109
|
+
|
|
110
|
+
- `enabled` (default `false`)
|
|
111
|
+
- `clientCapTokens` (default `200000`)
|
|
112
|
+
- `gamma` (default `1`, proportional compensation)
|
|
113
|
+
- `maxMultiplier` (default `2`)
|
|
114
|
+
|
|
115
|
+
Effective safe window (`T_safeEff`) used for compensation:
|
|
116
|
+
|
|
117
|
+
- `T_eff = min(modelMaxTokens, clientCapTokens)`
|
|
118
|
+
- `reserve = ceil(T_eff * (1 - warnRatio))` (warnRatio comes from `virtualrouter.contextRouting.warnRatio`, default `0.9`)
|
|
119
|
+
- `slack = max(0, modelMaxTokens - clientCapTokens)`
|
|
120
|
+
- `reserveEff = max(0, reserve - slack)` (models with slack can "absorb" the reserve)
|
|
121
|
+
- `T_safeEff = T_eff - reserveEff`
|
|
122
|
+
|
|
123
|
+
Then, within the bucket:
|
|
124
|
+
|
|
125
|
+
- `multiplier = min(maxMultiplier, (max(T_safeEff) / T_safeEff) ^ gamma)`
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
### Anthropic Golden Request Samples
|
|
2
|
+
|
|
3
|
+
我们把真实 `/v1/messages` 请求快照统一保存在 `~/.routecodex/golden_samples/anthropic_requests/`,每个目录
|
|
4
|
+
包含:
|
|
5
|
+
|
|
6
|
+
```
|
|
7
|
+
<slug>/
|
|
8
|
+
request_payload.json # 直接发送给 Anthropics API 的 json
|
|
9
|
+
meta.json # 来源阶段、采样说明、endpoint 等元数据
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
> **提示**:仓库内 `samples/chat-blackbox/anthropic/request-basic.json` 为上述样本的版本化拷贝,可在代码评审时直接 diff。
|
|
13
|
+
> 建议先用真实 provider 生成阶段快照,并把 `body` + `stageFile` 写入
|
|
14
|
+
> `~/.routecodex/golden_samples/new/anthropic-messages/<providerId>/`。随后执行
|
|
15
|
+
> `node scripts/tools/capture-provider-goldens.mjs --update-golden`,脚本会读取这些快照并同步
|
|
16
|
+
> `provider_golden_samples/`,检测到字段差异时会提示是否覆盖。
|
|
17
|
+
|
|
18
|
+
当前样本:
|
|
19
|
+
|
|
20
|
+
| slug | 描述 | Source Stage |
|
|
21
|
+
|------|------|--------------|
|
|
22
|
+
| `glm46-toolcall-20251209T223550158-010` | 用户让助手列出仓库目录,prompt 中包含 Codex/CLAUDE 大段 system 规则,`stream=true`,用于验证工具治理路径 | `anthropic-messages/req_1765290950164_req_inbound_stage1_format_parse.json` |
|
|
23
|
+
| `glm46-toolcall-20251209T223550463-011` | 用户只说“列出本地文件”,模型应拒绝直接读取本地盘,适合验证拒绝/告警逻辑 | `anthropic-messages/req_1765290950463_req_inbound_stage1_format_parse.json` |
|
|
24
|
+
|
|
25
|
+
#### 如何回放
|
|
26
|
+
|
|
27
|
+
1. 启动 RouteCodex,确保目标 provider(例如 `glm.key1.glm-4.6`)可用。
|
|
28
|
+
2. 直接将样本作为请求体发送:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
curl -s http://127.0.0.1:5555/v1/messages \
|
|
32
|
+
-H 'Content-Type: application/json' \
|
|
33
|
+
-H 'Authorization: Bearer test' \
|
|
34
|
+
--data @~/.routecodex/golden_samples/anthropic_requests/glm46-toolcall-20251209T223550158-010/request_payload.json
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
3. 如果需要切换 provider,只需修改 JSON 中的 `model` 字段或配合用户配置热更(无需 CLI 抓样本)。
|
|
38
|
+
|
|
39
|
+
#### 验证快照
|
|
40
|
+
|
|
41
|
+
- 设置 `ROUTECODEX_HUB_SNAPSHOTS=1` 后回放,`~/.routecodex/codex-samples/anthropic-messages/` 将刷新对应的
|
|
42
|
+
`req_*` 与 `resp_*` 阶段文件,可直接 diff。
|
|
43
|
+
- `anthropic/glm46-toolcall-…` 目录内已有响应黄金样本,可与请求目录交叉比对,确认入站/出站一致性。
|
|
44
|
+
|
|
45
|
+
#### 扩展样本
|
|
46
|
+
|
|
47
|
+
1. 捕获目标请求期间的 `req_*_req_inbound_stage1_format_parse.json`
|
|
48
|
+
2. 在 `anthropic_requests/` 下创建新子目录,复制 `body.payload` 为 `request_payload.json`
|
|
49
|
+
3. 写入 `meta.json` 说明模型、来源阶段、场景描述
|
|
50
|
+
4. 更新本文档表格即可
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Antigravity Gemini 格式清理要求
|
|
3
|
+
date: 2026-01-25
|
|
4
|
+
tags:
|
|
5
|
+
- routecodex
|
|
6
|
+
- antigravity
|
|
7
|
+
- gemini
|
|
8
|
+
- claude
|
|
9
|
+
status: active
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Antigravity Gemini 格式清理要求(gcli2api 对齐)
|
|
13
|
+
|
|
14
|
+
> [!summary]
|
|
15
|
+
> 本文汇总当前 **antigravity** 走 Gemini 协议时的格式清理要求,覆盖 **Gemini 系列** 与 **Claude 系列** 的关键输出/请求规范、UA/Headers 规范、工具历史一致性要求等。
|
|
16
|
+
> 本次改动已生效:历史 `functionCall` 强制补 `thoughtSignature: "skip_thought_signature_validator"`。
|
|
17
|
+
|
|
18
|
+
## 1) 适用范围
|
|
19
|
+
- **Gemini 系列**:`gemini-3-pro-low / gemini-3-pro-high` 等 Gemini 协议模型。
|
|
20
|
+
- **Claude 系列**:`claude-*` 走 antigravity/兼容层的 Gemini 路由时的兼容字段统一。
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 2) UA 与 Headers(gcli2api 对齐)
|
|
25
|
+
- **User-Agent**:固定为 `gcloud-cli/1.11.3`(对齐 gcli2api 行为)。
|
|
26
|
+
- **Headers 关键项**:
|
|
27
|
+
- `x-goog-api-client`: `gl-go/1.0.0 gccl/1.11.3`
|
|
28
|
+
- `x-goog-user-project`: 使用 `project`(保持与 gcli2api 一致)
|
|
29
|
+
- `x-goog-request-params`: `model=...`
|
|
30
|
+
- `x-client-request-id` + `x-goog-request-id`(使用 requestId/requestType 组合)
|
|
31
|
+
- **Body 结构**:
|
|
32
|
+
- 仅保留 gcli2api 需要的最小字段集合
|
|
33
|
+
- **不带 sessionId**
|
|
34
|
+
- 保持 `contents / systemInstruction / safetySettings / generationConfig / tools` 的一致性顺序与结构
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## 3) 工具与历史一致性(核心要求)
|
|
39
|
+
|
|
40
|
+
> [!important]
|
|
41
|
+
> **历史中出现的工具调用必须与当前请求 tools 对齐**。历史中不得出现当前 tools 列表中不存在的工具调用。
|
|
42
|
+
|
|
43
|
+
- **历史工具清理**:
|
|
44
|
+
- 对 **history 中出现但当前 tools 不存在** 的 `functionCall`/`functionResponse` 做 **移除或降级为纯文本**。
|
|
45
|
+
- 保持 **tools 列表与历史工具调用**的 **一一对应**。
|
|
46
|
+
- **工具名合法性**:
|
|
47
|
+
- Gemini 对函数名字符集/形状严格校验;不合法名称需 **清理或过滤**。
|
|
48
|
+
- **工具 schema 对齐**:
|
|
49
|
+
- 历史 `functionCall.args` 必须与当前工具 schema 对齐。
|
|
50
|
+
- 对 `args` 做 **结构修正**:Gemini 期望 `functionCall.args` 为对象(Struct),非对象需包 `value`。
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## 4) Gemini 协议的格式清理要点
|
|
55
|
+
|
|
56
|
+
### 4.1 functionCall 历史补签名
|
|
57
|
+
- **新增要求(已生效)**:
|
|
58
|
+
- 历史 `functionCall` **必须包含**:
|
|
59
|
+
- `thoughtSignature: "skip_thought_signature_validator"`
|
|
60
|
+
- 这是 gcli2api 的行为:即使没有真实签名,也需要该字段以通过 Cloud Code 严格校验。
|
|
61
|
+
|
|
62
|
+
### 4.2 工具 schema 输出
|
|
63
|
+
- **始终输出工具 schema**(Gemini 需要工具声明来校验 `functionCall`/`functionResponse`)。
|
|
64
|
+
- `toolConfig.functionCallingConfig`:
|
|
65
|
+
- `NONE / ANY / ALLOWED` 按 `tool_choice` 映射。
|
|
66
|
+
|
|
67
|
+
### 4.3 Content 清理
|
|
68
|
+
- 统一 `contents` 结构,确保每条 entry 的 parts 合法。
|
|
69
|
+
- 对无效 part 做降级或过滤,避免 Gemini 侧 malformed。
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 5) Claude 系列在 Antigravity 中的兼容统一
|
|
74
|
+
|
|
75
|
+
- Claude-thinking / 非 thinking 输出在 antigravity 侧 **统一形态**:
|
|
76
|
+
- 保证与 Gemini/OpenAI 响应结构一致的 **content 形状**。
|
|
77
|
+
- 保持 **history/tool 行为与 Gemini 同步**(同样遵循历史工具一致性要求)。
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## 6) 当前已生效的关键修复
|
|
82
|
+
|
|
83
|
+
- ✅ **历史 functionCall 强制补 `thoughtSignature`**(gcli2api 行为一致)。
|
|
84
|
+
- ✅ **history/tool 对齐清理**:历史工具调用不再允许与当前 tools 不一致。
|
|
85
|
+
- ✅ **args 结构修正**:非对象 args 包装到 `{ value }`。
|
|
86
|
+
- ✅ **UA/Headers 与 gcli2api 对齐**(最小 body、requestId/requestType headers)。
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## 7) 验证方式(建议)
|
|
91
|
+
|
|
92
|
+
- 对比两条请求(首条无历史、次条带历史):
|
|
93
|
+
- `provider-request.json` 中 **`functionCall` 必须带 `thoughtSignature`**。
|
|
94
|
+
- `tools` 与历史 functionCall **必须一一对齐**。
|
|
95
|
+
- `args` 必须为对象(Struct)。
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## 8) 备注
|
|
100
|
+
|
|
101
|
+
> [!note]
|
|
102
|
+
> 本次修改已验证生效。若后续仍出现 429 或 Cloud Code 严格校验失败,优先检查 **history 中工具清理是否遗漏** 或 **functionCall/Response 的结构化字段是否存在差异**。
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Antigravity 429 + sticky-queue contract (standard behavior)
|
|
2
|
+
|
|
3
|
+
This document defines the *default* behavior for Antigravity routing under transient 429s. It is a hard requirement
|
|
4
|
+
for the "standard" execution path; any alternative behavior is considered legacy compatibility.
|
|
5
|
+
|
|
6
|
+
## Contract (3 rules)
|
|
7
|
+
|
|
8
|
+
1) **Success sticks**
|
|
9
|
+
Once an alias is selected for a `(providerId=antigravity, modelId)` group, routing keeps selecting that alias
|
|
10
|
+
until the alias becomes unavailable (error / cooldown / blacklist).
|
|
11
|
+
|
|
12
|
+
2) **429 cools down + rotates to tail**
|
|
13
|
+
For capacity-style 429s (e.g. upstream "model capacity exhausted"), routing:
|
|
14
|
+
- immediately applies a short cooldown to the failing `providerKey` (alias-level for Antigravity), and
|
|
15
|
+
- on retry, rotates the failing alias to the tail of the sticky-queue, so the next attempt prefers a different alias.
|
|
16
|
+
|
|
17
|
+
3) **Fallback only when exhausted**
|
|
18
|
+
Retrying stays within Antigravity for the same model as long as any usable alias remains.
|
|
19
|
+
Only when all aliases are excluded/cooling/blacklisted does routing fall back to other providers/routes.
|
|
20
|
+
|
|
21
|
+
## Where this is implemented
|
|
22
|
+
|
|
23
|
+
- **Retry hint plumbing (excludedProviderKeys)**: `src/server/runtime/http-server/request-executor.ts`
|
|
24
|
+
- **Sticky-queue selection + alias rotation**:
|
|
25
|
+
- `sharedmodule/llmswitch-core/src/router/virtual-router/engine-selection/alias-selection.ts`
|
|
26
|
+
- `sharedmodule/llmswitch-core/src/router/virtual-router/engine-selection/tier-selection.ts`
|
|
27
|
+
- `sharedmodule/llmswitch-core/src/router/virtual-router/engine-selection/tier-selection-select.ts`
|
|
28
|
+
- **Capacity-style 429 cooldown (alias-level for Antigravity)**:
|
|
29
|
+
- `src/manager/modules/quota/provider-quota-daemon.model-backoff.ts`
|
|
30
|
+
- `src/manager/modules/quota/provider-quota-daemon.events.ts`
|
|
31
|
+
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# CCR enhancetool 行为与对齐方案(形状/语法修复,非语义重写)
|
|
2
|
+
|
|
3
|
+
本文档总结了 claude-code-router(下称 CCR)中内置 transformer “enhancetool”的关键行为,并给出在 llmswitch-core 中实现等价对齐的方案。对齐范围严格限定为“整体形状/语法/JSON(JSON5) 层”,不解析或重写具体命令语义(如 grep 正则、管道策略等)。
|
|
4
|
+
|
|
5
|
+
## 1. CCR enhancetool 行为摘要
|
|
6
|
+
|
|
7
|
+
- 非流 JSON(application/json)
|
|
8
|
+
- 对 `choices[0].message.tool_calls[].function.arguments` 执行三段式容错修复:
|
|
9
|
+
1) 尝试 `JSON.parse` 成功 → 使用原字符串。
|
|
10
|
+
2) 失败则 `JSON5.parse` 成功 → `JSON.stringify` 输出合法 JSON 字符串。
|
|
11
|
+
3) 再失败则进行“安全修复”(典型策略:去除围栏标记、去掉尾随逗号、单引号转双引号、补齐引号/括号等),成功后 `JSON.stringify`。
|
|
12
|
+
4) 全部失败 → 回退为字符串 "{}"(空对象)。
|
|
13
|
+
- 若存在 `tool_calls`:标准化 `content=null`;无 `finish_reason` 时补齐为 `tool_calls`。
|
|
14
|
+
|
|
15
|
+
- 流式(text/event-stream)
|
|
16
|
+
- 吞掉“工具参数增量”片段,不向下游透出 arguments 的碎片增量。
|
|
17
|
+
- 聚合策略:
|
|
18
|
+
- 记录工具调用开始(OpenAI Chat: `delta.tool_calls`;Anthropic Messages: `content_block_start` 等),保存 `index/name/id`。
|
|
19
|
+
- 聚合 `partial_json` / `function.arguments` 的增量数据到缓冲;不在增量阶段向下游发送 arguments 内容。
|
|
20
|
+
- 在工具完成时(OpenAI: `finish_reason=tool_calls`;Anthropic: `content_block_stop`)一次性下发:
|
|
21
|
+
- 将聚合后的 arguments 走上述“三段式容错修复”,最终保证为“单个 JSON 字符串”。
|
|
22
|
+
- 构造新的 delta(含完整 `name` 与 `arguments`),并删除任何同时出现的 `delta.content`。
|
|
23
|
+
- 思考文本(reasoning)在 CCR 中被专门转为 `thinking` 域;本轮对齐聚焦工具通路,不改变我们已存在的 reasoning 处理策略。
|
|
24
|
+
|
|
25
|
+
- 不做的事
|
|
26
|
+
- 不解析或重写具体命令语义(不拆分正则、多 -e 重写、命令管道改写等)。
|
|
27
|
+
- 不注入系统提示词;仅允许在 tools schema 描述中加入“形状/用法提示”(非 system)。
|
|
28
|
+
|
|
29
|
+
## 2. 我们的对齐原则(三端一致)
|
|
30
|
+
|
|
31
|
+
1) 形状优先:仅保障 `function.arguments` 在所有输出路径上都是“单个 JSON 字符串”,并保持 `content=null`、`finish_reason=tool_calls` 等不变式。
|
|
32
|
+
2) 三端统一:Chat(OpenAI)、Responses(OpenAI)、Messages(Anthropic)在非流与流式两条通路都执行一致策略。
|
|
33
|
+
3) 不解析命令语义:不对 grep/正则/管道等进行语义重写,避免引入不可预测副作用。
|
|
34
|
+
|
|
35
|
+
## 3. 对齐实施方案
|
|
36
|
+
|
|
37
|
+
### 3.1 非流(一次性 JSON)
|
|
38
|
+
|
|
39
|
+
- 入口:`llmswitch-core v2` 的响应治理(response 相位)。
|
|
40
|
+
- 动作:
|
|
41
|
+
- 若 `function.arguments` 是对象 → 仅 `JSON.stringify`(保持语义原样)。
|
|
42
|
+
- 若是字符串 → 走 `repairArguments`(JSON→JSON5→安全修复→失败回退 "{}")。
|
|
43
|
+
- 补齐 `finish_reason=tool_calls`(若缺),以及 `content=null`(当存在 `tool_calls`)。
|
|
44
|
+
|
|
45
|
+
### 3.2 流式(SSE 聚合)
|
|
46
|
+
|
|
47
|
+
- Chat(OpenAI /v1/chat/completions):新增“Chat SSE 工具参数聚合器”。
|
|
48
|
+
- 吞掉增量 arguments,不向下游透出;工具完成时合并缓冲并 `repairArguments`,一次性发送完整字符串。
|
|
49
|
+
|
|
50
|
+
- Messages(Anthropic /v1/messages):新增“Messages SSE 工具参数聚合器”。
|
|
51
|
+
- 聚合 `input_json_delta.partial_json`;`content_block_stop` 时进行 `repairArguments` 并一次性下发。
|
|
52
|
+
|
|
53
|
+
- Responses(OpenAI /v1/responses):改造现有 `ResponsesSSETransformer` 为同策略。
|
|
54
|
+
- 工具参数不再逐片外发,仅在工具结束时一次性输出完整字符串。
|
|
55
|
+
|
|
56
|
+
### 3.3 repairArguments(对齐 CCR,形状/语法修复)
|
|
57
|
+
|
|
58
|
+
- 实现在 `shared/v2/conversion/shared/jsonish.ts`:
|
|
59
|
+
- `repairArguments(arg: unknown): string`:输入任意字符串/对象,输出“单个 JSON 字符串”。
|
|
60
|
+
- 顺序:`JSON.parse` → `JSON5.parse` → 安全修复(去围栏/尾逗号/单引号等)→ 失败返回 "{}"。
|
|
61
|
+
- 不触碰命令语义(值中的命令原封不动)。
|
|
62
|
+
|
|
63
|
+
### 3.4 tools schema 描述增强(非 system 提示)
|
|
64
|
+
|
|
65
|
+
- 在 `augmentOpenAITools` 的 `shell` 描述中追加“稳健用法提示”(仅描述层):
|
|
66
|
+
- 长 OR 模式建议使用多个 `-e` 或 `-f`(从 stdin 读模式列表)。
|
|
67
|
+
- 可优先使用 `rg`(ripgrep)以减少引号/括号陷阱。
|
|
68
|
+
- 避免将解释性文字混入 `arguments`;说明性文字放在普通对话文本中。
|
|
69
|
+
|
|
70
|
+
## 4. 开关与默认
|
|
71
|
+
|
|
72
|
+
- `RCC_TOOL_ENHANCE=1`(默认开):启用 `repairArguments` 三段式修复(失败回退 "{}")。
|
|
73
|
+
- `RCC_SSE_TOOL_AGGREGATE=1`(默认开):吞掉参数增量,完结一次性下发完整 arguments。
|
|
74
|
+
|
|
75
|
+
## 5. 快照与验收
|
|
76
|
+
|
|
77
|
+
- 预期在 `*_provider-request.json`:
|
|
78
|
+
- `assistant.tool_calls[].function.arguments` 均为合法 JSON 字符串;
|
|
79
|
+
- 当有 `tool_calls` 时,`content=null`,`finish_reason='tool_calls'`;
|
|
80
|
+
- 无 arguments 增量碎片。
|
|
81
|
+
|
|
82
|
+
- SSE:不再透出 arguments 增量;仅在工具完成时出现一次完整 arguments。
|
|
83
|
+
|
|
84
|
+
- 失败回退:当 JSON/JSON5/修复全部失败时,arguments 应为 "{}"。
|
|
85
|
+
|
|
86
|
+
## 6. 边界与不做项
|
|
87
|
+
|
|
88
|
+
- 不解析或重写具体命令语义(例如:不拆分大正则为多 `-e`,不重排管道)。
|
|
89
|
+
- 不在服务器端点或兼容层重复实现工具转换/聚合;统一入口仅在 `llmswitch-core`。
|
|
90
|
+
|
|
91
|
+
## 7. 实施清单(按顺序)
|
|
92
|
+
|
|
93
|
+
1) 文档到位(本文件 + AGENTS.md 对齐段落)。
|
|
94
|
+
2) 新增 `repairArguments`(JSON→JSON5→安全修复→"{}")。
|
|
95
|
+
3) 改造响应相位(非流)调用 `repairArguments` 并保证 finish_reason/content 不变式。
|
|
96
|
+
4) 新增 Chat/Anthropic 两个 SSE 聚合器;改造 Responses SSE 统一策略。
|
|
97
|
+
5) 更新 tools schema 描述(仅描述增强)。
|
|
98
|
+
6) 严格按“先编译共享模块、再构建根包并全局安装”的顺序验证。
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
附:CCR 代码阅读锚点(仅供对照,不在代码注释中引用)
|
|
103
|
+
- (更新)移除 `@musistudio/llms` 依赖描述;增强工具路径由 llmswitch-core 统一实现(透明代理 + 二轮请求)。
|
|
104
|
+
- 流式路径中 `content_block_start/stop` 与 `partial_json` 聚合逻辑;
|
|
105
|
+
- 非流路径中 arguments 三段式修复与回退策略。
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Chat GLM 500 调查与处置记录(精准定位)
|
|
2
|
+
|
|
3
|
+
## 背景
|
|
4
|
+
- 现象:Chat 通路上游 GLM 返回 500(Operation failed)。
|
|
5
|
+
- 最新失败样本目录:`~/.routecodex/codex-samples/openai-chat`
|
|
6
|
+
- 例:`req_1761955101841_2d71u9w6x_provider-request.json`
|
|
7
|
+
|
|
8
|
+
## 症状与证据
|
|
9
|
+
- 请求载荷体积异常:多轮 `role:"tool"` 消息携带巨大 JSON/文本结果;两条超长 system 提示叠加。
|
|
10
|
+
- codec/compat 阶段的快照显示:`assistant.tool_calls` 的 `content` 已规范为 `null`;但 `provider-request.json` 依然包含大量工具结果文本(历史轮未最小化)。
|
|
11
|
+
- SSE 侧报错:`Error: GLM API error: 500 Internal Server Error - Operation failed`。
|
|
12
|
+
|
|
13
|
+
## 根因(Root Cause)
|
|
14
|
+
- 历史工具结果在多轮会话中持续累积为长文本,叠加双 system 文本,导致上游 GLM 对载荷体量/结构敏感触发 500。
|
|
15
|
+
- 并非“工具引导未生效”。工具引导与工具增强均在 llmswitch-core 正常注入(`[Codex Tool Guidance v1]` + 严格 schema)。
|
|
16
|
+
|
|
17
|
+
## CCR(Claude Code Router)的相关做法(预算来源)
|
|
18
|
+
- CCR 以“总上下文预算(token count)”为核心,计算消息 + system + tools 的 token 数,并基于阈值选用长上下文模型:
|
|
19
|
+
- 位置:`../../claude-code-router/src/utils/router.ts`
|
|
20
|
+
- 关键点:
|
|
21
|
+
- 使用 `tiktoken` 计算 token(消息文本、tool_use/input、tool_result/content、system 文本、工具 schema 都计入)。
|
|
22
|
+
- 与配置阈值比较(`virtualrouter.classifier.longContextThresholdTokens`,默认 180,000 tokens)。
|
|
23
|
+
- 超阈值或结合上一轮 usage 过大则切换到 `config.Router.longContext` 模型。
|
|
24
|
+
- CCR 并不把大段工具结果回灌到 assistant 文本;工作流结束时通过 ExitTool 返回最终文本,移除 `tool_calls`。
|
|
25
|
+
|
|
26
|
+
## 我们的对齐策略(直击根因)
|
|
27
|
+
- 唯一入口:仅在 `sharedmodule/llmswitch-core` 做统一处理;Provider/兼容层不做逻辑修改。
|
|
28
|
+
- 两类措施:
|
|
29
|
+
1) 工具结果“主动最小化 + 分层预算”
|
|
30
|
+
- 所有 `role:'tool'` 消息统一“文本化+裁剪”。
|
|
31
|
+
- rcc.tool.v1 成功 → 提取 stdout/简明输出;失败 → `执行失败:前三行`;无输出 → `执行成功(无输出)`。
|
|
32
|
+
- 为避免累计膨胀,引入分层预算:
|
|
33
|
+
- 总载荷预算(token/字节,按 CCR 思路来自配置/环境)。
|
|
34
|
+
- 每条工具消息预算(HEAD/TAIL、类型化提要),最近 N 条额度更大,其余更严格。
|
|
35
|
+
- 保留结构与 `tool_call_id`,不改角色、不清历史(记忆靠历史)。
|
|
36
|
+
2) 去噪
|
|
37
|
+
- 删除“无 `tool_calls` 且内容为空/仅空白”的 `assistant` 回合,减少空 turn.
|
|
38
|
+
|
|
39
|
+
## 已落地(当前版本)
|
|
40
|
+
- 实施位置:`sharedmodule/llmswitch-core/src/conversion/shared/openai-message-normalize.ts`
|
|
41
|
+
- 统一对所有 `role:'tool'` 消息做“文本化+截断”,并在文本前加截断提示(例如:`[输出已截断至 2048 字符]`)。
|
|
42
|
+
- 默认阈值:`RCC_TOOL_TEXT_LIMIT`(默认 2048,可调)。
|
|
43
|
+
- `assistant` 含 `tool_calls` 时,将空字符串 `content` 规范为 `null`(保留混合内容)。
|
|
44
|
+
- 删除空文本 `assistant`(无工具调用)。
|
|
45
|
+
|
|
46
|
+
## curl 复现与验证
|
|
47
|
+
1. 启动本地服务(示例端口 5520)
|
|
48
|
+
```bash
|
|
49
|
+
rcc start # 或 routecodex start
|
|
50
|
+
```
|
|
51
|
+
2. 使用失败样本 `*_raw-request.json` 复现
|
|
52
|
+
```bash
|
|
53
|
+
jq -r '.body' ~/.routecodex/codex-samples/openai-chat/<失败样本>_raw-request.json > /tmp/rc_req_body.json
|
|
54
|
+
curl -s -o /tmp/rc_resp.json -w "%{http_code}" \
|
|
55
|
+
-H 'Content-Type: application/json' \
|
|
56
|
+
--data @/tmp/rc_req_body.json \
|
|
57
|
+
http://127.0.0.1:5520/v1/chat/completions
|
|
58
|
+
```
|
|
59
|
+
3. 成功标准
|
|
60
|
+
- `provider-request.json` 中:
|
|
61
|
+
- `role:'tool'` 文本出现截断提示;历史轮不再巨量。
|
|
62
|
+
- 不再出现空的 `assistant` turn。
|
|
63
|
+
- SSE/JSON 不再出现上游 500。
|
|
64
|
+
|
|
65
|
+
## 后续工作(对齐 CCR 的“预算来源”)
|
|
66
|
+
- 预算来源与策略:
|
|
67
|
+
- 总上下文预算:
|
|
68
|
+
- 从配置载入(建议:`virtualrouter.classifier.longContextThresholdTokens`,或在用户配置中覆盖)。
|
|
69
|
+
- 用 `tiktoken` 计算请求 token 数,参照 CCR 的 `router.ts` 逻辑。
|
|
70
|
+
- 分层预算落到工具结果:
|
|
71
|
+
- 最近 N 条工具消息额度更大,其余更严格(HEAD/TAIL/摘要)。
|
|
72
|
+
- 类型化提要(stderr/失败仅前几行,stdout/JSON 取关键信息)。
|
|
73
|
+
- 超预算策略:
|
|
74
|
+
- 优先压缩工具结果文本,不修改历史结构与角色;必要时切换长上下文模型(CCR 同源策略)。
|
|
75
|
+
|
|
76
|
+
## 结论
|
|
77
|
+
- 500 原因是“累积工具结果文本 + 超长 system 导致载荷过大”,而非“工具引导缺失”。
|
|
78
|
+
- 处置方案定位在唯一入口(llmswitch-core),以“主动最小化 + 预算控制”预防问题发生。
|
|
79
|
+
- 下一步将把“分层预算 + 类型化提要 + 全局上下文预算(CCR 同源)”落地为可配置策略,并继续用 curl 真样本回放验证。
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
### OpenAI Chat Golden Request Samples
|
|
2
|
+
|
|
3
|
+
存放位置:`~/.routecodex/golden_samples/openai_requests/<slug>/`
|
|
4
|
+
|
|
5
|
+
> **提示**:
|
|
6
|
+
> - 自 0.87.21 起,chat 入口的 provider 专属样本统一存放在
|
|
7
|
+
> `~/.routecodex/golden_samples/new/<entryType>/<providerId>/`(例如 `new/openai-chat/glm`)。
|
|
8
|
+
> 目录内包含 `request.sample.json`(直接从阶段快照复制的 `body`)以及 `meta.json`
|
|
9
|
+
> (指向原始 `*_stage2_format_build.json` 路径)。`scripts/tools/capture-provider-goldens.mjs`
|
|
10
|
+
> 会优先读取这些“真实快照”,无需再回放 `samples/chat-blackbox/**/request-basic.json`。
|
|
11
|
+
> - 仍需保留仓库内 `samples/chat-blackbox/*/request-basic.json`,用于快速审查/比较;当新增场景时,
|
|
12
|
+
> 先运行真实请求生成阶段快照,再在 `new/<entryType>/<providerId>/` 放置 `request.sample` 与 `meta`,
|
|
13
|
+
> 最后执行 `node scripts/tools/capture-provider-goldens.mjs --update-golden`,脚本会把同一份请求复制到
|
|
14
|
+
> `provider_golden_samples/`,供 mock/provider 单元测试使用。
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
<slug>/
|
|
18
|
+
request_payload.json # 直接发送到 /v1/chat/completions 的 JSON
|
|
19
|
+
meta.json # 包含来源阶段、endpoint、描述等元数据
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
| slug | 描述 | Source Stage |
|
|
23
|
+
|------|------|--------------|
|
|
24
|
+
| `chat-toolcall-20251209T225016004-002` | Codex CLI 会话(用户 repeatedly “列出本地文件”,`stream=true`,含完整 system/环境上下文与工具 schema),用于验证 chat 入口 → glm.provider 的骨架路径 | `openai-chat/req_1765291814052_req_inbound_stage1_format_parse.json` |
|
|
25
|
+
|
|
26
|
+
#### 回放方式
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
curl -s http://127.0.0.1:5555/v1/chat/completions \
|
|
30
|
+
-H 'Content-Type: application/json' \
|
|
31
|
+
-H 'Authorization: Bearer test' \
|
|
32
|
+
--data @~/.routecodex/golden_samples/openai_requests/chat-toolcall-20251209T225016004-002/request_payload.json
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
该样本会沿 V2 骨架走 chat 入口 → hub → glm provider,可直接用来对比 legacy/chat-provider 行为。
|
|
36
|
+
|
|
37
|
+
#### 如何扩展
|
|
38
|
+
|
|
39
|
+
1. 在 `~/.routecodex/golden_samples/openai-chat/req_*_req_inbound_stage1_format_parse.json` 中找到需要的请求负载。
|
|
40
|
+
2. 将 `body.payload` 拷贝为新的 `request_payload.json`;注明 slug、描述后写入 `meta.json`。
|
|
41
|
+
3. 更新本文件表格,描述该样本的用途、对应阶段文件。若需要刷新所有 provider 的黄金请求,可运行
|
|
42
|
+
`node scripts/tools/capture-provider-goldens.mjs --update-golden`,脚本将自动覆盖 `provider_golden_samples/` 下对应入口的请求副本。
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
## Chat 语义扩展与接线计划
|
|
2
|
+
|
|
3
|
+
> 目标:让 llmswitch-core 中的 Chat Process / Standardized 桥承接四种协议的语义,不再依赖 metadata 透传 “raw payload”,并按顺序分阶段完成。
|
|
4
|
+
|
|
5
|
+
> 术语约定:本文中的 “chat process” 指代码层面的 `chat_process` 阶段(工具治理/路由/协议重建的必经处理段)。
|
|
6
|
+
|
|
7
|
+
### 阶段 0:现状确认
|
|
8
|
+
|
|
9
|
+
1. **协议扫描**
|
|
10
|
+
- `chat-mapper.ts`:系统提示、工具空数组、未知字段依赖 `metadata.systemInstructions/extraFields/toolsFieldPresent`。
|
|
11
|
+
- `responses-mapper.ts`:resume/include/store 等通过 `metadata.responsesContext/responseFormat` 储存。
|
|
12
|
+
- `anthropic-mapper.ts`:system blocks、tool alias、内容 shape 等塞进 `metadata.extraFields`。
|
|
13
|
+
- `gemini-mapper.ts`:systemInstruction、safetySettings、generationConfig、toolConfig 均在 metadata/parameters。
|
|
14
|
+
2. **chat process / standardized 桥**
|
|
15
|
+
- 只理解 `messages/tools/toolOutputs/parameters`,其余通通进 `metadata.capturedContext`。
|
|
16
|
+
|
|
17
|
+
### 阶段 1:扩展 Chat Process + Standardized 桥
|
|
18
|
+
|
|
19
|
+
1. **类型扩展**
|
|
20
|
+
- 在 `ChatEnvelope`、`StandardizedRequest` 新增 `semantics`,并明确区分:
|
|
21
|
+
- **通用横向字段**:如 `semantics.session.previousResponseId`、`semantics.system.textBlocks`,用于跨协议共享。
|
|
22
|
+
- **协议专属命名空间**:`semantics.responses` / `semantics.anthropic` / `semantics.gemini`。每个命名空间内定义稳定 contract,禁止随意往里塞 provider extras。
|
|
23
|
+
- **providerExtras** 仅用于临时透传,默认禁止业务逻辑读取,后续接线完成后应趋近于空。
|
|
24
|
+
- `chatEnvelopeToStandardized` / `standardizedToChatEnvelope` 深拷贝 `semantics`。
|
|
25
|
+
2. **chat process 适配**
|
|
26
|
+
- `runHubChatProcess`、工具治理、路由决策只读 `request.semantics`;除 mapper/bridge 外,任何模块不得写入 `semantics`。
|
|
27
|
+
- Metadata 退回诊断角色:仅保留 `missingFields/providerMetadata` 等调试字段,`capturedContext` 禁止再夹带业务语义。
|
|
28
|
+
3. **模块测试**
|
|
29
|
+
- 新增 spec:构造 `ChatEnvelope` (含 system/responses/anthropic/gemini),执行标准化→还原→chat process,断言 `semantics` 原样保留。
|
|
30
|
+
|
|
31
|
+
> 完成该阶段后,chat process 成为“语义承接层”,为后续接线提供可靠落点。
|
|
32
|
+
|
|
33
|
+
### 阶段 2:协议语义接线(分批)
|
|
34
|
+
|
|
35
|
+
1. **OpenAI Chat**
|
|
36
|
+
- 将 `metadata.systemInstructions`/`extraFields`/`toolsFieldPresent` 迁移到 `semantics.system` / `semantics.tools`,只允许在 `semantics.providerExtras` 做临时镜像。
|
|
37
|
+
- 迁移期间保持“语义双写”:写入 semantics 后,兼容代码仍可读旧 metadata,但新逻辑必须只读 semantics。
|
|
38
|
+
- 更新现有 chat mapper 测试,确认 round-trip 不丢数据。
|
|
39
|
+
2. **Responses**
|
|
40
|
+
- `captureResponsesContext` 输出的 include/store/responseFormat/resume 等写入 `semantics.responses`,必要时临时镜像到旧 metadata。
|
|
41
|
+
- SubmitToolOutputs、resume、responses-roundtrip 仅依赖 `semantics.responses`;现有逻辑若仍读 metadata,需先迁移。
|
|
42
|
+
- 针对 responses 的 mock sample 回放,验证 `semantics.responses` 中包含 `previousResponseId`、`resumeToolOutputs` 等。
|
|
43
|
+
3. **Anthropic**
|
|
44
|
+
- system blocks、alias map、passthrough metadata、anthropicMirror -> `semantics.anthropic`。
|
|
45
|
+
- outbound mapper 从 `semantics` 还原 payload,metadata.extraFields 仅做兼容写;新读路径统一指向 semantics。
|
|
46
|
+
- 更新 `tests/sharedmodule/gemini/anthropic` 相关断言。
|
|
47
|
+
4. **Gemini**
|
|
48
|
+
- systemInstruction、safetySettings、toolConfig、generationConfig、`__rcc_stream` → `semantics.gemini`,仅在兼容期间写 metadata 镜像。
|
|
49
|
+
- generationConfig / toolConfig 通过 `semantics` 显式传递,metadata 不得再承载业务语义。
|
|
50
|
+
- 确认 `buildGeminiRequestFromChat` 仅依赖 `chat.semantics.gemini`。
|
|
51
|
+
|
|
52
|
+
每完成一个协议接线:
|
|
53
|
+
- 编写/更新对应 spec。
|
|
54
|
+
- 运行协议相关现有测试(tool-loop、responses-submit、anthropic roundtrip、gemini mapper)。
|
|
55
|
+
- 确认黑盒模块测试(阶段 1)依然通过。
|
|
56
|
+
|
|
57
|
+
### 阶段 3:清理与回归
|
|
58
|
+
|
|
59
|
+
1. **移除遗留 metadata 键**
|
|
60
|
+
- 删除 `metadata.systemInstructions/extraFields.responsesContext` 等已迁移字段,保留 `missingFields/providerMetadata`。
|
|
61
|
+
- 更新文档与类型约束。
|
|
62
|
+
2. **回归测试矩阵**
|
|
63
|
+
- `npm run test:sharedmodule`
|
|
64
|
+
- `npm run verify:e2e-toolcall`(覆盖 responses tool loop)
|
|
65
|
+
- `scripts/tests/apply-patch-loop.mjs` / `responses-submit` 样本回放
|
|
66
|
+
- Anthropic / Gemini 专属 dry-run(若有)。
|
|
67
|
+
3. **文档更新**
|
|
68
|
+
- `docs/responses-...`, `docs/pipeline/...` 添加新语义字段说明。
|
|
69
|
+
- 记录“metadata 仅用于诊断,业务语义全部进入 `semantics`”的新约束。
|
|
70
|
+
|
|
71
|
+
### 注意事项
|
|
72
|
+
|
|
73
|
+
- **严格顺序**:阶段 1 完成并通过黑盒测试后,才能启动阶段 2 的任何接线工作。
|
|
74
|
+
- **只读语义**:除 Semantic Mapper / Bridge 外,任何模块不得写 `semantics`; chat process 之后的所有节点禁止从 metadata/raw 读取业务语义。
|
|
75
|
+
- **最小增量**:每个协议接线尽量独立 PR/commit,便于回滚。
|
|
76
|
+
- **兼容期双写**:阶段 2 中需维护 semantics & metadata 双写(写 semantics → 同步旧字段);读路径优先 semantics,metadata 仅保底兼容,直到阶段 3 清理完成。
|
|
77
|
+
- **验证方式**:所有语义字段必须能在 `StandardizedRequest.semantics` 中观测到,且 chat process/路由/工具治理仅依赖该结构。
|
|
78
|
+
|
|
79
|
+
### 审查建议
|
|
80
|
+
|
|
81
|
+
- **横纵拆分**:在 `semantics` 结构中明确跨协议共享字段(例如 `semantics.session.previousResponseId`、`semantics.system.textBlocks`),避免每个协议重复定义同义字段;协议专属字段需在命名空间内列出 contract,并写测试覆盖。
|
|
82
|
+
- **提交策略**:阶段 2~3 的每个协议迁移都需更新 spec + 运行现有样本(responses submit、anthropic/gemini roundtrip 等),并用黑盒模块测试确认 semantics 不丢失。
|
|
83
|
+
- **metadata 清理**:阶段 3 清理前做 StandardizedRequest/ChatEnvelope 快照测试,确保 metadata 只剩诊断信息;用 codex samples 回放检查 semantics 是否完整覆盖我们关心的语义。
|
|
84
|
+
- **与“禁止 raw 打洞”对齐**:任何绕开 semantics、试图回读 raw/metatada 的逻辑都应视为架构违规;新文档明确强调这一点,保持与工具链路治理的统一思路。
|