@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,227 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.0.0",
|
|
3
|
+
"description": "OpenAI to iFlow compatibility mapping table based on Claude Code Router architecture",
|
|
4
|
+
"formats": {
|
|
5
|
+
"source": "openai",
|
|
6
|
+
"target": "iflow"
|
|
7
|
+
},
|
|
8
|
+
"metadata": {
|
|
9
|
+
"created": "2024-01-01T00:00:00Z",
|
|
10
|
+
"updated": "2024-01-01T00:00:00Z",
|
|
11
|
+
"author": "RCC System",
|
|
12
|
+
"architecture": "agent-based",
|
|
13
|
+
"basedOn": "claude-code-router"
|
|
14
|
+
},
|
|
15
|
+
"fieldMappings": {
|
|
16
|
+
"id": {
|
|
17
|
+
"targetField": "taskId",
|
|
18
|
+
"transform": "directMapping",
|
|
19
|
+
"required": true,
|
|
20
|
+
"description": "Map OpenAI request ID to iFlow task ID"
|
|
21
|
+
},
|
|
22
|
+
"model": {
|
|
23
|
+
"targetField": "agentId",
|
|
24
|
+
"transform": "mapModelToAgent",
|
|
25
|
+
"required": true,
|
|
26
|
+
"description": "Map OpenAI model to iFlow agent ID"
|
|
27
|
+
},
|
|
28
|
+
"messages": {
|
|
29
|
+
"targetField": "messages",
|
|
30
|
+
"transform": "messageFormatConversion",
|
|
31
|
+
"required": true,
|
|
32
|
+
"description": "Convert OpenAI message format to iFlow message format"
|
|
33
|
+
},
|
|
34
|
+
"tools": {
|
|
35
|
+
"targetField": "tools",
|
|
36
|
+
"transform": "toolFormatConversion",
|
|
37
|
+
"description": "Convert OpenAI tool format to iFlow tool format"
|
|
38
|
+
},
|
|
39
|
+
"tool_choice": {
|
|
40
|
+
"targetField": "tool_choice",
|
|
41
|
+
"transform": "toolChoiceConversion",
|
|
42
|
+
"defaultValue": "auto",
|
|
43
|
+
"description": "Tool choice strategy"
|
|
44
|
+
},
|
|
45
|
+
"temperature": {
|
|
46
|
+
"targetField": "temperature",
|
|
47
|
+
"transform": "directMapping",
|
|
48
|
+
"defaultValue": 0.7,
|
|
49
|
+
"description": "Temperature parameter for response randomness"
|
|
50
|
+
},
|
|
51
|
+
"max_tokens": {
|
|
52
|
+
"targetField": "maxTokens",
|
|
53
|
+
"transform": "directMapping",
|
|
54
|
+
"description": "Maximum number of tokens to generate"
|
|
55
|
+
},
|
|
56
|
+
"top_p": {
|
|
57
|
+
"targetField": "parameters.top_p",
|
|
58
|
+
"transform": "directMapping",
|
|
59
|
+
"defaultValue": 1.0,
|
|
60
|
+
"description": "Nucleus sampling parameter"
|
|
61
|
+
},
|
|
62
|
+
"frequency_penalty": {
|
|
63
|
+
"targetField": "parameters.frequency_penalty",
|
|
64
|
+
"transform": "directMapping",
|
|
65
|
+
"defaultValue": 0.0,
|
|
66
|
+
"description": "Frequency penalty for token repetition"
|
|
67
|
+
},
|
|
68
|
+
"presence_penalty": {
|
|
69
|
+
"targetField": "parameters.presence_penalty",
|
|
70
|
+
"transform": "directMapping",
|
|
71
|
+
"defaultValue": 0.0,
|
|
72
|
+
"description": "Presence penalty for new topics"
|
|
73
|
+
},
|
|
74
|
+
"stop": {
|
|
75
|
+
"targetField": "parameters.stop",
|
|
76
|
+
"transform": "arrayMapping",
|
|
77
|
+
"description": "Stop sequences for generation"
|
|
78
|
+
},
|
|
79
|
+
"stream": {
|
|
80
|
+
"targetField": "streaming",
|
|
81
|
+
"transform": "directMapping",
|
|
82
|
+
"defaultValue": false,
|
|
83
|
+
"description": "Enable streaming response"
|
|
84
|
+
},
|
|
85
|
+
"user": {
|
|
86
|
+
"targetField": "userId",
|
|
87
|
+
"transform": "mapUserId",
|
|
88
|
+
"description": "User identifier"
|
|
89
|
+
},
|
|
90
|
+
"metadata": {
|
|
91
|
+
"targetField": "metadata",
|
|
92
|
+
"transform": "extractMetadata",
|
|
93
|
+
"description": "Extract and map metadata fields"
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
"validationRules": {
|
|
97
|
+
"required": ["id", "model", "messages"],
|
|
98
|
+
"types": {
|
|
99
|
+
"id": "string",
|
|
100
|
+
"model": "string",
|
|
101
|
+
"messages": "array",
|
|
102
|
+
"temperature": "number",
|
|
103
|
+
"max_tokens": "number",
|
|
104
|
+
"top_p": "number",
|
|
105
|
+
"frequency_penalty": "number",
|
|
106
|
+
"presence_penalty": "number",
|
|
107
|
+
"stream": "boolean",
|
|
108
|
+
"user": "string",
|
|
109
|
+
"tools": "array",
|
|
110
|
+
"tool_choice": "string",
|
|
111
|
+
"streaming": "boolean",
|
|
112
|
+
"maxTokens": "number",
|
|
113
|
+
"userId": "string",
|
|
114
|
+
"taskId": "string",
|
|
115
|
+
"agentId": "string"
|
|
116
|
+
},
|
|
117
|
+
"constraints": {
|
|
118
|
+
"id": {
|
|
119
|
+
"pattern": "^[a-zA-Z0-9-_]+$",
|
|
120
|
+
"minLength": 1,
|
|
121
|
+
"maxLength": 100
|
|
122
|
+
},
|
|
123
|
+
"model": {
|
|
124
|
+
"pattern": "^[a-zA-Z0-9-_]+$",
|
|
125
|
+
"minLength": 1,
|
|
126
|
+
"maxLength": 100
|
|
127
|
+
},
|
|
128
|
+
"messages": {
|
|
129
|
+
"minLength": 1,
|
|
130
|
+
"maxLength": 100
|
|
131
|
+
},
|
|
132
|
+
"max_tokens": {
|
|
133
|
+
"min": 1,
|
|
134
|
+
"max": 200000
|
|
135
|
+
},
|
|
136
|
+
"temperature": {
|
|
137
|
+
"min": 0.0,
|
|
138
|
+
"max": 2.0
|
|
139
|
+
},
|
|
140
|
+
"top_p": {
|
|
141
|
+
"min": 0.0,
|
|
142
|
+
"max": 1.0
|
|
143
|
+
},
|
|
144
|
+
"frequency_penalty": {
|
|
145
|
+
"min": -2.0,
|
|
146
|
+
"max": 2.0
|
|
147
|
+
},
|
|
148
|
+
"presence_penalty": {
|
|
149
|
+
"min": -2.0,
|
|
150
|
+
"max": 2.0
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
"transformFunctions": {
|
|
155
|
+
"mapModelToAgent": {
|
|
156
|
+
"type": "mapping",
|
|
157
|
+
"description": "Map OpenAI models to iFlow agent IDs",
|
|
158
|
+
"mappings": {
|
|
159
|
+
"gpt-4o": "multimodal-agent",
|
|
160
|
+
"gpt-4o-mini": "text-agent",
|
|
161
|
+
"gpt-4-turbo": "reasoning-agent",
|
|
162
|
+
"gpt-4": "analysis-agent",
|
|
163
|
+
"gpt-3.5-turbo": "chat-agent",
|
|
164
|
+
"gpt-4-vision-preview": "image-agent",
|
|
165
|
+
"claude-3-5-sonnet-20241022": "reasoning-agent",
|
|
166
|
+
"claude-3-5-haiku-20241022": "text-agent"
|
|
167
|
+
},
|
|
168
|
+
"defaultValue": "text-agent"
|
|
169
|
+
},
|
|
170
|
+
"messageFormatConversion": {
|
|
171
|
+
"type": "object_transform",
|
|
172
|
+
"description": "Convert OpenAI message format to iFlow format",
|
|
173
|
+
"roleMapping": {
|
|
174
|
+
"system": "system",
|
|
175
|
+
"user": "user",
|
|
176
|
+
"assistant": "assistant",
|
|
177
|
+
"tool": "tool"
|
|
178
|
+
},
|
|
179
|
+
"contentProcessing": {
|
|
180
|
+
"preserveStructure": true,
|
|
181
|
+
"handleMultimodal": true,
|
|
182
|
+
"agentContentHandling": true
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
"toolFormatConversion": {
|
|
186
|
+
"type": "array_transform",
|
|
187
|
+
"description": "Convert OpenAI tool format to iFlow tool format",
|
|
188
|
+
"elementTransform": {
|
|
189
|
+
"type": "object_transform",
|
|
190
|
+
"fields": {
|
|
191
|
+
"type": "type",
|
|
192
|
+
"function": "function"
|
|
193
|
+
},
|
|
194
|
+
"preserveStructure": true,
|
|
195
|
+
"agentToolSchema": true
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
"toolChoiceConversion": {
|
|
199
|
+
"type": "mapping",
|
|
200
|
+
"description": "Convert OpenAI tool choice to iFlow tool choice",
|
|
201
|
+
"mappings": {
|
|
202
|
+
"auto": "auto",
|
|
203
|
+
"none": "none",
|
|
204
|
+
"required": "required"
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
"mapUserId": {
|
|
208
|
+
"type": "transform",
|
|
209
|
+
"description": "Format OpenAI user ID to iFlow format",
|
|
210
|
+
"transformFunction": "formatUserId"
|
|
211
|
+
},
|
|
212
|
+
"extractMetadata": {
|
|
213
|
+
"type": "object_transform",
|
|
214
|
+
"description": "Extract metadata from OpenAI request",
|
|
215
|
+
"extractFields": ["session_info", "timeout", "priority", "context"]
|
|
216
|
+
},
|
|
217
|
+
"directMapping": {
|
|
218
|
+
"type": "direct",
|
|
219
|
+
"description": "No transformation needed - pass through as-is"
|
|
220
|
+
},
|
|
221
|
+
"arrayMapping": {
|
|
222
|
+
"type": "array_transform",
|
|
223
|
+
"description": "Convert array format for iFlow compatibility",
|
|
224
|
+
"preserveElements": true
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Monitoring & Offline Routing Dry‑Run (Design)
|
|
2
|
+
|
|
3
|
+
This document describes a passive monitoring and replay system for RouteCodex.
|
|
4
|
+
|
|
5
|
+
## Goals
|
|
6
|
+
- Zero‑impact observability for OpenAI/Anthropic requests and responses
|
|
7
|
+
- Uniform on‑disk artifacts for offline routing simulation and response replay
|
|
8
|
+
- Not enabled by default; strictly opt‑in when integrated later
|
|
9
|
+
|
|
10
|
+
## Architecture
|
|
11
|
+
- MonitorModule (passive hooks)
|
|
12
|
+
- onIncoming: capture request snapshot + meta
|
|
13
|
+
- onRouteDecision: save online route/pipeline decision if available
|
|
14
|
+
- onOutgoing: save full response (non‑stream)
|
|
15
|
+
- onStreamChunk: append streaming chunks/SSE events to JSONL
|
|
16
|
+
- finalize: update meta with storage details and optional summary
|
|
17
|
+
- Recorder: filesystem writer + redaction utilities
|
|
18
|
+
- VirtualRouterDryRunExecutor: use existing executor to simulate routing for recorded requests
|
|
19
|
+
- ReplayExecutor (future): replay `response.json` or `stream-events.jsonl`
|
|
20
|
+
|
|
21
|
+
## Storage Layout
|
|
22
|
+
Root: `~/.routecodex/monitor/sessions/<YYYYMMDD>/<protocol>/<reqId>/`
|
|
23
|
+
|
|
24
|
+
- `meta.json` — meta + routing snapshot + redaction flags
|
|
25
|
+
- `request.json` — original input (protocol‑native)
|
|
26
|
+
- `request.summary.json` — optional summary for indexing
|
|
27
|
+
- `decision.json` — online routing decision if available
|
|
28
|
+
- `response.json` — non‑stream full response (protocol‑native)
|
|
29
|
+
- `stream-events.jsonl` — streaming chunks/SSE events (one JSON per line)
|
|
30
|
+
- `replay.json` — optional aggregation suitable for direct replay
|
|
31
|
+
- `logs-tail.txt` — optional diagnostics
|
|
32
|
+
|
|
33
|
+
## Redaction & Sampling
|
|
34
|
+
- Never persist Authorization/API keys
|
|
35
|
+
- Optional content redaction for messages/tools (config flag)
|
|
36
|
+
- Optional sampling by rate/provider/route/model
|
|
37
|
+
|
|
38
|
+
## Protocols
|
|
39
|
+
- OpenAI Chat Completions
|
|
40
|
+
- Anthropic Messages
|
|
41
|
+
- Streaming and non‑streaming supported
|
|
42
|
+
|
|
43
|
+
## CLI & Scripts
|
|
44
|
+
- Virtual router dry‑run matrix (no provider calls):
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm run build
|
|
48
|
+
node scripts/virtualrouter-dry-run-matrix.mjs --config ~/.routecodex/config/verified_0.46.32/multi-provider.json
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Integration Plan (Phased)
|
|
52
|
+
1) Skeleton only (this change): code structure + documentation, no runtime wiring
|
|
53
|
+
2) Passive recording (opt‑in) with redaction and sampling
|
|
54
|
+
3) Dry‑run from records + diff report (simulate route vs config)
|
|
55
|
+
4) Replay executor for response (non‑stream & stream)
|
|
56
|
+
|
|
57
|
+
## Invariants
|
|
58
|
+
- Monitoring must not block or slow down the main request path (async writes, backpressure)
|
|
59
|
+
- Recording failures must never propagate to API clients
|
|
60
|
+
- Redaction is enabled by default for credentials
|
|
61
|
+
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Multi-Token Authentication Guide
|
|
2
|
+
|
|
3
|
+
RouteCodex now supports multiple OAuth tokens per provider using a standardized naming convention.
|
|
4
|
+
|
|
5
|
+
## Token File Naming Convention
|
|
6
|
+
|
|
7
|
+
Token files must follow the pattern: `<provider>-oauth-<sequence>[-<alias>].json`
|
|
8
|
+
|
|
9
|
+
Examples:
|
|
10
|
+
- `iflow-oauth-1-primary.json` (sequence 1, alias "primary")
|
|
11
|
+
- `iflow-oauth-2-backup.json` (sequence 2, alias "backup")
|
|
12
|
+
- `qwen-oauth-1-work.json` (sequence 1, alias "work")
|
|
13
|
+
|
|
14
|
+
The `sequence` number determines the order in which tokens are used (1, 2, 3...).
|
|
15
|
+
The `alias` part is optional and ignored by the system - it's just for your reference.
|
|
16
|
+
|
|
17
|
+
## Automatic Discovery
|
|
18
|
+
|
|
19
|
+
The system automatically scans `~/.routecodex/auth/` for token files matching the pattern and creates multiple provider instances. No manual configuration needed.
|
|
20
|
+
|
|
21
|
+
## Authentication Commands
|
|
22
|
+
|
|
23
|
+
### Authenticate specific token:
|
|
24
|
+
```bash
|
|
25
|
+
# Token 1
|
|
26
|
+
IFLOW_TOKEN_FILE="$HOME/.routecodex/auth/iflow-oauth-1-primary.json" node scripts/auth-iflow-token-direct.mjs
|
|
27
|
+
|
|
28
|
+
# Token 2
|
|
29
|
+
IFLOW_TOKEN_FILE="$HOME/.routecodex/auth/iflow-oauth-2-backup.json" node scripts/auth-iflow-token-direct.mjs
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Manual authentication (if device flow fails):
|
|
33
|
+
```bash
|
|
34
|
+
IFLOW_TOKEN_FILE="$HOME/.routecodex/auth/iflow-oauth-1-primary.json" node scripts/auth-iflow-manual.mjs
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Delete and re-authenticate:
|
|
38
|
+
```bash
|
|
39
|
+
rm ~/.routecodex/auth/iflow-oauth-1-primary.json
|
|
40
|
+
IFLOW_TOKEN_FILE="$HOME/.routecodex/auth/iflow-oauth-1-primary.json" node scripts/auth-iflow-token-direct.mjs
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## How It Works
|
|
44
|
+
|
|
45
|
+
1. On startup, RouteCodex scans for all token files matching the pattern
|
|
46
|
+
2. Each token becomes a separate provider instance with keyAlias = sequence number
|
|
47
|
+
3. Routing automatically includes all available tokens in round-robin order
|
|
48
|
+
4. If a token fails, the system tries the next one
|
|
49
|
+
5. Console logs show which token sequence is being used
|
|
50
|
+
|
|
51
|
+
## Troubleshooting
|
|
52
|
+
|
|
53
|
+
- **Token fails**: The system will automatically try the next token in sequence
|
|
54
|
+
- **Need to re-auth**: Delete the token file and run the auth command again
|
|
55
|
+
- **Wrong redirect**: The OAuth callback now shows a success page instead of redirecting to example.com
|
|
56
|
+
|
|
57
|
+
## Provider Support
|
|
58
|
+
|
|
59
|
+
Currently the following providers support multi-token authentication:
|
|
60
|
+
|
|
61
|
+
- iFlow (`iflow-oauth-*.json`)
|
|
62
|
+
- Qwen (`qwen-oauth-*.json`)
|
|
63
|
+
- Gemini CLI (`gemini-oauth-*.json`)
|
|
64
|
+
- Antigravity (`antigravity-oauth-*.json`)
|
|
65
|
+
|
|
66
|
+
Other providers will be added as needed.
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Unified OAuth Authentication System Guide
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The Unified OAuth Authentication System provides a comprehensive solution for managing authentication across multiple AI service providers. It supports both static token files and dynamic OAuth 2.0 flows with automatic token refresh, PKCE security, and unified configuration management.
|
|
6
|
+
|
|
7
|
+
## Architecture
|
|
8
|
+
|
|
9
|
+
### Core Components
|
|
10
|
+
|
|
11
|
+
1. **OAuthConfigManager** - Centralized configuration management
|
|
12
|
+
2. **BaseOAuthManager** - Abstract base class for OAuth implementations
|
|
13
|
+
3. **Provider-specific Managers** - QwenOAuthManager and iFlowOAuthManager
|
|
14
|
+
4. **AuthResolver** - Unified token resolution supporting both static and OAuth
|
|
15
|
+
5. **UserConfigParser** - Extended to support OAuth configuration parsing
|
|
16
|
+
|
|
17
|
+
### Authentication Flow
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
Request → Provider → AuthResolver → OAuth Manager → Token Resolution → Response
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 🔐 iFlow OAuth 实现详解
|
|
24
|
+
|
|
25
|
+
### 核心流程概述
|
|
26
|
+
|
|
27
|
+
iFlow 的 OAuth 实现遵循 **"access_token → API Key → 实际请求"** 的两阶段模式:
|
|
28
|
+
|
|
29
|
+
1. **OAuth 认证阶段**:获取 `access_token` 和 `refresh_token`
|
|
30
|
+
2. **API Key 提取阶段**:用 `access_token` 调用 `getUserInfo` 获取真正的 `api_key`
|
|
31
|
+
3. **业务请求阶段**:所有后续 API 调用都使用 `api_key` 作为 `Authorization: Bearer <api_key>`
|
|
32
|
+
|
|
33
|
+
> ⚠️ **关键区别**:iFlow 的 `access_token` **只能**用来换取 API Key,**不能**直接作为鉴权凭证调用聊天完成接口。
|
|
34
|
+
|
|
35
|
+
### 详细流程步骤
|
|
36
|
+
|
|
37
|
+
#### 阶段1:OAuth 认证(获取 access_token)
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
用户授权 → 浏览器回调 → 授权码交换 → 获取 access_token + refresh_token
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
- **端点**:`https://iflow.cn/oauth/token`
|
|
44
|
+
- **流程**:标准 OAuth 2.0 授权码流程或设备码流程
|
|
45
|
+
- **输出**:`{ access_token, refresh_token, token_type, expires_in, scope }`
|
|
46
|
+
|
|
47
|
+
#### 阶段2:API Key 提取(getUserInfo 调用)
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
access_token → getUserInfo → api_key + email
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
- **端点**:`https://iflow.cn/api/oauth/getUserInfo?accessToken=<token>`
|
|
54
|
+
- **请求**:`GET` 请求,无额外 headers
|
|
55
|
+
- **响应**:`{ success: true, data: { apiKey: "sk-xxx", email: "user@mail", phone: "+86..." } }`
|
|
56
|
+
- **关键**:如果 `apiKey` 为空,整个流程失败(Fast-Fail 原则)
|
|
57
|
+
|
|
58
|
+
#### 阶段3:业务 API 调用(使用 api_key)
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
api_key → Authorization: Bearer <api_key> → 聊天完成接口
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
- **端点**:`https://apis.iflow.cn/v1/chat/completions`
|
|
65
|
+
- **鉴权**:`Authorization: Bearer sk-xxx`(**不是** access_token)
|
|
66
|
+
- **模型**:默认 `kimi`,支持模型列表需查阅 iFlow 官方文档
|
|
67
|
+
|
|
68
|
+
### 与 CLIProxyAPI 的对齐
|
|
69
|
+
|
|
70
|
+
我们的实现完全对齐 CLIProxyAPI 的 Go 版本逻辑:
|
|
71
|
+
|
|
72
|
+
| 步骤 | CLIProxyAPI (Go) | RouteCodex (TypeScript) |
|
|
73
|
+
|------|------------------|-------------------------|
|
|
74
|
+
| OAuth 认证 | `ExchangeCodeForTokens()` | `oauth-lifecycle.ts` 中的标准流程 |
|
|
75
|
+
| 获取 API Key | `FetchUserInfo()` → `apiKey` | `fetchIFlowUserInfo()` → `api_key` |
|
|
76
|
+
| 存储格式 | `IFlowTokenStorage` 结构体 | 相同字段名的 JSON 对象 |
|
|
77
|
+
| 鉴权方式 | `Authorization: Bearer <api_key>` | 完全一致 |
|
|
78
|
+
| 错误处理 | Fast-Fail,无隐藏回退 | 完全一致 |
|
|
79
|
+
|
|
80
|
+
### 代码实现位置
|
|
81
|
+
|
|
82
|
+
1. **OAuth 生命周期管理**:`src/providers/auth/oauth-lifecycle.ts`
|
|
83
|
+
- 在 `ensureValidOAuthToken()` 中,iFlow 认证成功后会自动调用 `fetchIFlowUserInfo()`
|
|
84
|
+
- 将返回的 `api_key` 和 `email` 合并到 token 数据中并重新保存
|
|
85
|
+
|
|
86
|
+
2. **API Key 提取逻辑**:`src/providers/auth/iflow-userinfo-helper.ts`
|
|
87
|
+
- `fetchIFlowUserInfo()`:调用 `https://iflow.cn/api/oauth/getUserInfo`
|
|
88
|
+
- `mergeIFlowTokenData()`:将 OAuth token 与用户信息合并
|
|
89
|
+
|
|
90
|
+
3. **认证提供者**:`src/providers/auth/tokenfile-auth.ts`
|
|
91
|
+
- `TokenFileAuthProvider.buildHeaders()`:优先使用 `api_key`,回退到 `access_token`
|
|
92
|
+
|
|
93
|
+
4. **服务配置**:`src/providers/core/config/service-profiles.ts`
|
|
94
|
+
- iFlow 默认端点:`https://apis.iflow.cn/v1/chat/completions`
|
|
95
|
+
- 默认模型:`kimi`
|
|
96
|
+
|
|
97
|
+
### 使用示例
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
// 1. 配置 iFlow OAuth
|
|
101
|
+
const iflowConfig = {
|
|
102
|
+
type: 'openai-standard',
|
|
103
|
+
config: {
|
|
104
|
+
providerType: 'iflow',
|
|
105
|
+
auth: {
|
|
106
|
+
type: 'oauth'
|
|
107
|
+
// 无需手动指定 clientId/secret,使用内置默认值
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// 2. 首次使用会触发浏览器授权
|
|
113
|
+
const provider = new ChatHttpProvider(iflowConfig, dependencies);
|
|
114
|
+
await provider.initialize(); // → 打开浏览器 → 授权 → 获取 API Key
|
|
115
|
+
|
|
116
|
+
// 3. 后续使用直接读取本地 token 文件
|
|
117
|
+
// ~/.routecodex/auth/iflow-oauth.json 包含:
|
|
118
|
+
// {
|
|
119
|
+
// "access_token": "...",
|
|
120
|
+
// "refresh_token": "...",
|
|
121
|
+
// "api_key": "sk-xxx", // ← 实际用于 API 调用
|
|
122
|
+
// "email": "user@mail.com",
|
|
123
|
+
// "type": "iflow"
|
|
124
|
+
// }
|
|
125
|
+
|
|
126
|
+
// 4. 正常调用模型
|
|
127
|
+
const response = await provider.processIncoming({
|
|
128
|
+
model: 'kimi',
|
|
129
|
+
messages: [{ role: 'user', content: 'Hello iFlow!' }]
|
|
130
|
+
});
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 故障排查
|
|
134
|
+
|
|
135
|
+
| 问题 | 可能原因 | 解决方案 |
|
|
136
|
+
|------|----------|----------|
|
|
137
|
+
| `getaddrinfo ENOTFOUND iflow.cn` | DNS 解析失败 | 检查网络连接,确认 iFlow 服务状态 |
|
|
138
|
+
| `empty api key returned` | getUserInfo 未返回 apiKey | 确认 iFlow 账户已开通 API 权限 |
|
|
139
|
+
| `401 Unauthorized` | api_key 无效 | 重新走 OAuth 流程获取新的 api_key |
|
|
140
|
+
| `40308` 业务错误 | 使用了 access_token 而非 api_key | 确认 TokenFileAuthProvider 正确读取了 api_key 字段 |
|
|
141
|
+
|
|
142
|
+
### 环境变量
|
|
143
|
+
|
|
144
|
+
- `IFLOW_CLIENT_ID`:覆盖默认 clientId(高级用法)
|
|
145
|
+
- `IFLOW_CLIENT_SECRET`:覆盖默认 clientSecret(高级用法)
|
|
146
|
+
|
|
147
|
+
> OAuth 认证流程现已强制在可用时自动打开浏览器完成授权,不再提供环境变量开关。
|
|
148
|
+
|
|
149
|
+
# Unified OAuth Authentication System Guide
|
|
150
|
+
|
|
151
|
+
## Overview
|
|
152
|
+
|
|
153
|
+
The Unified OAuth Authentication System provides a comprehensive solution for managing authentication across multiple AI service providers. It supports both static token files and dynamic OAuth 2.0 flows with automatic token refresh, PKCE security, and unified configuration management.
|
|
154
|
+
|
|
155
|
+
## Architecture
|
|
156
|
+
|
|
157
|
+
### Core Components
|
|
158
|
+
|
|
159
|
+
1. **OAuthConfigManager** - Centralized configuration management
|
|
160
|
+
2. **BaseOAuthManager** - Abstract base class for OAuth implementations
|
|
161
|
+
3. **Provider-specific Managers** - QwenOAuthManager and iFlowOAuthManager
|
|
162
|
+
4. **AuthResolver** - Unified token resolution supporting both static and OAuth
|
|
163
|
+
5. **UserConfigParser** - Extended to support OAuth configuration parsing
|
|
164
|
+
|
|
165
|
+
### Authentication Flow
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
Request → Provider → AuthResolver → OAuth Manager → Token Resolution → Response
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# OAuth Authentication Module - 详细实现文档
|
|
2
|
+
|
|
3
|
+
## 🎯 概述
|
|
4
|
+
|
|
5
|
+
本模块提供统一的OAuth 2.0认证实现,支持多种AI服务提供商(Qwen、iFlow等),遵循RouteCodex 9大核心架构原则。
|
|
6
|
+
|
|
7
|
+
## 🔐 iFlow OAuth 实现详解
|
|
8
|
+
|
|
9
|
+
### 核心流程概述
|
|
10
|
+
|
|
11
|
+
iFlow 的 OAuth 实现遵循 **"access_token → API Key → 实际请求"** 的两阶段模式:
|
|
12
|
+
|
|
13
|
+
1. **OAuth 认证阶段**:获取 `access_token` 和 `refresh_token`
|
|
14
|
+
2. **API Key 提取阶段**:用 `access_token` 调用 `getUserInfo` 获取真正的 `api_key`
|
|
15
|
+
3. **业务请求阶段**:所有后续 API 调用都使用 `api_key` 作为 `Authorization: Bearer <api_key>`
|
|
16
|
+
|
|
17
|
+
> ⚠️ **关键区别**:iFlow 的 `access_token` **只能**用来换取 API Key,**不能**直接作为鉴权凭证调用聊天完成接口。
|
|
18
|
+
|
|
19
|
+
### 详细流程步骤
|
|
20
|
+
|
|
21
|
+
#### 阶段1:OAuth 认证(获取 access_token)
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
用户授权 → 浏览器回调 → 授权码交换 → 获取 access_token + refresh_token
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
- **端点**:`https://iflow.cn/oauth/token`
|
|
28
|
+
- **流程**:标准 OAuth 2.0 授权码流程或设备码流程
|
|
29
|
+
- **输出**:`{ access_token, refresh_token, token_type, expires_in, scope }`
|
|
30
|
+
|
|
31
|
+
#### 阶段2:API Key 提取(getUserInfo 调用)
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
access_token → getUserInfo → api_key + email
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
- **端点**:`https://iflow.cn/api/oauth/getUserInfo?accessToken=<token>`
|
|
38
|
+
- **请求**:`GET` 请求,无额外 headers
|
|
39
|
+
- **响应**:`{ success: true, data: { apiKey: "sk-xxx", email: "user@mail", phone: "+86..." } }`
|
|
40
|
+
- **关键**:如果 `apiKey` 为空,整个流程失败(Fast-Fail 原则)
|
|
41
|
+
|
|
42
|
+
#### 阶段3:业务 API 调用(使用 api_key)
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
api_key → Authorization: Bearer <api_key> → 聊天完成接口
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
- **端点**:`https://apis.iflow.cn/v1/chat/completions`
|
|
49
|
+
- **鉴权**:`Authorization: Bearer sk-xxx`(**不是** access_token)
|
|
50
|
+
- **模型**:默认 `kimi`,支持模型列表需查阅 iFlow 官方文档
|
|
51
|
+
|
|
52
|
+
### 与 CLIProxyAPI 的对齐
|
|
53
|
+
|
|
54
|
+
我们的实现完全对齐 CLIProxyAPI 的 Go 版本逻辑:
|
|
55
|
+
|
|
56
|
+
| 步骤 | CLIProxyAPI (Go) | RouteCodex (TypeScript) |
|
|
57
|
+
|------|------------------|-------------------------|
|
|
58
|
+
| OAuth 认证 | `ExchangeCodeForTokens()` | `oauth-lifecycle.ts` 中的标准流程 |
|
|
59
|
+
| 获取 API Key | `FetchUserInfo()` → `apiKey` | `fetchIFlowUserInfo()` → `api_key` |
|
|
60
|
+
| 存储格式 | `IFlowTokenStorage` 结构体 | 相同字段名的 JSON 对象 |
|
|
61
|
+
| 鉴权方式 | `Authorization: Bearer <api_key>` | 完全一致 |
|
|
62
|
+
| 错误处理 | Fast-Fail,无隐藏回退 | 完全一致 |
|
|
63
|
+
|
|
64
|
+
### 代码实现位置
|
|
65
|
+
|
|
66
|
+
1. **OAuth 生命周期管理**:`oauth-lifecycle.ts`
|
|
67
|
+
- 在 `ensureValidOAuthToken()` 中,iFlow 认证成功后会自动调用 `fetchIFlowUserInfo()`
|
|
68
|
+
- 将返回的 `api_key` 和 `email` 合并到 token 数据中并重新保存
|
|
69
|
+
|
|
70
|
+
2. **API Key 提取逻辑**:`iflow-userinfo-helper.ts`
|
|
71
|
+
- `fetchIFlowUserInfo()`:调用 `https://iflow.cn/api/oauth/getUserInfo`
|
|
72
|
+
- `mergeIFlowTokenData()`:将 OAuth token 与用户信息合并
|
|
73
|
+
|
|
74
|
+
3. **认证提供者**:`tokenfile-auth.ts`
|
|
75
|
+
- `TokenFileAuthProvider.buildHeaders()`:优先使用 `api_key`,回退到 `access_token`
|
|
76
|
+
|
|
77
|
+
4. **服务配置**:`../config/service-profiles.ts`
|
|
78
|
+
- iFlow 默认端点:`https://apis.iflow.cn/v1/chat/completions`
|
|
79
|
+
- 默认模型:`kimi`
|
|
80
|
+
|
|
81
|
+
## 📋 使用示例
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
// 1. 配置 iFlow OAuth
|
|
85
|
+
const iflowConfig = {
|
|
86
|
+
type: 'openai-standard',
|
|
87
|
+
config: {
|
|
88
|
+
providerType: 'iflow',
|
|
89
|
+
auth: {
|
|
90
|
+
type: 'oauth'
|
|
91
|
+
// 无需手动指定 clientId/secret,使用内置默认值
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
// 2. 首次使用会触发浏览器授权
|
|
97
|
+
const provider = new ChatHttpProvider(iflowConfig, dependencies);
|
|
98
|
+
await provider.initialize(); // → 打开浏览器 → 授权 → 获取 API Key
|
|
99
|
+
|
|
100
|
+
// 3. 后续使用直接读取本地 token 文件
|
|
101
|
+
// ~/.routecodex/auth/iflow-oauth.json 包含:
|
|
102
|
+
// {
|
|
103
|
+
// "access_token": "...",
|
|
104
|
+
// "refresh_token": "...",
|
|
105
|
+
// "api_key": "sk-xxx", // ← 实际用于 API 调用
|
|
106
|
+
// "email": "user@mail.com",
|
|
107
|
+
// "type": "iflow"
|
|
108
|
+
// }
|
|
109
|
+
|
|
110
|
+
// 4. 正常调用模型
|
|
111
|
+
const response = await provider.processIncoming({
|
|
112
|
+
model: 'kimi',
|
|
113
|
+
messages: [{ role: 'user', content: 'Hello iFlow!' }]
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## 🔧 故障排查
|
|
118
|
+
|
|
119
|
+
| 问题 | 可能原因 | 解决方案 |
|
|
120
|
+
|------|----------|----------|
|
|
121
|
+
| `getaddrinfo ENOTFOUND iflow.cn` | DNS 解析失败 | 检查网络连接,确认 iFlow 服务状态 |
|
|
122
|
+
| `empty api key returned` | getUserInfo 未返回 apiKey | 确认 iFlow 账户已开通 API 权限 |
|
|
123
|
+
| `401 Unauthorized` | api_key 无效 | 重新走 OAuth 流程获取新的 api_key |
|
|
124
|
+
| `40308` 业务错误 | 使用了 access_token 而非 api_key | 确认 TokenFileAuthProvider 正确读取了 api_key 字段 |
|
|
125
|
+
|
|
126
|
+
## 🌍 环境变量
|
|
127
|
+
|
|
128
|
+
- `IFLOW_CLIENT_ID`:覆盖默认 clientId(高级用法)
|
|
129
|
+
- `IFLOW_CLIENT_SECRET`:覆盖默认 clientSecret(高级用法)
|
|
130
|
+
|
|
131
|
+
> 所有 OAuth 流程现在都会在可用时自动拉起浏览器进行授权,不再支持通过环境变量关闭自动打开行为。
|
|
132
|
+
|
|
133
|
+
## 📊 测试验证
|
|
134
|
+
|
|
135
|
+
运行以下命令验证 iFlow OAuth 实现:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# 测试 OAuth 流程
|
|
139
|
+
node -e "const { TokenFileAuthProvider } = require('./dist/providers/auth/tokenfile-auth.js'); const provider = new TokenFileAuthProvider({type: 'oauth', tokenFile: '~/.routecodex/auth/iflow-oauth.json'}); provider.initialize().then(() => console.log('✅ iFlow OAuth working:', provider.getStatus()));"
|
|
140
|
+
|
|
141
|
+
# 测试 API Key 提取
|
|
142
|
+
node -e "const { fetchIFlowUserInfo } = require('./dist/providers/auth/iflow-userinfo-helper.js'); fetchIFlowUserInfo('test_token').catch(e => console.log('✅ Error handling working:', e.message));"
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## 🎯 总结
|
|
146
|
+
|
|
147
|
+
iFlow OAuth 实现完全对齐 CLIProxyAPI 的设计:
|
|
148
|
+
|
|
149
|
+
- ✅ **两阶段认证**:access_token → API Key → 业务请求
|
|
150
|
+
- ✅ **Fast-Fail 原则**:任何步骤失败立即报错,无隐藏回退
|
|
151
|
+
- ✅ **配置驱动**:所有参数外部化,无硬编码
|
|
152
|
+
- ✅ **CLIProxyAPI 兼容**:字段名、端点、错误处理完全一致
|
|
153
|
+
- ✅ **生产就绪**:经过完整测试验证,支持自动刷新和错误恢复
|