@jsonstudio/rcc 0.89.1205 → 0.89.1348

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.
Files changed (332) hide show
  1. package/README.md +17 -0
  2. package/configsamples/config.json +426 -0
  3. package/configsamples/config.reference.json +58 -0
  4. package/configsamples/provider/crs/config.v1.json +46 -0
  5. package/configsamples/provider/glm/config.v1.json +81 -0
  6. package/configsamples/provider/glm-anthropic/config.v1.json +45 -0
  7. package/configsamples/provider/iflow/config.v1.json +74 -0
  8. package/configsamples/provider/kimi/config.v1.json +41 -0
  9. package/configsamples/provider/lmstudio/config.v1.json +101 -0
  10. package/configsamples/provider/mimo/config.v1.json +35 -0
  11. package/configsamples/provider/modelscope/config.v1.json +96 -0
  12. package/configsamples/provider/qwen/config.v1.json +38 -0
  13. package/configsamples/provider/tab/config.v1.json +50 -0
  14. package/configsamples/provider/tabglm/config.v1.json +49 -0
  15. package/dist/build-info.js +2 -2
  16. package/dist/cli/commands/code.js +12 -6
  17. package/dist/cli/commands/code.js.map +1 -1
  18. package/dist/cli/commands/config.d.ts +2 -1
  19. package/dist/cli/commands/config.js +74 -103
  20. package/dist/cli/commands/config.js.map +1 -1
  21. package/dist/cli/commands/examples.js +6 -6
  22. package/dist/cli/commands/examples.js.map +1 -1
  23. package/dist/cli/commands/init.d.ts +28 -0
  24. package/dist/cli/commands/init.js +91 -0
  25. package/dist/cli/commands/init.js.map +1 -0
  26. package/dist/cli/commands/port.js +10 -2
  27. package/dist/cli/commands/port.js.map +1 -1
  28. package/dist/cli/commands/restart.js +5 -2
  29. package/dist/cli/commands/restart.js.map +1 -1
  30. package/dist/cli/commands/start.js +25 -22
  31. package/dist/cli/commands/start.js.map +1 -1
  32. package/dist/cli/commands/status.js +1 -0
  33. package/dist/cli/commands/status.js.map +1 -1
  34. package/dist/cli/commands/stop.js +1 -0
  35. package/dist/cli/commands/stop.js.map +1 -1
  36. package/dist/cli/config/bundled-docs.d.ts +20 -0
  37. package/dist/cli/config/bundled-docs.js +91 -0
  38. package/dist/cli/config/bundled-docs.js.map +1 -0
  39. package/dist/cli/config/init-config.d.ts +36 -0
  40. package/dist/cli/config/init-config.js +180 -0
  41. package/dist/cli/config/init-config.js.map +1 -0
  42. package/dist/cli/config/init-provider-catalog.d.ts +8 -0
  43. package/dist/cli/config/init-provider-catalog.js +187 -0
  44. package/dist/cli/config/init-provider-catalog.js.map +1 -0
  45. package/dist/cli/register/init-command.d.ts +3 -0
  46. package/dist/cli/register/init-command.js +5 -0
  47. package/dist/cli/register/init-command.js.map +1 -0
  48. package/dist/cli.js +28 -3
  49. package/dist/cli.js.map +1 -1
  50. package/dist/client/gemini-cli/gemini-cli-protocol-client.js +1 -1
  51. package/dist/client/gemini-cli/gemini-cli-protocol-client.js.map +1 -1
  52. package/dist/config/risk-control-config.d.ts +94 -0
  53. package/dist/config/risk-control-config.js +196 -0
  54. package/dist/config/risk-control-config.js.map +1 -0
  55. package/dist/constants/index.d.ts +6 -0
  56. package/dist/constants/index.js +13 -0
  57. package/dist/constants/index.js.map +1 -1
  58. package/dist/docs/daemon-admin-ui.html +2113 -190
  59. package/dist/index.js +0 -1
  60. package/dist/index.js.map +1 -1
  61. package/dist/manager/modules/health/index.d.ts +1 -1
  62. package/dist/manager/modules/quota/antigravity-quota-manager.d.ts +70 -0
  63. package/dist/manager/modules/quota/antigravity-quota-manager.js +442 -0
  64. package/dist/manager/modules/quota/antigravity-quota-manager.js.map +1 -0
  65. package/dist/manager/modules/quota/index.d.ts +3 -127
  66. package/dist/manager/modules/quota/index.js +2 -1093
  67. package/dist/manager/modules/quota/index.js.map +1 -1
  68. package/dist/manager/modules/quota/provider-key-normalization.d.ts +3 -0
  69. package/dist/manager/modules/quota/provider-key-normalization.js +155 -0
  70. package/dist/manager/modules/quota/provider-key-normalization.js.map +1 -0
  71. package/dist/manager/modules/quota/provider-quota-daemon.cooldown.d.ts +9 -0
  72. package/dist/manager/modules/quota/provider-quota-daemon.cooldown.js +115 -0
  73. package/dist/manager/modules/quota/provider-quota-daemon.cooldown.js.map +1 -0
  74. package/dist/manager/modules/quota/provider-quota-daemon.d.ts +77 -0
  75. package/dist/manager/modules/quota/provider-quota-daemon.events.d.ts +12 -0
  76. package/dist/manager/modules/quota/provider-quota-daemon.events.js +237 -0
  77. package/dist/manager/modules/quota/provider-quota-daemon.events.js.map +1 -0
  78. package/dist/manager/modules/quota/provider-quota-daemon.js +404 -0
  79. package/dist/manager/modules/quota/provider-quota-daemon.js.map +1 -0
  80. package/dist/manager/modules/quota/provider-quota-daemon.model-backoff.d.ts +11 -0
  81. package/dist/manager/modules/quota/provider-quota-daemon.model-backoff.js +189 -0
  82. package/dist/manager/modules/quota/provider-quota-daemon.model-backoff.js.map +1 -0
  83. package/dist/manager/modules/quota/provider-quota-daemon.snapshot.d.ts +8 -0
  84. package/dist/manager/modules/quota/provider-quota-daemon.snapshot.js +96 -0
  85. package/dist/manager/modules/quota/provider-quota-daemon.snapshot.js.map +1 -0
  86. package/dist/manager/modules/quota/provider-quota-daemon.view.d.ts +19 -0
  87. package/dist/manager/modules/quota/provider-quota-daemon.view.js +37 -0
  88. package/dist/manager/modules/quota/provider-quota-daemon.view.js.map +1 -0
  89. package/dist/manager/modules/routing/index.d.ts +1 -0
  90. package/dist/manager/modules/routing/index.js +11 -25
  91. package/dist/manager/modules/routing/index.js.map +1 -1
  92. package/dist/manager/quota/provider-quota-center.d.ts +2 -0
  93. package/dist/manager/quota/provider-quota-center.js +80 -82
  94. package/dist/manager/quota/provider-quota-center.js.map +1 -1
  95. package/dist/modules/llmswitch/bridge.d.ts +16 -18
  96. package/dist/modules/llmswitch/bridge.js +293 -94
  97. package/dist/modules/llmswitch/bridge.js.map +1 -1
  98. package/dist/modules/llmswitch/core-loader.d.ts +4 -2
  99. package/dist/modules/llmswitch/core-loader.js +32 -20
  100. package/dist/modules/llmswitch/core-loader.js.map +1 -1
  101. package/dist/modules/pipeline/utils/colored-logger.js +3 -2
  102. package/dist/modules/pipeline/utils/colored-logger.js.map +1 -1
  103. package/dist/modules/pipeline/utils/debug-logger.js +1 -1
  104. package/dist/modules/pipeline/utils/debug-logger.js.map +1 -1
  105. package/dist/providers/auth/iflow-cookie-auth.js +0 -2
  106. package/dist/providers/auth/iflow-cookie-auth.js.map +1 -1
  107. package/dist/providers/auth/oauth-lifecycle.js +2 -23
  108. package/dist/providers/auth/oauth-lifecycle.js.map +1 -1
  109. package/dist/providers/core/config/camoufox-launcher.js +35 -4
  110. package/dist/providers/core/config/camoufox-launcher.js.map +1 -1
  111. package/dist/providers/core/runtime/antigravity-quota-client.js +6 -3
  112. package/dist/providers/core/runtime/antigravity-quota-client.js.map +1 -1
  113. package/dist/providers/core/runtime/base-provider.d.ts +2 -2
  114. package/dist/providers/core/runtime/base-provider.js +74 -69
  115. package/dist/providers/core/runtime/base-provider.js.map +1 -1
  116. package/dist/providers/core/runtime/gemini-cli-http-provider.js +6 -4
  117. package/dist/providers/core/runtime/gemini-cli-http-provider.js.map +1 -1
  118. package/dist/providers/core/runtime/http-request-executor.js +2 -2
  119. package/dist/providers/core/runtime/http-request-executor.js.map +1 -1
  120. package/dist/providers/core/runtime/http-transport-provider.d.ts +14 -0
  121. package/dist/providers/core/runtime/http-transport-provider.js +111 -5
  122. package/dist/providers/core/runtime/http-transport-provider.js.map +1 -1
  123. package/dist/providers/core/runtime/provider-error-classifier.js +10 -0
  124. package/dist/providers/core/runtime/provider-error-classifier.js.map +1 -1
  125. package/dist/providers/core/runtime/provider-factory.js +7 -5
  126. package/dist/providers/core/runtime/provider-factory.js.map +1 -1
  127. package/dist/providers/core/runtime/provider-runtime-metadata.d.ts +6 -0
  128. package/dist/providers/core/runtime/provider-runtime-metadata.js.map +1 -1
  129. package/dist/providers/core/runtime/responses-provider.d.ts +1 -7
  130. package/dist/providers/core/runtime/responses-provider.js +12 -93
  131. package/dist/providers/core/runtime/responses-provider.js.map +1 -1
  132. package/dist/providers/core/strategies/oauth-auth-code-flow.js +12 -8
  133. package/dist/providers/core/strategies/oauth-auth-code-flow.js.map +1 -1
  134. package/dist/providers/core/utils/http-client.js +16 -3
  135. package/dist/providers/core/utils/http-client.js.map +1 -1
  136. package/dist/providers/core/utils/provider-error-logger.d.ts +1 -1
  137. package/dist/providers/core/utils/provider-error-reporter.d.ts +3 -1
  138. package/dist/providers/core/utils/provider-error-reporter.js +3 -0
  139. package/dist/providers/core/utils/provider-error-reporter.js.map +1 -1
  140. package/dist/providers/core/utils/snapshot-writer.js +1 -4
  141. package/dist/providers/core/utils/snapshot-writer.js.map +1 -1
  142. package/dist/providers/mock/mock-provider-runtime.js +57 -27
  143. package/dist/providers/mock/mock-provider-runtime.js.map +1 -1
  144. package/dist/scripts/camoufox/launch-auth.mjs +193 -58
  145. package/dist/server/handlers/handler-utils.js +3 -2
  146. package/dist/server/handlers/handler-utils.js.map +1 -1
  147. package/dist/server/runtime/http-server/daemon-admin/auth-handler.d.ts +2 -0
  148. package/dist/server/runtime/http-server/daemon-admin/auth-handler.js +103 -0
  149. package/dist/server/runtime/http-server/daemon-admin/auth-handler.js.map +1 -0
  150. package/dist/server/runtime/http-server/daemon-admin/auth-session.d.ts +5 -0
  151. package/dist/server/runtime/http-server/daemon-admin/auth-session.js +77 -0
  152. package/dist/server/runtime/http-server/daemon-admin/auth-session.js.map +1 -0
  153. package/dist/server/runtime/http-server/daemon-admin/auth-store.d.ts +18 -0
  154. package/dist/server/runtime/http-server/daemon-admin/auth-store.js +89 -0
  155. package/dist/server/runtime/http-server/daemon-admin/auth-store.js.map +1 -0
  156. package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js +1 -2
  157. package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js.map +1 -1
  158. package/dist/server/runtime/http-server/daemon-admin/providers-handler.js +226 -24
  159. package/dist/server/runtime/http-server/daemon-admin/providers-handler.js.map +1 -1
  160. package/dist/server/runtime/http-server/daemon-admin/quota-handler.js +47 -8
  161. package/dist/server/runtime/http-server/daemon-admin/quota-handler.js.map +1 -1
  162. package/dist/server/runtime/http-server/daemon-admin/restart-handler.js +1 -1
  163. package/dist/server/runtime/http-server/daemon-admin/restart-handler.js.map +1 -1
  164. package/dist/server/runtime/http-server/daemon-admin/stats-handler.js +1 -1
  165. package/dist/server/runtime/http-server/daemon-admin/stats-handler.js.map +1 -1
  166. package/dist/server/runtime/http-server/daemon-admin/status-handler.js +68 -4
  167. package/dist/server/runtime/http-server/daemon-admin/status-handler.js.map +1 -1
  168. package/dist/server/runtime/http-server/daemon-admin-routes.d.ts +3 -4
  169. package/dist/server/runtime/http-server/daemon-admin-routes.js +9 -14
  170. package/dist/server/runtime/http-server/daemon-admin-routes.js.map +1 -1
  171. package/dist/server/runtime/http-server/executor-metadata.js +1 -1
  172. package/dist/server/runtime/http-server/executor-metadata.js.map +1 -1
  173. package/dist/server/runtime/http-server/executor-response.js +0 -16
  174. package/dist/server/runtime/http-server/executor-response.js.map +1 -1
  175. package/dist/server/runtime/http-server/hub-shadow-compare.js +110 -34
  176. package/dist/server/runtime/http-server/hub-shadow-compare.js.map +1 -1
  177. package/dist/server/runtime/http-server/index.d.ts +5 -3
  178. package/dist/server/runtime/http-server/index.js +215 -109
  179. package/dist/server/runtime/http-server/index.js.map +1 -1
  180. package/dist/server/runtime/http-server/middleware.js +19 -1
  181. package/dist/server/runtime/http-server/middleware.js.map +1 -1
  182. package/dist/server/runtime/http-server/request-executor.js +10 -19
  183. package/dist/server/runtime/http-server/request-executor.js.map +1 -1
  184. package/dist/server/runtime/http-server/routes.js +8 -2
  185. package/dist/server/runtime/http-server/routes.js.map +1 -1
  186. package/dist/server/runtime/http-server/session-dir.d.ts +2 -0
  187. package/dist/server/runtime/http-server/session-dir.js +59 -0
  188. package/dist/server/runtime/http-server/session-dir.js.map +1 -0
  189. package/dist/server/runtime/http-server/types.d.ts +0 -4
  190. package/dist/server/utils/utf8-chunk-buffer.js +6 -3
  191. package/dist/server/utils/utf8-chunk-buffer.js.map +1 -1
  192. package/dist/server/utils/warmup-storm-tracker.js +1 -1
  193. package/dist/server/utils/warmup-storm-tracker.js.map +1 -1
  194. package/dist/server-factory.d.ts +6 -28
  195. package/dist/server-factory.js +8 -93
  196. package/dist/server-factory.js.map +1 -1
  197. package/dist/token-daemon/index.js +2 -2
  198. package/dist/token-daemon/index.js.map +1 -1
  199. package/dist/token-daemon/provider-registry.js +0 -1
  200. package/dist/token-daemon/provider-registry.js.map +1 -1
  201. package/dist/token-daemon/server-utils.js +8 -9
  202. package/dist/token-daemon/server-utils.js.map +1 -1
  203. package/dist/token-daemon/token-utils.js +1 -1
  204. package/dist/token-daemon/token-utils.js.map +1 -1
  205. package/dist/tools/semantic-replay.js +2 -2
  206. package/dist/tools/semantic-replay.js.map +1 -1
  207. package/dist/tools/stats-request-events.d.ts +1 -1
  208. package/dist/tools/stats-usage.js +6 -3
  209. package/dist/tools/stats-usage.js.map +1 -1
  210. package/dist/utils/llms-engine-shadow.d.ts +19 -0
  211. package/dist/utils/llms-engine-shadow.js +209 -0
  212. package/dist/utils/llms-engine-shadow.js.map +1 -0
  213. package/dist/utils/runtime-versions.js +2 -1
  214. package/dist/utils/runtime-versions.js.map +1 -1
  215. package/docs/ARCHITECTURE.md +402 -0
  216. package/docs/CODEX_AND_CLAUDE_CODE.md +69 -0
  217. package/docs/CONFIG_ARCHITECTURE.md +517 -0
  218. package/docs/ERROR_HANDLING_AUDIT.md +0 -0
  219. package/docs/GCLI2API_PARITY_GAPS.md +98 -0
  220. package/docs/INSTALLATION_AND_QUICKSTART.md +74 -0
  221. package/docs/INSTRUCTION_MARKUP.md +89 -0
  222. package/docs/MODULE_ENHANCEMENT_SYSTEM.md +666 -0
  223. package/docs/PORTS.md +36 -0
  224. package/docs/PROVIDERS_BUILTIN.md +111 -0
  225. package/docs/PROVIDER_TYPES.md +55 -0
  226. package/docs/SERVERTOOL_CLOCK_DESIGN.md +233 -0
  227. package/docs/USAGE_HANDLING_ANALYSIS.md +335 -0
  228. package/docs/USER_CONFIG_PARSER_CHANGES.md +175 -0
  229. package/docs/V3_INBOUND_OUTBOUND_DESIGN.md +86 -0
  230. package/docs/VIRTUAL_ROUTER_PRIORITY_AND_HEALTH.md +125 -0
  231. package/docs/anthropic-request-golden-samples.md +50 -0
  232. package/docs/ccr-alignment-enhancetool.md +105 -0
  233. package/docs/chat-glm-500-analysis.md +79 -0
  234. package/docs/chat-request-golden-samples.md +42 -0
  235. package/docs/chat-semantic-expansion-plan.md +82 -0
  236. package/docs/cli-command-inventory.md +76 -0
  237. package/docs/codex-samples-replay.md +50 -0
  238. package/docs/daemon-admin-api-design.md +350 -0
  239. package/docs/daemon-admin-module-structure.md +169 -0
  240. package/docs/daemon-admin-ui.html +3394 -0
  241. package/docs/debug-system-design.md +734 -0
  242. package/docs/debugging/gemini-sse-root-cause.md +52 -0
  243. package/docs/debugging/sse_encoding_failure_analysis.md +53 -0
  244. package/docs/dry-run/README.md +721 -0
  245. package/docs/error-handling-v2.md +92 -0
  246. package/docs/exec-command-guard-policy.example.v1.json +42 -0
  247. package/docs/fixes/gemini-protocol-mapping.md +57 -0
  248. package/docs/fixes/oauth-portal-timing-fix.md +202 -0
  249. package/docs/fixes/web-search-hop3-fix.md +265 -0
  250. package/docs/glm-api-reference.md +390 -0
  251. package/docs/glm-chat-completions.md +1779 -0
  252. package/docs/glm-history-inline-images.md +44 -0
  253. package/docs/golden-ci-library.md +66 -0
  254. package/docs/lmstudio-dry-run-summary.md +203 -0
  255. package/docs/lmstudio-tool-calling.md +214 -0
  256. package/docs/mapping-tables/anthropic-to-openai.json +290 -0
  257. package/docs/mapping-tables/iflow-to-openai.json +215 -0
  258. package/docs/mapping-tables/openai-passthrough.json +190 -0
  259. package/docs/mapping-tables/openai-to-iflow.json +227 -0
  260. package/docs/monitoring/Design.md +61 -0
  261. package/docs/multi-token-auth-guide.md +66 -0
  262. package/docs/oauth-authentication-guide.md +168 -0
  263. package/docs/oauth-iflow-implementation.md +153 -0
  264. package/docs/pipeline-routing-report.md +209 -0
  265. package/docs/plans/manager-daemon/PLAN.md +86 -0
  266. package/docs/plans/provider-config-v2-plan.md +176 -0
  267. package/docs/plans/provider-runtime-manager-plan.md +209 -0
  268. package/docs/plans/transparent-429-failover.md +89 -0
  269. package/docs/plans/unified-hub-framework-v1.md +245 -0
  270. package/docs/provider-config-v2-ui-design.md +181 -0
  271. package/docs/provider-quota-design.md +129 -0
  272. package/docs/providers/gemini-provider.md +62 -0
  273. package/docs/providers/lmstudio-v2-migration-report.md +102 -0
  274. package/docs/providers/provider-composite-design.md +142 -0
  275. package/docs/providers/provider-composite-testing.md +98 -0
  276. package/docs/providers/provider-type-only-migration.md +111 -0
  277. package/docs/rccx-wasm-migration.md +74 -0
  278. package/docs/refactoring/architecture-comparison-diagram.md +140 -0
  279. package/docs/refactoring/compatibility-v2-architecture-design.md +738 -0
  280. package/docs/refactoring/workflow-compatibility-refactoring-design.md +361 -0
  281. package/docs/reports/routing-classification-report.json +24 -0
  282. package/docs/reports/routing-classification-report.md +18 -0
  283. package/docs/reports/thinking-keywords-report.json +19 -0
  284. package/docs/responses/README.md +156 -0
  285. package/docs/responses-generic-provider.md +86 -0
  286. package/docs/responses-passthrough-provider-design.md +202 -0
  287. package/docs/routing-awrr-health-weighted-round-robin.md +179 -0
  288. package/docs/routing-instructions.md +393 -0
  289. package/docs/stop-message-auto.md +225 -0
  290. package/docs/streaming-flow.html +30 -0
  291. package/docs/streaming-flow.md +182 -0
  292. package/docs/token-daemon-preview.html +490 -0
  293. package/docs/token-refresh-daemon-plan.md +269 -0
  294. package/docs/transformation-tables/Gemini-FinishReason/345/256/214/346/225/264/350/275/254/346/215/242/350/241/250.json +233 -0
  295. package/docs/transformation-tables/README.md +225 -0
  296. package/docs/transformation-tables/claude-code-router-anthropic-to-gemini.json +283 -0
  297. package/docs/transformation-tables/claude-code-router-anthropic-to-openai.json +208 -0
  298. package/docs/transformation-tables/claude-code-router-openai-to-anthropic.json +261 -0
  299. package/docs/transformation-tables/claude-code-router-openai-to-gemini.json +208 -0
  300. package/docs/transformation-tables/claude-code-router-openai-to-lmstudio.json +182 -0
  301. package/docs/transformation-tables/claude-code-router-openai-to-ollama.json +250 -0
  302. package/docs/transformation-tables/claude-code-router-openai-to-textgenwebui.json +295 -0
  303. package/docs/transformation-tables/claude-code-router-provider-conversions.json +193 -0
  304. 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
  305. 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
  306. 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
  307. 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
  308. 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
  309. 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
  310. 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
  311. package/docs/v2-architecture/IMPLEMENTATION-ROADMAP.md +367 -0
  312. package/docs/v2-architecture/OPTIMIZED-DESIGN.md +827 -0
  313. package/docs/v2-architecture/PRERUN-CONNECTION-DESIGN.md +716 -0
  314. package/docs/v2-architecture/README.md +551 -0
  315. package/docs/verification/modelscope-verify.md +59 -0
  316. package/docs/web-search-service-design.md +322 -0
  317. package/package.json +12 -7
  318. package/scripts/camoufox/launch-auth.mjs +193 -58
  319. package/scripts/monitor-diff.mjs +126 -0
  320. package/scripts/pack-mode.mjs +19 -1
  321. package/scripts/pack-rcc.mjs +63 -0
  322. package/scripts/unified-hub-shadow-compare.mjs +33 -13
  323. package/scripts/verify-e2e-toolcall.mjs +115 -26
  324. package/dist/modules/llmswitch/pipeline-registry.d.ts +0 -57
  325. package/dist/modules/llmswitch/pipeline-registry.js +0 -229
  326. package/dist/modules/llmswitch/pipeline-registry.js.map +0 -1
  327. package/dist/server/RouteCodexServer.d.ts +0 -13
  328. package/dist/server/RouteCodexServer.js +0 -25
  329. package/dist/server/RouteCodexServer.js.map +0 -1
  330. package/dist/v2/conversion/hub/snapshot-recorder.d.ts +0 -12
  331. package/dist/v2/conversion/hub/snapshot-recorder.js +0 -22
  332. package/dist/v2/conversion/hub/snapshot-recorder.js.map +0 -1
@@ -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
+ - ✅ **生产就绪**:经过完整测试验证,支持自动刷新和错误恢复