@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,716 @@
|
|
|
1
|
+
# V2 Pipeline Prerun and Dynamic Connection Design
|
|
2
|
+
## (Support Zero-Configuration Migration Gradual Switch)
|
|
3
|
+
|
|
4
|
+
## 🎯 Core Design Objectives
|
|
5
|
+
|
|
6
|
+
1. **Pipeline Prerun**: V2 can first dry-run validation, ensuring complete compatibility with V1
|
|
7
|
+
2. **Dynamic Connection**: Only increase connection process after selecting route, no reassembly
|
|
8
|
+
3. **Simplified Assembler**: Only check if modules are statically configured, no connection building
|
|
9
|
+
4. **Zero Configuration Migration**: V1 configuration auto-converts to V2 static instance configuration
|
|
10
|
+
|
|
11
|
+
## 🏗️ Overall Architecture Design
|
|
12
|
+
|
|
13
|
+
### V1 vs V2 Architecture Comparison
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
V1 Static Assembly (Current):
|
|
17
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
18
|
+
│ PipelineAssembler │
|
|
19
|
+
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
20
|
+
│ │ Config Parse │→ │ Instance Create │→ │ Connection Build │ │
|
|
21
|
+
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
|
22
|
+
│ ↓ ↓ ↓ │
|
|
23
|
+
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
24
|
+
│ │ PipelineManager (Static Connection) │ │
|
|
25
|
+
│ │ [ProviderA]─[CompatA]─[LLMSwitchA] (Connected) │ │
|
|
26
|
+
│ │ [ProviderB]─[CompatB]─[LLMSwitchB] (Connected) │ │
|
|
27
|
+
│ └─────────────────────────────────────────────────────────┘ │
|
|
28
|
+
└─────────────────────────────────────────────────────────────┘
|
|
29
|
+
|
|
30
|
+
V2 Prerun + Dynamic Connection (New Design):
|
|
31
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
32
|
+
│ V2PipelineAssembler │
|
|
33
|
+
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
34
|
+
│ │ Config Check │→ │ Instance Verify │→ │ Prerun Validate │ │
|
|
35
|
+
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
|
36
|
+
│ ↓ ↓ ↓ │
|
|
37
|
+
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
38
|
+
│ │ StaticInstancePool │ │
|
|
39
|
+
│ │ [ProviderA] [ProviderB] [CompatA] [CompatB] [SwitchA] │ │
|
|
40
|
+
│ │ (Static instance pool, not connected) │ │
|
|
41
|
+
│ └─────────────────────────────────────────────────────────┘ │
|
|
42
|
+
│ ↓ │
|
|
43
|
+
│ ┌─────────────────────────────────────────────────────────┐ │
|
|
44
|
+
│ │ DynamicConnector │ │
|
|
45
|
+
│ │ Request time dynamic connect → Execute → Disconnect │ │
|
|
46
|
+
│ └─────────────────────────────────────────────────────────┘ │
|
|
47
|
+
└─────────────────────────────────────────────────────────────┘
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## 📋 Detailed Design Plan
|
|
51
|
+
|
|
52
|
+
### 1. V2 Pipeline Assembler (Simplified Version)
|
|
53
|
+
|
|
54
|
+
#### 1.1 Prerun Validation Mechanism
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
// src/modules/pipeline/v2/config/v2-pipeline-assembler.ts
|
|
58
|
+
export class V2PipelineAssembler {
|
|
59
|
+
constructor(
|
|
60
|
+
private staticInstancePool: StaticInstancePool,
|
|
61
|
+
private configValidator: V2ConfigValidator
|
|
62
|
+
) {}
|
|
63
|
+
|
|
64
|
+
// Assemble pipeline (validation only, no connection)
|
|
65
|
+
async assemble(mergedConfig: MergedConfig): Promise<V2AssembledPipelines> {
|
|
66
|
+
// 1. Convert V1 configuration to V2 format
|
|
67
|
+
const v2Config = this.migrateV1ToV2(mergedConfig);
|
|
68
|
+
|
|
69
|
+
// 2. Validate V2 configuration integrity
|
|
70
|
+
await this.validateV2Config(v2Config);
|
|
71
|
+
|
|
72
|
+
// 3. Check required modules are statically loaded
|
|
73
|
+
await this.verifyStaticInstances(v2Config);
|
|
74
|
+
|
|
75
|
+
// 4. Prerun pipeline route validation
|
|
76
|
+
await this.preRunRoutes(v2Config);
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
v2Config,
|
|
80
|
+
staticInstancePool: this.staticInstancePool,
|
|
81
|
+
routeTable: v2Config.virtualPipelines.routeTable,
|
|
82
|
+
isReady: true
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Prerun all routes (dry run mode, no actual execution)
|
|
87
|
+
private async preRunRoutes(v2Config: V2SystemConfig): Promise<PreRunReport> {
|
|
88
|
+
const report: PreRunReport = {
|
|
89
|
+
totalRoutes: 0,
|
|
90
|
+
successfulRoutes: 0,
|
|
91
|
+
failedRoutes: [],
|
|
92
|
+
warnings: []
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const { routeTable } = v2Config.virtualPipelines;
|
|
96
|
+
report.totalRoutes = routeTable.routes.length;
|
|
97
|
+
|
|
98
|
+
// Create mock requests for dry run
|
|
99
|
+
for (const route of routeTable.routes) {
|
|
100
|
+
try {
|
|
101
|
+
await this.preRunSingleRoute(route);
|
|
102
|
+
report.successfulRoutes++;
|
|
103
|
+
} catch (error) {
|
|
104
|
+
report.failedRoutes.push({
|
|
105
|
+
routeId: route.id,
|
|
106
|
+
error: error.message,
|
|
107
|
+
recoverable: this.isRecoverableError(error)
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return report;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Single route prerun
|
|
116
|
+
private async preRunSingleRoute(route: RouteDefinition): Promise<void> {
|
|
117
|
+
// 1. Validate route pattern matching
|
|
118
|
+
this.validateRoutePattern(route);
|
|
119
|
+
|
|
120
|
+
// 2. Verify all module instances available
|
|
121
|
+
for (const moduleSpec of route.modules) {
|
|
122
|
+
const config = this.resolveModuleConfig(moduleSpec);
|
|
123
|
+
const instance = this.staticInstancePool.getInstance(moduleSpec.type, config);
|
|
124
|
+
|
|
125
|
+
// Check instance health status
|
|
126
|
+
if (!await this.isInstanceHealthy(instance)) {
|
|
127
|
+
throw new Error(`Module instance ${moduleSpec.type} is not healthy`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// 3. Simulate data flow validation (dry run)
|
|
132
|
+
await this.simulateDataFlow(route);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Simulate data flow validation
|
|
136
|
+
private async simulateDataFlow(route: RouteDefinition): Promise<void> {
|
|
137
|
+
const mockRequest = this.createMockRequest(route);
|
|
138
|
+
const mockContext = { dryRun: true, routeId: route.id };
|
|
139
|
+
|
|
140
|
+
// Verify each module's input-output compatibility in order
|
|
141
|
+
let currentData = mockRequest;
|
|
142
|
+
|
|
143
|
+
for (let i = 0; i < route.modules.length; i++) {
|
|
144
|
+
const moduleSpec = route.modules[i];
|
|
145
|
+
const config = this.resolveModuleConfig(moduleSpec);
|
|
146
|
+
const instance = this.staticInstancePool.getInstance(moduleSpec.type, config);
|
|
147
|
+
|
|
148
|
+
try {
|
|
149
|
+
// Dry run mode, modules only do format validation, no actual processing
|
|
150
|
+
const validatedData = await instance.validateInput(currentData, mockContext);
|
|
151
|
+
currentData = validatedData;
|
|
152
|
+
} catch (error) {
|
|
153
|
+
throw new Error(`Data flow validation failed at module ${moduleSpec.type}: ${error.message}`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
#### 1.2 V1 Configuration Auto Migration
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
// src/modules/pipeline/v2/config/v1-migrator.ts
|
|
164
|
+
export class V1ToV2Migrator {
|
|
165
|
+
// Auto migrate V1 configuration to V2 static instance configuration
|
|
166
|
+
static migrate(mergedConfig: MergedConfig): V2SystemConfig {
|
|
167
|
+
return {
|
|
168
|
+
version: '2.0',
|
|
169
|
+
|
|
170
|
+
// System configuration (default V2 mode)
|
|
171
|
+
system: {
|
|
172
|
+
mode: 'v2',
|
|
173
|
+
enableDryRun: true,
|
|
174
|
+
featureFlags: {
|
|
175
|
+
dynamicConnection: true,
|
|
176
|
+
staticInstancePool: true,
|
|
177
|
+
preRunValidation: true
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
|
|
181
|
+
// Static instance pool configuration (generated based on V1 configuration)
|
|
182
|
+
staticInstances: {
|
|
183
|
+
preloadModules: this.extractRequiredModules(mergedConfig),
|
|
184
|
+
poolConfig: {
|
|
185
|
+
maxInstancesPerType: 10,
|
|
186
|
+
warmupInstances: this.calculateWarmupCount(mergedConfig),
|
|
187
|
+
idleTimeout: 300000 // 5 minutes
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
|
|
191
|
+
// Virtual pipeline configuration (converted from V1 routePools)
|
|
192
|
+
virtualPipelines: {
|
|
193
|
+
routeTable: this.convertRoutePoolsToRoutes(mergedConfig),
|
|
194
|
+
moduleRegistry: {
|
|
195
|
+
providers: this.extractProviderConfigs(mergedConfig),
|
|
196
|
+
compatibility: this.extractCompatibilityConfigs(mergedConfig),
|
|
197
|
+
llmSwitch: this.extractLLMSwitchConfigs(mergedConfig)
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
|
|
201
|
+
// Keep original configuration for rollback
|
|
202
|
+
legacy: mergedConfig
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Convert V1 routePools to V2 routing table
|
|
207
|
+
private static convertRoutePoolsToRoutes(mergedConfig: MergedConfig): RouteTableConfig {
|
|
208
|
+
const pac = this.asRecord(this.asRecord(mergedConfig.pipeline_assembler).config);
|
|
209
|
+
const legacyRoutePools = pac.routePools as Record<string, string[]> || {};
|
|
210
|
+
const legacyRouteMeta = pac.routeMeta as Record<string, any> || {};
|
|
211
|
+
|
|
212
|
+
const routes: RouteDefinition[] = [];
|
|
213
|
+
|
|
214
|
+
// Create route definition for each routing category
|
|
215
|
+
for (const [routeName, pipelineIds] of Object.entries(legacyRoutePools)) {
|
|
216
|
+
for (const pipelineId of pipelineIds) {
|
|
217
|
+
const route = this.createRouteFromLegacy(pipelineId, routeName, legacyRouteMeta);
|
|
218
|
+
routes.push(route);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return {
|
|
223
|
+
routes,
|
|
224
|
+
defaultRoute: 'default',
|
|
225
|
+
// Note: No fallback strategies - fail fast when routing fails
|
|
226
|
+
// Mode switching must be explicit operator action
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Create V2 route from Legacy pipeline ID
|
|
231
|
+
private static createRouteFromLegacy(
|
|
232
|
+
pipelineId: string,
|
|
233
|
+
routeName: string,
|
|
234
|
+
routeMeta: Record<string, any>
|
|
235
|
+
): RouteDefinition {
|
|
236
|
+
// Parse Legacy ID (e.g.: glm_key1.glm-4.5-air)
|
|
237
|
+
const parsed = this.parseLegacyPipelineId(pipelineId);
|
|
238
|
+
|
|
239
|
+
return {
|
|
240
|
+
id: `${routeName}-${pipelineId}`,
|
|
241
|
+
pattern: {
|
|
242
|
+
// Match based on model ID and provider characteristics
|
|
243
|
+
model: new RegExp(`^${parsed.modelId}$`),
|
|
244
|
+
provider: parsed.provider
|
|
245
|
+
},
|
|
246
|
+
modules: [
|
|
247
|
+
{
|
|
248
|
+
type: 'provider',
|
|
249
|
+
config: `${parsed.provider}-provider-config`
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
type: 'compatibility',
|
|
253
|
+
config: `${parsed.provider}-compatibility-config`
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
type: 'llmSwitch',
|
|
257
|
+
config: 'conversion-router-config'
|
|
258
|
+
}
|
|
259
|
+
],
|
|
260
|
+
priority: this.calculateRoutePriority(routeName),
|
|
261
|
+
metadata: routeMeta[pipelineId] || {}
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Extract required module types
|
|
266
|
+
private static extractRequiredModules(mergedConfig: MergedConfig): string[] {
|
|
267
|
+
const modules = new Set<string>();
|
|
268
|
+
|
|
269
|
+
// Analyze module types used in all routes
|
|
270
|
+
const routeTable = this.convertRoutePoolsToRoutes(mergedConfig);
|
|
271
|
+
for (const route of routeTable.routes) {
|
|
272
|
+
for (const module of route.modules) {
|
|
273
|
+
modules.add(module.type);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return Array.from(modules);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### 2. Dynamic Connector Design
|
|
283
|
+
|
|
284
|
+
#### 2.1 Runtime Dynamic Connection
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
// src/modules/pipeline/v2/core/dynamic-connector.ts
|
|
288
|
+
export class DynamicConnector {
|
|
289
|
+
// Handle request (dynamic connection mode)
|
|
290
|
+
async handleRequest(
|
|
291
|
+
request: PipelineRequest,
|
|
292
|
+
v2Config: V2SystemConfig,
|
|
293
|
+
staticInstancePool: StaticInstancePool
|
|
294
|
+
): Promise<PipelineResponse> {
|
|
295
|
+
// 1. Route matching
|
|
296
|
+
const route = this.matchRoute(request, v2Config.virtualPipelines.routeTable);
|
|
297
|
+
|
|
298
|
+
// 2. Dynamic connect modules (only connection, no instance creation)
|
|
299
|
+
const connection = await this.connectModules(route, staticInstancePool);
|
|
300
|
+
|
|
301
|
+
try {
|
|
302
|
+
// 3. Execute pipeline processing
|
|
303
|
+
const response = await this.executeConnectedModules(connection, request);
|
|
304
|
+
return response;
|
|
305
|
+
} finally {
|
|
306
|
+
// 4. Disconnect connection (keep instances)
|
|
307
|
+
await this.disconnectModules(connection);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// Dynamic connect modules (core: only increase connection process)
|
|
312
|
+
private async connectModules(
|
|
313
|
+
route: RouteDefinition,
|
|
314
|
+
staticInstancePool: StaticInstancePool
|
|
315
|
+
): Promise<ModuleConnection> {
|
|
316
|
+
const instances: ModuleInstance[] = [];
|
|
317
|
+
const connections: InstanceConnection[] = [];
|
|
318
|
+
|
|
319
|
+
// 1. Get all required module instances (from static pool)
|
|
320
|
+
for (const moduleSpec of route.modules) {
|
|
321
|
+
const config = this.resolveModuleConfig(moduleSpec);
|
|
322
|
+
const instance = staticInstancePool.getInstance(moduleSpec.type, config);
|
|
323
|
+
instances.push(instance);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// 2. Create temporary connections (this is "only increase connection process")
|
|
327
|
+
for (let i = 0; i < instances.length - 1; i++) {
|
|
328
|
+
const from = instances[i];
|
|
329
|
+
const to = instances[i + 1];
|
|
330
|
+
|
|
331
|
+
// Create lightweight connection
|
|
332
|
+
const connection = new InstanceConnection(from, to, {
|
|
333
|
+
connectionId: `${route.id}-${i}`,
|
|
334
|
+
temporary: true,
|
|
335
|
+
metadata: { routeId: route.id, position: i }
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
connections.push(connection);
|
|
339
|
+
|
|
340
|
+
// Establish connection
|
|
341
|
+
await this.establishConnection(connection);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
return new ModuleConnection(route.id, instances, connections);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Establish connection
|
|
348
|
+
private async establishConnection(connection: InstanceConnection): Promise<void> {
|
|
349
|
+
// Set output to next module's pipeline
|
|
350
|
+
connection.from.setOutputTarget(connection.to);
|
|
351
|
+
|
|
352
|
+
// Set input from previous module's pipeline
|
|
353
|
+
connection.to.setInputSource(connection.from);
|
|
354
|
+
|
|
355
|
+
// Connection ready notification
|
|
356
|
+
await connection.onConnect();
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// Execute connected modules
|
|
360
|
+
private async executeConnectedModules(
|
|
361
|
+
connection: ModuleConnection,
|
|
362
|
+
request: PipelineRequest
|
|
363
|
+
): Promise<PipelineResponse> {
|
|
364
|
+
const { instances } = connection;
|
|
365
|
+
let currentData = request;
|
|
366
|
+
|
|
367
|
+
// Execute connected modules in order
|
|
368
|
+
for (let i = 0; i < instances.length; i++) {
|
|
369
|
+
const instance = instances[i];
|
|
370
|
+
|
|
371
|
+
try {
|
|
372
|
+
// Pass data through connection
|
|
373
|
+
currentData = await instance.processIncoming(currentData, {
|
|
374
|
+
connectionId: connection.id,
|
|
375
|
+
position: i,
|
|
376
|
+
totalModules: instances.length
|
|
377
|
+
});
|
|
378
|
+
} catch (error) {
|
|
379
|
+
// Connection level error handling (fail fast with full context)
|
|
380
|
+
const structuredError = new V2ConnectionError(
|
|
381
|
+
`Connection failed at position ${i} in chain ${connection.id}`,
|
|
382
|
+
{
|
|
383
|
+
connectionId: connection.id,
|
|
384
|
+
position: i,
|
|
385
|
+
moduleType: instances[i]?.type,
|
|
386
|
+
moduleId: instances[i]?.id,
|
|
387
|
+
originalError: error.message,
|
|
388
|
+
timestamp: new Date().toISOString()
|
|
389
|
+
}
|
|
390
|
+
);
|
|
391
|
+
|
|
392
|
+
// Log detailed error information
|
|
393
|
+
logger.error('V2 connection error', {
|
|
394
|
+
error: structuredError.toJSON(),
|
|
395
|
+
requestId: connection.metadata?.requestId,
|
|
396
|
+
routeId: connection.metadata?.routeId
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
// Fail fast - no recovery attempts
|
|
400
|
+
throw structuredError;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
return currentData as PipelineResponse;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// Disconnect connection (keep instances)
|
|
408
|
+
private async disconnectModules(connection: ModuleConnection): Promise<void> {
|
|
409
|
+
// Only disconnect, don't destroy instances
|
|
410
|
+
for (const instanceConnection of connection.connections) {
|
|
411
|
+
await this.breakConnection(instanceConnection);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// Break single connection
|
|
416
|
+
private async breakConnection(connection: InstanceConnection): Promise<void> {
|
|
417
|
+
// Clear output target
|
|
418
|
+
connection.from.clearOutputTarget();
|
|
419
|
+
|
|
420
|
+
// Clear input source
|
|
421
|
+
connection.to.clearInputSource();
|
|
422
|
+
|
|
423
|
+
// Disconnect notification
|
|
424
|
+
await connection.onDisconnect();
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
#### 2.2 Connection State Management
|
|
430
|
+
|
|
431
|
+
```typescript
|
|
432
|
+
// src/modules/pipeline/v2/core/module-connection.ts
|
|
433
|
+
export class ModuleConnection {
|
|
434
|
+
constructor(
|
|
435
|
+
public readonly id: string,
|
|
436
|
+
public readonly instances: ModuleInstance[],
|
|
437
|
+
public readonly connections: InstanceConnection[]
|
|
438
|
+
) {}
|
|
439
|
+
|
|
440
|
+
// Connection status query
|
|
441
|
+
getConnectionStatus(): ConnectionStatus {
|
|
442
|
+
return {
|
|
443
|
+
id: this.id,
|
|
444
|
+
instanceCount: this.instances.length,
|
|
445
|
+
connectionCount: this.connections.length,
|
|
446
|
+
allConnected: this.connections.every(c => c.isConnected()),
|
|
447
|
+
establishedAt: this.connections[0]?.establishedAt,
|
|
448
|
+
metadata: this.getMetadata()
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// Get connection metadata
|
|
453
|
+
private getMetadata(): Record<string, any> {
|
|
454
|
+
return {
|
|
455
|
+
modules: this.instances.map(i => ({
|
|
456
|
+
id: i.id,
|
|
457
|
+
type: i.type,
|
|
458
|
+
healthy: i.isHealthy()
|
|
459
|
+
})),
|
|
460
|
+
connections: this.connections.map(c => ({
|
|
461
|
+
from: c.from.id,
|
|
462
|
+
to: c.to.id,
|
|
463
|
+
connected: c.isConnected(),
|
|
464
|
+
latency: c.getLatency()
|
|
465
|
+
}))
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
export class InstanceConnection {
|
|
471
|
+
private isConnectedFlag = false;
|
|
472
|
+
private establishedAt?: number;
|
|
473
|
+
private latency = 0;
|
|
474
|
+
|
|
475
|
+
constructor(
|
|
476
|
+
public readonly from: ModuleInstance,
|
|
477
|
+
public readonly to: ModuleInstance,
|
|
478
|
+
public readonly options: ConnectionOptions
|
|
479
|
+
) {}
|
|
480
|
+
|
|
481
|
+
// Connection ready callback
|
|
482
|
+
async onConnect(): Promise<void> {
|
|
483
|
+
this.isConnectedFlag = true;
|
|
484
|
+
this.establishedAt = Date.now();
|
|
485
|
+
|
|
486
|
+
// Trigger connection establishment event
|
|
487
|
+
await this.from.onConnected?.(this.to);
|
|
488
|
+
await this.to.onConnected?.(this.from);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// Disconnect callback
|
|
492
|
+
async onDisconnect(): Promise<void> {
|
|
493
|
+
this.isConnectedFlag = false;
|
|
494
|
+
|
|
495
|
+
// Trigger connection disconnection event
|
|
496
|
+
await this.from.onDisconnected?.(this.to);
|
|
497
|
+
await this.to.onDisconnected?.(this.from);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
// Check connection status
|
|
501
|
+
isConnected(): boolean {
|
|
502
|
+
return this.isConnectedFlag &&
|
|
503
|
+
this.from.isHealthy() &&
|
|
504
|
+
this.to.isHealthy();
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// Get connection latency
|
|
508
|
+
getLatency(): number {
|
|
509
|
+
return this.latency;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
### 3. V1/V2 Switch Mechanism
|
|
515
|
+
|
|
516
|
+
#### 3.1 Gradual Switch
|
|
517
|
+
|
|
518
|
+
```typescript
|
|
519
|
+
// src/core/v1-v2-switch.ts
|
|
520
|
+
export class V1V2ModeSwitch {
|
|
521
|
+
private currentMode: 'v1' | 'v2' = 'v1';
|
|
522
|
+
private v1Assembler?: V1PipelineAssembler;
|
|
523
|
+
private v2Assembler?: V2PipelineAssembler;
|
|
524
|
+
private dynamicConnector?: DynamicConnector;
|
|
525
|
+
|
|
526
|
+
// Gradual mode switch
|
|
527
|
+
async gradualSwitch(targetMode: 'v1' | 'v2', options: SwitchOptions = {}): Promise<SwitchReport> {
|
|
528
|
+
const report: SwitchReport = {
|
|
529
|
+
from: this.currentMode,
|
|
530
|
+
to: targetMode,
|
|
531
|
+
startTime: Date.now(),
|
|
532
|
+
steps: [],
|
|
533
|
+
success: false,
|
|
534
|
+
error: undefined
|
|
535
|
+
};
|
|
536
|
+
|
|
537
|
+
try {
|
|
538
|
+
if (targetMode === 'v2' && this.currentMode === 'v1') {
|
|
539
|
+
// V1 → V2 switch process
|
|
540
|
+
await this.switchToV2(report, options);
|
|
541
|
+
} else if (targetMode === 'v1' && this.currentMode === 'v2') {
|
|
542
|
+
// V2 → V1 switch process
|
|
543
|
+
await this.switchToV1(report, options);
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
report.success = true;
|
|
547
|
+
this.currentMode = targetMode;
|
|
548
|
+
|
|
549
|
+
} catch (error) {
|
|
550
|
+
report.error = error.message;
|
|
551
|
+
|
|
552
|
+
// Manual rollback only - no auto fallback
|
|
553
|
+
if (options.manualRollback) {
|
|
554
|
+
await this.executeManualRollback(report);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
// Fail fast - expose problem immediately
|
|
558
|
+
throw new Error(`V2 switch failed: ${error.message}. Manual intervention required.`);
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
report.endTime = Date.now();
|
|
562
|
+
report.duration = report.endTime - report.startTime;
|
|
563
|
+
|
|
564
|
+
return report;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
// V1 → V2 switch
|
|
568
|
+
private async switchToV2(report: SwitchReport, options: SwitchOptions): Promise<void> {
|
|
569
|
+
// Step 1: Initialize V2 assembler
|
|
570
|
+
report.steps.push('initializing-v2-assembler');
|
|
571
|
+
this.v2Assembler = new V2PipelineAssembler(
|
|
572
|
+
new StaticInstancePool(),
|
|
573
|
+
new V2ConfigValidator()
|
|
574
|
+
);
|
|
575
|
+
|
|
576
|
+
// Step 2: Migrate configuration and prerun validation
|
|
577
|
+
report.steps.push('migrating-and-validating-config');
|
|
578
|
+
const v2Assembled = await this.v2Assembler.assemble(this.getCurrentConfig());
|
|
579
|
+
|
|
580
|
+
if (!v2Assembled.isReady) {
|
|
581
|
+
throw new Error('V2 pre-run validation failed');
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// Step 3: Initialize dynamic connector
|
|
585
|
+
report.steps.push('initializing-dynamic-connector');
|
|
586
|
+
this.dynamicConnector = new DynamicConnector();
|
|
587
|
+
|
|
588
|
+
// Step 4: Verify V2 compatibility (optional)
|
|
589
|
+
if (options.validateCompatibility) {
|
|
590
|
+
report.steps.push('validating-v2-compatibility');
|
|
591
|
+
await this.validateV2Compatibility(v2Assembled);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
// Step 5: Gradual traffic switch (if enabled)
|
|
595
|
+
if (options.trafficShift) {
|
|
596
|
+
report.steps.push('gradual-traffic-shift');
|
|
597
|
+
await this.gradualTrafficShift(v2Assembled, options);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
// Request handling (auto route to current mode)
|
|
602
|
+
async handleRequest(request: PipelineRequest): Promise<PipelineResponse> {
|
|
603
|
+
if (this.currentMode === 'v1') {
|
|
604
|
+
return this.v1Assembler!.handleRequest(request);
|
|
605
|
+
} else {
|
|
606
|
+
return this.dynamicConnector!.handleRequest(
|
|
607
|
+
request,
|
|
608
|
+
this.v2Assembler!.getV2Config(),
|
|
609
|
+
this.v2Assembler!.getStaticInstancePool()
|
|
610
|
+
);
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
// Verify V2 compatibility
|
|
615
|
+
private async validateV2Compatibility(v2Assembled: V2AssembledPipelines): Promise<void> {
|
|
616
|
+
// Use same request to execute in both V1 and V2 modes
|
|
617
|
+
// Compare results to ensure compatibility
|
|
618
|
+
const testRequests = this.generateCompatibilityTestRequests();
|
|
619
|
+
|
|
620
|
+
for (const testRequest of testRequests) {
|
|
621
|
+
const v1Response = await this.v1Assembler!.handleRequest(testRequest);
|
|
622
|
+
const v2Response = await this.dynamicConnector!.handleRequest(
|
|
623
|
+
testRequest,
|
|
624
|
+
v2Assembled.v2Config,
|
|
625
|
+
v2Assembled.staticInstancePool
|
|
626
|
+
);
|
|
627
|
+
|
|
628
|
+
// Compare responses
|
|
629
|
+
const compatibility = this.compareResponses(v1Response, v2Response);
|
|
630
|
+
if (!compatibility.compatible) {
|
|
631
|
+
throw new Error(`V2 compatibility issue: ${compatibility.differences.join(', ')}`);
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
```
|
|
637
|
+
|
|
638
|
+
### 4. Configuration Validation and Prerun Tools
|
|
639
|
+
|
|
640
|
+
#### 4.1 Prerun Validation Tools
|
|
641
|
+
|
|
642
|
+
```typescript
|
|
643
|
+
// src/tools/pre-run-validator.ts
|
|
644
|
+
export class PreRunValidator {
|
|
645
|
+
// Comprehensive prerun validation
|
|
646
|
+
async validateV2Setup(v2Config: V2SystemConfig): Promise<ValidationReport> {
|
|
647
|
+
const report: ValidationReport = {
|
|
648
|
+
configValidation: await this.validateConfig(v2Config),
|
|
649
|
+
instanceValidation: await this.validateInstances(v2Config),
|
|
650
|
+
routeValidation: await this.validateRoutes(v2Config),
|
|
651
|
+
dataFlowValidation: await this.validateDataFlow(v2Config),
|
|
652
|
+
performanceValidation: await this.validatePerformance(v2Config)
|
|
653
|
+
};
|
|
654
|
+
|
|
655
|
+
return report;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
// Route validation
|
|
659
|
+
private async validateRoutes(v2Config: V2SystemConfig): Promise<RouteValidationResult> {
|
|
660
|
+
const results: RouteTestResult[] = [];
|
|
661
|
+
|
|
662
|
+
for (const route of v2Config.virtualPipelines.routeTable.routes) {
|
|
663
|
+
const result = await this.testRoute(route);
|
|
664
|
+
results.push(result);
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
return {
|
|
668
|
+
totalRoutes: results.length,
|
|
669
|
+
successfulRoutes: results.filter(r => r.success).length,
|
|
670
|
+
failedRoutes: results.filter(r => !r.success),
|
|
671
|
+
results
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
// Data flow validation
|
|
676
|
+
private async validateDataFlow(v2Config: V2SystemConfig): Promise<DataFlowValidationResult> {
|
|
677
|
+
const testData = this.generateTestData();
|
|
678
|
+
const results: DataFlowTestResult[] = [];
|
|
679
|
+
|
|
680
|
+
for (const test of testData) {
|
|
681
|
+
// Simulate complete request-response flow
|
|
682
|
+
const result = await this.simulateCompleteFlow(test, v2Config);
|
|
683
|
+
results.push(result);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
return {
|
|
687
|
+
totalTests: results.length,
|
|
688
|
+
successfulTests: results.filter(r => r.success).length,
|
|
689
|
+
failedTests: results.filter(r => !r.success),
|
|
690
|
+
results
|
|
691
|
+
};
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
## 🎯 Key Advantages
|
|
697
|
+
|
|
698
|
+
### Migration Advantages
|
|
699
|
+
1. **Zero Configuration Migration**: V1 configuration auto-converts to V2 static instance configuration
|
|
700
|
+
2. **Prerun Validation**: Verify all routes and data flow compatibility before switching
|
|
701
|
+
3. **Gradual Switch**: Support gradual traffic switching, can rollback anytime
|
|
702
|
+
4. **Compatibility Guarantee**: V2 and V1 results completely identical validation
|
|
703
|
+
|
|
704
|
+
### Performance Advantages
|
|
705
|
+
1. **Only Add Connection**: Switch process only adds connections, no reassembly or reinitialization
|
|
706
|
+
2. **Static Instances**: All modules preloaded, zero cold start latency
|
|
707
|
+
3. **Lightweight Connection**: Temporary connection establishment/disconnection overhead is minimal
|
|
708
|
+
4. **Instance Reuse**: Same configuration shared instances between different routes
|
|
709
|
+
|
|
710
|
+
### Operations Advantages
|
|
711
|
+
1. **Visualization Validation**: Prerun report clearly shows compatibility status
|
|
712
|
+
2. **Complete Monitoring**: Connection status, instance status, performance metrics full coverage
|
|
713
|
+
3. **Fault Isolation**: Single connection failure doesn't affect overall system
|
|
714
|
+
4. **Fast Rollback**: Can immediately switch back to V1 mode when problems found
|
|
715
|
+
|
|
716
|
+
This design ensures V2 and V1 seamless migration while guaranteeing zero-risk switching through prerun validation mechanism.
|