@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.
Files changed (391) hide show
  1. package/README.md +53 -1412
  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 +77 -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 +94 -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 +37 -0
  40. package/dist/cli/config/init-config.js +212 -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/gemini-protocol-client.js +2 -1
  51. package/dist/client/gemini/gemini-protocol-client.js.map +1 -1
  52. package/dist/client/gemini-cli/gemini-cli-protocol-client.js +40 -16
  53. package/dist/client/gemini-cli/gemini-cli-protocol-client.js.map +1 -1
  54. package/dist/client/openai/chat-protocol-client.js +2 -1
  55. package/dist/client/openai/chat-protocol-client.js.map +1 -1
  56. package/dist/client/responses/responses-protocol-client.js +2 -1
  57. package/dist/client/responses/responses-protocol-client.js.map +1 -1
  58. package/dist/config/risk-control-config.d.ts +94 -0
  59. package/dist/config/risk-control-config.js +196 -0
  60. package/dist/config/risk-control-config.js.map +1 -0
  61. package/dist/constants/index.d.ts +6 -0
  62. package/dist/constants/index.js +13 -0
  63. package/dist/constants/index.js.map +1 -1
  64. package/dist/docs/daemon-admin-ui.html +2113 -190
  65. package/dist/error-handling/quiet-error-handling-center.js +46 -8
  66. package/dist/error-handling/quiet-error-handling-center.js.map +1 -1
  67. package/dist/index.js +0 -1
  68. package/dist/index.js.map +1 -1
  69. package/dist/manager/modules/health/index.d.ts +1 -1
  70. package/dist/manager/modules/quota/antigravity-quota-manager.d.ts +70 -0
  71. package/dist/manager/modules/quota/antigravity-quota-manager.js +442 -0
  72. package/dist/manager/modules/quota/antigravity-quota-manager.js.map +1 -0
  73. package/dist/manager/modules/quota/index.d.ts +3 -127
  74. package/dist/manager/modules/quota/index.js +2 -1093
  75. package/dist/manager/modules/quota/index.js.map +1 -1
  76. package/dist/manager/modules/quota/provider-key-normalization.d.ts +3 -0
  77. package/dist/manager/modules/quota/provider-key-normalization.js +155 -0
  78. package/dist/manager/modules/quota/provider-key-normalization.js.map +1 -0
  79. package/dist/manager/modules/quota/provider-quota-daemon.cooldown.d.ts +9 -0
  80. package/dist/manager/modules/quota/provider-quota-daemon.cooldown.js +115 -0
  81. package/dist/manager/modules/quota/provider-quota-daemon.cooldown.js.map +1 -0
  82. package/dist/manager/modules/quota/provider-quota-daemon.d.ts +77 -0
  83. package/dist/manager/modules/quota/provider-quota-daemon.events.d.ts +12 -0
  84. package/dist/manager/modules/quota/provider-quota-daemon.events.js +239 -0
  85. package/dist/manager/modules/quota/provider-quota-daemon.events.js.map +1 -0
  86. package/dist/manager/modules/quota/provider-quota-daemon.js +404 -0
  87. package/dist/manager/modules/quota/provider-quota-daemon.js.map +1 -0
  88. package/dist/manager/modules/quota/provider-quota-daemon.model-backoff.d.ts +11 -0
  89. package/dist/manager/modules/quota/provider-quota-daemon.model-backoff.js +192 -0
  90. package/dist/manager/modules/quota/provider-quota-daemon.model-backoff.js.map +1 -0
  91. package/dist/manager/modules/quota/provider-quota-daemon.snapshot.d.ts +8 -0
  92. package/dist/manager/modules/quota/provider-quota-daemon.snapshot.js +96 -0
  93. package/dist/manager/modules/quota/provider-quota-daemon.snapshot.js.map +1 -0
  94. package/dist/manager/modules/quota/provider-quota-daemon.view.d.ts +19 -0
  95. package/dist/manager/modules/quota/provider-quota-daemon.view.js +37 -0
  96. package/dist/manager/modules/quota/provider-quota-daemon.view.js.map +1 -0
  97. package/dist/manager/modules/routing/index.d.ts +1 -0
  98. package/dist/manager/modules/routing/index.js +11 -25
  99. package/dist/manager/modules/routing/index.js.map +1 -1
  100. package/dist/manager/quota/provider-quota-center.d.ts +2 -0
  101. package/dist/manager/quota/provider-quota-center.js +80 -82
  102. package/dist/manager/quota/provider-quota-center.js.map +1 -1
  103. package/dist/modules/llmswitch/bridge.d.ts +16 -18
  104. package/dist/modules/llmswitch/bridge.js +293 -94
  105. package/dist/modules/llmswitch/bridge.js.map +1 -1
  106. package/dist/modules/llmswitch/core-loader.d.ts +4 -2
  107. package/dist/modules/llmswitch/core-loader.js +32 -20
  108. package/dist/modules/llmswitch/core-loader.js.map +1 -1
  109. package/dist/modules/pipeline/utils/colored-logger.js +3 -2
  110. package/dist/modules/pipeline/utils/colored-logger.js.map +1 -1
  111. package/dist/modules/pipeline/utils/debug-logger.js +1 -1
  112. package/dist/modules/pipeline/utils/debug-logger.js.map +1 -1
  113. package/dist/providers/auth/antigravity-userinfo-helper.d.ts +2 -1
  114. package/dist/providers/auth/antigravity-userinfo-helper.js +25 -4
  115. package/dist/providers/auth/antigravity-userinfo-helper.js.map +1 -1
  116. package/dist/providers/auth/iflow-cookie-auth.js +0 -2
  117. package/dist/providers/auth/iflow-cookie-auth.js.map +1 -1
  118. package/dist/providers/auth/oauth-lifecycle.js +2 -23
  119. package/dist/providers/auth/oauth-lifecycle.js.map +1 -1
  120. package/dist/providers/auth/tokenfile-auth.d.ts +2 -0
  121. package/dist/providers/auth/tokenfile-auth.js +33 -1
  122. package/dist/providers/auth/tokenfile-auth.js.map +1 -1
  123. package/dist/providers/core/config/camoufox-launcher.d.ts +5 -0
  124. package/dist/providers/core/config/camoufox-launcher.js +40 -4
  125. package/dist/providers/core/config/camoufox-launcher.js.map +1 -1
  126. package/dist/providers/core/config/service-profiles.js +7 -18
  127. package/dist/providers/core/config/service-profiles.js.map +1 -1
  128. package/dist/providers/core/runtime/antigravity-quota-client.js +6 -3
  129. package/dist/providers/core/runtime/antigravity-quota-client.js.map +1 -1
  130. package/dist/providers/core/runtime/base-provider.d.ts +2 -7
  131. package/dist/providers/core/runtime/base-provider.js +84 -165
  132. package/dist/providers/core/runtime/base-provider.js.map +1 -1
  133. package/dist/providers/core/runtime/gemini-cli-http-provider.d.ts +7 -0
  134. package/dist/providers/core/runtime/gemini-cli-http-provider.js +368 -97
  135. package/dist/providers/core/runtime/gemini-cli-http-provider.js.map +1 -1
  136. package/dist/providers/core/runtime/http-request-executor.d.ts +3 -0
  137. package/dist/providers/core/runtime/http-request-executor.js +110 -38
  138. package/dist/providers/core/runtime/http-request-executor.js.map +1 -1
  139. package/dist/providers/core/runtime/http-transport-provider.d.ts +17 -0
  140. package/dist/providers/core/runtime/http-transport-provider.js +165 -16
  141. package/dist/providers/core/runtime/http-transport-provider.js.map +1 -1
  142. package/dist/providers/core/runtime/provider-error-classifier.js +10 -0
  143. package/dist/providers/core/runtime/provider-error-classifier.js.map +1 -1
  144. package/dist/providers/core/runtime/provider-factory.js +7 -5
  145. package/dist/providers/core/runtime/provider-factory.js.map +1 -1
  146. package/dist/providers/core/runtime/provider-runtime-metadata.d.ts +6 -0
  147. package/dist/providers/core/runtime/provider-runtime-metadata.js.map +1 -1
  148. package/dist/providers/core/runtime/rate-limit-manager.d.ts +1 -12
  149. package/dist/providers/core/runtime/rate-limit-manager.js +4 -77
  150. package/dist/providers/core/runtime/rate-limit-manager.js.map +1 -1
  151. package/dist/providers/core/runtime/responses-provider.d.ts +1 -7
  152. package/dist/providers/core/runtime/responses-provider.js +12 -93
  153. package/dist/providers/core/runtime/responses-provider.js.map +1 -1
  154. package/dist/providers/core/strategies/oauth-auth-code-flow.js +12 -8
  155. package/dist/providers/core/strategies/oauth-auth-code-flow.js.map +1 -1
  156. package/dist/providers/core/utils/http-client.js +36 -46
  157. package/dist/providers/core/utils/http-client.js.map +1 -1
  158. package/dist/providers/core/utils/provider-error-logger.d.ts +1 -1
  159. package/dist/providers/core/utils/provider-error-reporter.d.ts +3 -1
  160. package/dist/providers/core/utils/provider-error-reporter.js +3 -0
  161. package/dist/providers/core/utils/provider-error-reporter.js.map +1 -1
  162. package/dist/providers/core/utils/snapshot-writer.js +1 -4
  163. package/dist/providers/core/utils/snapshot-writer.js.map +1 -1
  164. package/dist/providers/mock/mock-provider-runtime.js +57 -27
  165. package/dist/providers/mock/mock-provider-runtime.js.map +1 -1
  166. package/dist/scripts/camoufox/launch-auth.mjs +193 -58
  167. package/dist/server/handlers/handler-utils.js +8 -3
  168. package/dist/server/handlers/handler-utils.js.map +1 -1
  169. package/dist/server/handlers/responses-handler.js +1 -1
  170. package/dist/server/handlers/responses-handler.js.map +1 -1
  171. package/dist/server/runtime/http-server/daemon-admin/auth-handler.d.ts +2 -0
  172. package/dist/server/runtime/http-server/daemon-admin/auth-handler.js +103 -0
  173. package/dist/server/runtime/http-server/daemon-admin/auth-handler.js.map +1 -0
  174. package/dist/server/runtime/http-server/daemon-admin/auth-session.d.ts +5 -0
  175. package/dist/server/runtime/http-server/daemon-admin/auth-session.js +77 -0
  176. package/dist/server/runtime/http-server/daemon-admin/auth-session.js.map +1 -0
  177. package/dist/server/runtime/http-server/daemon-admin/auth-store.d.ts +18 -0
  178. package/dist/server/runtime/http-server/daemon-admin/auth-store.js +89 -0
  179. package/dist/server/runtime/http-server/daemon-admin/auth-store.js.map +1 -0
  180. package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js +1 -2
  181. package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js.map +1 -1
  182. package/dist/server/runtime/http-server/daemon-admin/providers-handler.js +226 -24
  183. package/dist/server/runtime/http-server/daemon-admin/providers-handler.js.map +1 -1
  184. package/dist/server/runtime/http-server/daemon-admin/quota-handler.js +47 -8
  185. package/dist/server/runtime/http-server/daemon-admin/quota-handler.js.map +1 -1
  186. package/dist/server/runtime/http-server/daemon-admin/restart-handler.js +1 -1
  187. package/dist/server/runtime/http-server/daemon-admin/restart-handler.js.map +1 -1
  188. package/dist/server/runtime/http-server/daemon-admin/stats-handler.js +1 -1
  189. package/dist/server/runtime/http-server/daemon-admin/stats-handler.js.map +1 -1
  190. package/dist/server/runtime/http-server/daemon-admin/status-handler.js +68 -4
  191. package/dist/server/runtime/http-server/daemon-admin/status-handler.js.map +1 -1
  192. package/dist/server/runtime/http-server/daemon-admin-routes.d.ts +3 -4
  193. package/dist/server/runtime/http-server/daemon-admin-routes.js +9 -14
  194. package/dist/server/runtime/http-server/daemon-admin-routes.js.map +1 -1
  195. package/dist/server/runtime/http-server/executor-metadata.js +1 -1
  196. package/dist/server/runtime/http-server/executor-metadata.js.map +1 -1
  197. package/dist/server/runtime/http-server/executor-response.js +0 -16
  198. package/dist/server/runtime/http-server/executor-response.js.map +1 -1
  199. package/dist/server/runtime/http-server/hub-shadow-compare.js +110 -34
  200. package/dist/server/runtime/http-server/hub-shadow-compare.js.map +1 -1
  201. package/dist/server/runtime/http-server/index.d.ts +5 -3
  202. package/dist/server/runtime/http-server/index.js +281 -136
  203. package/dist/server/runtime/http-server/index.js.map +1 -1
  204. package/dist/server/runtime/http-server/middleware.js +19 -1
  205. package/dist/server/runtime/http-server/middleware.js.map +1 -1
  206. package/dist/server/runtime/http-server/request-executor.js +59 -24
  207. package/dist/server/runtime/http-server/request-executor.js.map +1 -1
  208. package/dist/server/runtime/http-server/routes.js +12 -3
  209. package/dist/server/runtime/http-server/routes.js.map +1 -1
  210. package/dist/server/runtime/http-server/session-dir.d.ts +2 -0
  211. package/dist/server/runtime/http-server/session-dir.js +59 -0
  212. package/dist/server/runtime/http-server/session-dir.js.map +1 -0
  213. package/dist/server/runtime/http-server/types.d.ts +0 -4
  214. package/dist/server/utils/utf8-chunk-buffer.js +6 -3
  215. package/dist/server/utils/utf8-chunk-buffer.js.map +1 -1
  216. package/dist/server/utils/warmup-storm-tracker.js +1 -1
  217. package/dist/server/utils/warmup-storm-tracker.js.map +1 -1
  218. package/dist/server-factory.d.ts +6 -28
  219. package/dist/server-factory.js +8 -93
  220. package/dist/server-factory.js.map +1 -1
  221. package/dist/token-daemon/index.js +2 -2
  222. package/dist/token-daemon/index.js.map +1 -1
  223. package/dist/token-daemon/provider-registry.js +0 -1
  224. package/dist/token-daemon/provider-registry.js.map +1 -1
  225. package/dist/token-daemon/server-utils.js +8 -9
  226. package/dist/token-daemon/server-utils.js.map +1 -1
  227. package/dist/token-daemon/token-utils.js +1 -1
  228. package/dist/token-daemon/token-utils.js.map +1 -1
  229. package/dist/tools/semantic-replay.js +2 -2
  230. package/dist/tools/semantic-replay.js.map +1 -1
  231. package/dist/tools/stats-request-events.d.ts +1 -1
  232. package/dist/tools/stats-usage.js +6 -3
  233. package/dist/tools/stats-usage.js.map +1 -1
  234. package/dist/utils/llms-engine-shadow.d.ts +19 -0
  235. package/dist/utils/llms-engine-shadow.js +209 -0
  236. package/dist/utils/llms-engine-shadow.js.map +1 -0
  237. package/dist/utils/runtime-versions.js +2 -1
  238. package/dist/utils/runtime-versions.js.map +1 -1
  239. package/dist/utils/strip-internal-keys.d.ts +12 -0
  240. package/dist/utils/strip-internal-keys.js +28 -0
  241. package/dist/utils/strip-internal-keys.js.map +1 -0
  242. package/docs/ARCHITECTURE.md +402 -0
  243. package/docs/CHAT_PROCESS_PROTOCOL_AND_PIPELINE.md +221 -0
  244. package/docs/CODEX_AND_CLAUDE_CODE.md +69 -0
  245. package/docs/CONFIG_ARCHITECTURE.md +517 -0
  246. package/docs/ERROR_HANDLING_AUDIT.md +0 -0
  247. package/docs/GCLI2API_PARITY_GAPS.md +98 -0
  248. package/docs/INSTALLATION_AND_QUICKSTART.md +74 -0
  249. package/docs/INSTRUCTION_MARKUP.md +89 -0
  250. package/docs/MODULE_ENHANCEMENT_SYSTEM.md +666 -0
  251. package/docs/PORTS.md +36 -0
  252. package/docs/PROVIDERS_BUILTIN.md +111 -0
  253. package/docs/PROVIDER_TYPES.md +55 -0
  254. package/docs/SERVERTOOL_CLOCK_DESIGN.md +233 -0
  255. package/docs/USAGE_HANDLING_ANALYSIS.md +335 -0
  256. package/docs/USER_CONFIG_PARSER_CHANGES.md +175 -0
  257. package/docs/V3_INBOUND_OUTBOUND_DESIGN.md +86 -0
  258. package/docs/VIRTUAL_ROUTER_PRIORITY_AND_HEALTH.md +125 -0
  259. package/docs/anthropic-request-golden-samples.md +50 -0
  260. package/docs/antigravity-gemini-format-cleanup.md +102 -0
  261. package/docs/antigravity-routing-contract.md +31 -0
  262. package/docs/ccr-alignment-enhancetool.md +105 -0
  263. package/docs/chat-glm-500-analysis.md +79 -0
  264. package/docs/chat-request-golden-samples.md +42 -0
  265. package/docs/chat-semantic-expansion-plan.md +84 -0
  266. package/docs/cli-command-inventory.md +76 -0
  267. package/docs/codex-samples-replay.md +50 -0
  268. package/docs/daemon-admin-api-design.md +350 -0
  269. package/docs/daemon-admin-module-structure.md +169 -0
  270. package/docs/daemon-admin-ui.html +3394 -0
  271. package/docs/debug-system-design.md +734 -0
  272. package/docs/debugging/gemini-sse-root-cause.md +52 -0
  273. package/docs/debugging/sse_encoding_failure_analysis.md +53 -0
  274. package/docs/dry-run/README.md +721 -0
  275. package/docs/error-handling-v2.md +92 -0
  276. package/docs/exec-command-guard-policy.example.v1.json +42 -0
  277. package/docs/fixes/gemini-protocol-mapping.md +57 -0
  278. package/docs/fixes/oauth-portal-timing-fix.md +202 -0
  279. package/docs/fixes/web-search-hop3-fix.md +265 -0
  280. package/docs/glm-api-reference.md +390 -0
  281. package/docs/glm-chat-completions.md +1779 -0
  282. package/docs/glm-history-inline-images.md +44 -0
  283. package/docs/golden-ci-library.md +66 -0
  284. package/docs/lmstudio-dry-run-summary.md +203 -0
  285. package/docs/lmstudio-tool-calling.md +214 -0
  286. package/docs/mapping-tables/anthropic-to-openai.json +290 -0
  287. package/docs/mapping-tables/iflow-to-openai.json +215 -0
  288. package/docs/mapping-tables/openai-passthrough.json +190 -0
  289. package/docs/mapping-tables/openai-to-iflow.json +227 -0
  290. package/docs/monitoring/Design.md +61 -0
  291. package/docs/multi-token-auth-guide.md +66 -0
  292. package/docs/oauth-authentication-guide.md +168 -0
  293. package/docs/oauth-iflow-implementation.md +153 -0
  294. package/docs/pipeline-routing-report.md +209 -0
  295. package/docs/plans/manager-daemon/PLAN.md +86 -0
  296. package/docs/plans/provider-config-v2-plan.md +176 -0
  297. package/docs/plans/provider-runtime-manager-plan.md +209 -0
  298. package/docs/plans/transparent-429-failover.md +89 -0
  299. package/docs/plans/unified-hub-framework-v1.md +245 -0
  300. package/docs/provider-config-v2-ui-design.md +181 -0
  301. package/docs/provider-quota-design.md +129 -0
  302. package/docs/providers/gemini-provider.md +62 -0
  303. package/docs/providers/lmstudio-v2-migration-report.md +102 -0
  304. package/docs/providers/provider-composite-design.md +142 -0
  305. package/docs/providers/provider-composite-testing.md +98 -0
  306. package/docs/providers/provider-type-only-migration.md +111 -0
  307. package/docs/rccx-wasm-migration.md +74 -0
  308. package/docs/refactoring/architecture-comparison-diagram.md +140 -0
  309. package/docs/refactoring/compatibility-v2-architecture-design.md +738 -0
  310. package/docs/refactoring/workflow-compatibility-refactoring-design.md +361 -0
  311. package/docs/reports/routing-classification-report.json +24 -0
  312. package/docs/reports/routing-classification-report.md +18 -0
  313. package/docs/reports/thinking-keywords-report.json +19 -0
  314. package/docs/responses/README.md +156 -0
  315. package/docs/responses-generic-provider.md +86 -0
  316. package/docs/responses-passthrough-provider-design.md +202 -0
  317. package/docs/routing-awrr-health-weighted-round-robin.md +179 -0
  318. package/docs/routing-instructions.md +393 -0
  319. package/docs/servertool-framework.md +65 -0
  320. package/docs/stop-message-auto.md +225 -0
  321. package/docs/streaming-flow.html +30 -0
  322. package/docs/streaming-flow.md +182 -0
  323. package/docs/token-daemon-preview.html +490 -0
  324. package/docs/token-refresh-daemon-plan.md +269 -0
  325. package/docs/transformation-tables/Gemini-FinishReason/345/256/214/346/225/264/350/275/254/346/215/242/350/241/250.json +233 -0
  326. package/docs/transformation-tables/README.md +225 -0
  327. package/docs/transformation-tables/claude-code-router-anthropic-to-gemini.json +283 -0
  328. package/docs/transformation-tables/claude-code-router-anthropic-to-openai.json +208 -0
  329. package/docs/transformation-tables/claude-code-router-openai-to-anthropic.json +261 -0
  330. package/docs/transformation-tables/claude-code-router-openai-to-gemini.json +208 -0
  331. package/docs/transformation-tables/claude-code-router-openai-to-lmstudio.json +182 -0
  332. package/docs/transformation-tables/claude-code-router-openai-to-ollama.json +250 -0
  333. package/docs/transformation-tables/claude-code-router-openai-to-textgenwebui.json +295 -0
  334. package/docs/transformation-tables/claude-code-router-provider-conversions.json +193 -0
  335. 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
  336. 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
  337. 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
  338. 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
  339. 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
  340. 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
  341. 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
  342. package/docs/v2-architecture/IMPLEMENTATION-ROADMAP.md +367 -0
  343. package/docs/v2-architecture/OPTIMIZED-DESIGN.md +827 -0
  344. package/docs/v2-architecture/PRERUN-CONNECTION-DESIGN.md +716 -0
  345. package/docs/v2-architecture/README.md +549 -0
  346. package/docs/verification/modelscope-verify.md +59 -0
  347. package/docs/verified-configs/README.md +60 -0
  348. package/docs/verified-configs/v0.45.0/README.md +244 -0
  349. package/docs/verified-configs/v0.45.0/lmstudio-5521-gpt-oss-20b-mlx.json +135 -0
  350. package/docs/verified-configs/v0.45.0/merged-config.5521.json +1205 -0
  351. package/docs/verified-configs/v0.45.0/merged-config.qwen-5522.json +1559 -0
  352. package/docs/verified-configs/v0.45.0/qwen-5522-qwen3-coder-plus-final.json +221 -0
  353. package/docs/verified-configs/v0.45.0/qwen-5522-qwen3-coder-plus-fixed.json +242 -0
  354. package/docs/verified-configs/v0.45.0/qwen-5522-qwen3-coder-plus.json +242 -0
  355. package/docs/web-search-service-design.md +322 -0
  356. package/package.json +26 -15
  357. package/scripts/build-core.mjs +3 -1
  358. package/scripts/camoufox/launch-auth.mjs +193 -58
  359. package/scripts/ci/repo-sanity.mjs +138 -0
  360. package/scripts/mock-provider/run-regressions.mjs +157 -1
  361. package/scripts/monitor-diff.mjs +126 -0
  362. package/scripts/pack-mode.mjs +19 -1
  363. package/scripts/pack-rcc.mjs +63 -0
  364. package/scripts/run-bg.sh +0 -14
  365. package/scripts/tests/ci-jest.mjs +119 -0
  366. package/scripts/tools-dev/responses-debug-client/README.md +23 -0
  367. package/scripts/tools-dev/responses-debug-client/payloads/poem.json +13 -0
  368. package/scripts/tools-dev/responses-debug-client/payloads/sample-no-tools.json +98 -0
  369. package/scripts/tools-dev/responses-debug-client/payloads/text.json +13 -0
  370. package/scripts/tools-dev/responses-debug-client/payloads/tool.json +27 -0
  371. package/scripts/tools-dev/responses-debug-client/run.mjs +65 -0
  372. package/scripts/tools-dev/responses-debug-client/src/index.ts +281 -0
  373. package/scripts/tools-dev/run-llmswitch-chat.mjs +53 -0
  374. package/scripts/tools-dev/server-tools-dev/run-web-fetch.mjs +65 -0
  375. package/scripts/unified-hub-shadow-compare.mjs +33 -13
  376. package/scripts/vendor-core.mjs +13 -3
  377. package/scripts/verify-e2e-toolcall.mjs +115 -26
  378. package/dist/modules/llmswitch/pipeline-registry.d.ts +0 -57
  379. package/dist/modules/llmswitch/pipeline-registry.js +0 -229
  380. package/dist/modules/llmswitch/pipeline-registry.js.map +0 -1
  381. package/dist/server/RouteCodexServer.d.ts +0 -13
  382. package/dist/server/RouteCodexServer.js +0 -25
  383. package/dist/server/RouteCodexServer.js.map +0 -1
  384. package/dist/v2/conversion/hub/snapshot-recorder.d.ts +0 -12
  385. package/dist/v2/conversion/hub/snapshot-recorder.js +0 -22
  386. package/dist/v2/conversion/hub/snapshot-recorder.js.map +0 -1
  387. package/scripts/test-fc-responses.mjs +0 -66
  388. package/scripts/test-guidance.mjs +0 -100
  389. package/scripts/test-iflow-web-search.mjs +0 -141
  390. package/scripts/test-iflow.mjs +0 -379
  391. package/scripts/test-tool-exec.mjs +0 -26
@@ -0,0 +1,89 @@
1
+ # Transparent 429 Failover Strategy Plan
2
+
3
+ ## Objective
4
+ Implement a transparent failover strategy for 429 (Too Many Requests) and other recoverable errors within the `RouteCodexHttpServer`. Instead of returning the error to the client and relying on client-side retries, the server should automatically switch to the next available provider and retry the request internally.
5
+
6
+ ## Current Behavior
7
+ 1. `executePipeline` runs the Hub Pipeline to select a provider.
8
+ 2. It attempts to send the request via `handle.instance.processIncoming`.
9
+ 3. If the provider returns a 429 error, the error is caught, reported via `emitProviderError`, and then re-thrown.
10
+ 4. The Express error handler catches the re-thrown error and sends an error response to the client.
11
+ 5. The Virtual Router updates its state (via `emitProviderError`), so the *next* client request is routed differently, but the *current* request fails.
12
+
13
+ ## Proposed Strategy
14
+ Modify `executePipeline` in `src/server/runtime/http-server/index.ts` to implement an internal retry loop.
15
+
16
+ ### implementation Details
17
+
18
+ #### 1. Retry Loop in `executePipeline`
19
+ Wrap the pipeline execution and provider sending logic in a loop that allows for a configurable number of retries (e.g., 3 attempts).
20
+
21
+ ```typescript
22
+ // Conceptual Logic
23
+ let attempts = 0;
24
+ const maxAttempts = 3;
25
+ const excludedProviders = new Set<string>();
26
+
27
+ while (attempts < maxAttempts) {
28
+ attempts++;
29
+ try {
30
+ // 1. Run Pipeline (Selection)
31
+ // Pass excludedProviders to metadata to hint the router to avoid them
32
+ // (Requires verification that HubPipeline respects 'excludedProviders' or 'blacklist' in metadata)
33
+ const pipelineResult = await this.runHubPipeline(input, {
34
+ ...metadata,
35
+ excludedProviders: Array.from(excludedProviders)
36
+ });
37
+
38
+ // 2. Prepare Provider
39
+ // ... (existing preparation logic) ...
40
+
41
+ // 3. Send to Provider
42
+ const response = await handle.instance.processIncoming(providerPayload);
43
+
44
+ // Success - return response
45
+ return convertedResponse;
46
+
47
+ } catch (error) {
48
+ // 4. Error Handling & Failover Decision
49
+ const status = this.extractResponseStatus(error) || error.status;
50
+ const isRateLimit = status === 429 || error.code === '429';
51
+
52
+ // Verify if we should retry
53
+ if (isRateLimit && attempts < maxAttempts) {
54
+ // Log the internal failover
55
+ this.logStage('provider.failover', input.requestId, { ... });
56
+
57
+ // Report error to update Router health state
58
+ emitProviderError({ ... });
59
+
60
+ // Add current provider to exclusion list for next iteration
61
+ if (target?.providerKey) {
62
+ excludedProviders.add(target.providerKey);
63
+ }
64
+
65
+ // Continue to next loop iteration
66
+ continue;
67
+ }
68
+
69
+ // If not retryable or exhausted, re-throw (existing behavior)
70
+ throw error;
71
+ }
72
+ }
73
+ ```
74
+
75
+ #### 2. Metadata Handling
76
+ Ensure that `runHubPipeline` and the underlying `llmswitch-core` Hub Pipeline can accept an exclusion list. If direct support is missing, we rely on the `emitProviderError` call, which should update the Virtual Router's health state (marking the node as unhealthy/rate-limited). The subsequent `runHubPipeline` call should then naturally pick a different healthy provider.
77
+
78
+ #### 3. Circuit Breaking
79
+ The `emitProviderError` function already integrates with `providerErrorCenter`. We must ensure that 429 errors trigger a temporary "unhealthy" status in the router's load balancer so that the failing provider is skipped in the immediate retry.
80
+
81
+ ### Risks & Mitigations
82
+ * **Infinite Loops**: Strict `maxAttempts` counter prevents indefinite loops.
83
+ * **Latency**: Retries add latency. We should ensure the `attempts` cap is low (e.g., 3) to fail fast if all providers are busy.
84
+ * **State Propagation**: If `emitProviderError` is async or slow to update the Router state, the retry might pick the same provider. Passing `excludedProviders` in metadata is the robust fix, assuming Router support.
85
+
86
+ ## Next Steps
87
+ 1. Verify if `HubPipeline.execute` supports `excludedProviders` or `blacklist` in input metadata.
88
+ 2. Implement the retry loop in `src/server/runtime/http-server/index.ts`.
89
+ 3. Test with a mock provider simulating 429s to verify failover behavior.
@@ -0,0 +1,245 @@
1
+ # Unified Hub Framework V1(单一路径 + 强制白名单 + 协议注册表)设计文档
2
+
3
+ 本文档是一个“逐步迁移”的架构改造计划,目标是把当前 llmswitch-core 的入站/出站/工具治理/ServerTool followup 等逻辑,收敛到**一套不可绕过的骨架**(single execution path),并把协议差异从“各处散落实现”改造成“表驱动 + 注册表 + 强制策略(policy)”。
4
+
5
+ ## 0. 背景与约束(不可违背)
6
+
7
+ 来自 RouteCodex V2 Working Agreement 的硬约束:
8
+
9
+ - **单一执行路径**:`HTTP server → llmswitch-core Hub Pipeline → Provider V2 → upstream AI`。
10
+ - **llmswitch-core 负责工具与路由**:host/server/provider 不得“修补工具调用/重写参数/决定路由”;只能使用 Hub Pipeline APIs。
11
+ - **Provider 层仅做传输**:auth/HTTP/retry/compat hook,不做 payload 语义检查与修补。
12
+ - **Fail fast**:上游错误必须经 providerErrorCenter + errorHandlingCenter 冒泡,无静默 fallback。
13
+ - **Config-driven**:host 只消费 `bootstrapVirtualRouterConfig` 的输出。
14
+
15
+ 本文档的方案会把这些约束“制度化”为框架级别的强制机制,而不是依赖开发习惯。
16
+
17
+ ## 0.1 当前落地状态(截至 2026-01-18)
18
+
19
+ - Host 已默认注入 `hubConfig.policy.mode="enforce"`(Phase 1:Responses-first provider outbound policy),可通过 `ROUTECODEX_HUB_POLICY_MODE=off` 显式关闭。
20
+ - llmswitch-core PolicyEngine 已支持 Responses 的 provider outbound wrapper 清理(例如扁平化 `request`/`parameters` wrapper)。
21
+
22
+ ## 1. 问题陈述(为什么会反复回归)
23
+
24
+ 现状并不是“没有骨架”,而是:
25
+
26
+ 1) **协议差异分散在多处,形成多套“局部骨架”**
27
+ - 同一类规则(参数白名单/字段位置/工具形态)在 semantic-mapper、bridge、servertool followup builder 等地方各写一份。
28
+ - 这些模块在实践中具备“独立执行能力”(自己组包/自己变更结构),导致出现“绕过骨架”的第二路径。
29
+
30
+ 2) **白名单不是中心化的“契约/政策”,而是若干实现片段**
31
+ - 改动时很容易只改到一处,漏掉其它分支(例如 wrapper/字段位置差异导致的 400/502)。
32
+ - CI 难以系统性捕获:因为没有统一的策略验证点,违规不会在边界处被观测/阻断。
33
+
34
+ 3) **语义治理(tools/servertools/stopMessage/web_search)仍然夹杂在协议实现里**
35
+ - 导致协议越多,分叉越多;新增功能时会在多个协议上重复做“相同语义”的实现与修补。
36
+
37
+ ## 2. 目标(V1 的“完成态”)
38
+
39
+ V1 的完成态强调“可被强制执行”的工程结构:
40
+
41
+ - **HubPipeline 是唯一可执行入口**:任何入站、出站、followup 都必须通过同一条 pipeline 路径。
42
+ - **协议实现不可独立执行**:协议代码只允许提供 `ProtocolSpec`(表/纯函数),不允许直接拼装可出站 payload。
43
+ - **白名单/字段位置/映射规则由 PolicyEngine 统一执行**:协议实现不能绕过;CI 可以强约束。
44
+ - **语义统一到 ChatSemantics 的 Operation Table**:协议只负责“wire ↔ ops”的映射;所有行为由统一的 ops 执行器完成。
45
+
46
+ ## 3. 核心方案(架构组件)
47
+
48
+ ### 3.1 ProtocolSpec:协议规格注册表(不可执行)
49
+
50
+ 为每个协议定义一个“规格对象”,用于描述差异,而不是承载执行逻辑。
51
+
52
+ 建议结构(概念):
53
+
54
+ - `id`: 协议标识(如 `openai-responses` / `anthropic-messages` / `gemini-chat` …)
55
+ - `wireShape`: 入站/出站字段布局约束
56
+ - 允许出现在哪些层级(top-level / metadata.extraFields / internal carrier)
57
+ - streaming 字段优先级与限制(followup 必须 non-stream 等)
58
+ - `parameterPolicy`: 参数白名单与映射
59
+ - allowlist(按方向:client_in / provider_out / provider_in / client_out)
60
+ - key remap(如 `max_tokens -> max_output_tokens`)
61
+ - container/layout(例如 Responses:禁止 `parameters:{...}` wrapper,只能 flatten)
62
+ - `toolSurface`: 工具定义/调用/结果的形态规范
63
+ - tool definition shape(function tools / builtin tools)
64
+ - tool call shape(chat 的 tool_calls vs responses 的 output.function_call)
65
+ - tool result shape(submit_tool_outputs 形态)
66
+ - `compatProfiles`: 可选的兼容 profile(仅做字段 remap/cleanup;禁止做语义修复/路由决策)
67
+
68
+ 实现原则:
69
+
70
+ - ProtocolSpec 只允许“表 + 纯函数”,不得访问网络/环境/路由状态。
71
+ - ProtocolSpec 不能调用 Provider;所有出站必须由骨架统一负责。
72
+
73
+ ### 3.2 PolicyEngine:强制白名单/字段位置/映射执行器(骨架所有)
74
+
75
+ PolicyEngine 是 HubPipeline 内部组件,负责把 ProtocolSpec 转化为“不可绕过的边界政策”。
76
+
77
+ PolicyEngine 在每个边界执行三类动作:
78
+
79
+ 1) `sanitize`:不允许字段一律转入 `metadata.extraFields`
80
+ - 不丢上下文,但**绝不让违规字段出站**。
81
+
82
+ 2) `normalize`:按 spec 做 key remap + 字段布局标准化
83
+ - 解决“同语义不同字段位置/命名”导致的协议不兼容问题。
84
+
85
+ 3) `assert`:在 CI/调试模式下硬断言
86
+ - “违规字段/布局/工具形态”直接抛错(fail fast)。
87
+ - 生产环境可采用 “采样断言 + 快照上报”,先观测再逐步收紧。
88
+
89
+ PolicyEngine 的关键要求:
90
+
91
+ - **所有出站(含 servertool followup)必须经 PolicyEngine**。
92
+ - 协议实现不得自行做白名单过滤/布局变更;否则将形成多套政策源。
93
+
94
+ ### 3.3 Operation Table:统一语义到 ChatSemantics(配置驱动)
95
+
96
+ 把“行为”从协议实现里抽离,迁移到 chat process 的统一语义表上:
97
+
98
+ - `ChatSemantics.ops: Operation[]`(或分域后最终归并为 Operation 表)
99
+ - 每个 Operation 是可组合的执行单元(已有能力应尽量复用现存实现):
100
+ - tool governance(形态校验/归一化/透传策略)
101
+ - web_search(注入 tool result / 或其它注入策略)
102
+ - stopMessage(停下/继续的 followup 生成)
103
+ - streaming 决策
104
+ - route hints / sticky / clear 等路由指令(仍属于 core)
105
+
106
+ 协议差异将变为:
107
+
108
+ - “wire → ops 的映射表” + “ops → wire 的渲染表”
109
+
110
+ 而不是:
111
+
112
+ - “每协议一套 if/else 行为实现”。
113
+
114
+ ### 3.4 Canonical Builders:收口所有“组包”入口(尤其 followup)
115
+
116
+ 在 V1 里必须明确禁止以下行为:
117
+
118
+ - 在 servertool handler 内自行 build provider payload(协议分支拼装)
119
+ - 在 bridge 内部自行决定字段布局(绕过政策)
120
+
121
+ 替代方案:
122
+
123
+ - `buildProviderRequestFromChat(envelope, spec, ctx)`:唯一出站组包入口
124
+ - `buildClientResponseFromChat(envelope, spec, ctx)`:唯一回包入口
125
+ - `buildFollowupFromCapturedEntry(capture, injection, ctx)`:唯一 followup 入口
126
+ - followup 必须复用入口 capture(深拷贝),只做 injection
127
+ - `disableStickyRoutes: true` / `preserveRouteHint: false` / entry endpoint meta 等策略由框架统一注入,而不是散落在各 handler
128
+
129
+ ## 4. 迁移路线(逐步收敛、可回滚)
130
+
131
+ ### Phase 0(观测):只记录不改写
132
+
133
+ 目标:建立“可量化的违规清单”,不破坏现有行为。
134
+
135
+ - 在 HubPipeline 关键边界插入 PolicyEngine 的 observe 模式:
136
+ - req inbound 完成后
137
+ - provider outbound 发送前
138
+ - provider inbound 解析后
139
+ - client outbound 回包前
140
+ - 输出:
141
+ - 每协议的违规字段统计
142
+ - 违规快照(含 requestId/endpoint/protocol)
143
+
144
+ 验收标准:
145
+
146
+ - 不改变任何线上行为(只加日志/快照)。
147
+ - 能得到一份“每协议整改 checklist”。
148
+
149
+ ### Phase 1(政策收口):统一参数白名单 + 字段位置(收益最大、风险最低)
150
+
151
+ 目标:解决大部分 “400/字段不认/位置不对” 类问题,并防止复发。
152
+
153
+ - 建立 `ProtocolSpec.parameterPolicy` 并把所有协议的 allowlist/映射/容器规则收口。
154
+ - 所有 provider outbound(含 followup)必须走:
155
+ - `sanitize → normalize → buildProviderRequestFromChat`
156
+ - CI 新增断言:
157
+ - “禁止出现未允许字段”
158
+ - “禁止出现错误容器/布局(例如 parameters wrapper)”
159
+
160
+ 验收标准:
161
+
162
+ - 通过错误样本回归(errorsamples)与现有 e2e。
163
+ - 违规字段数量显著下降,且新增协议不会引入新路径。
164
+
165
+ ### Phase 2(工具形态收口):统一 tools 的 definition/call/result 骨架
166
+
167
+ 目标:工具循环不再因为“形态改写/历史与本次不一致”反复出错。
168
+
169
+ - 将工具表述抽象为 `ProtocolSpec.toolSurface`,并在 PolicyEngine/ToolGovernance 边界统一治理:
170
+ - “形态归一”与“透传模式”都必须可由 spec/policy 配置(支持 A/B)。
171
+ - 明确规则:
172
+ - **任何情况下回包格式必须正确**(内容不一定正确,但结构不得静默失败)。
173
+ - 禁止 silent catch:需要结构化记录 + 可定位快照。
174
+
175
+ 验收标准:
176
+
177
+ - 新增工具/新增协议不会导致工具循环分叉。
178
+ - tool governance 的行为可配置、可回放、可回归。
179
+
180
+ ### Phase 3(followup 收口):ServerTool followup 彻底统一
181
+
182
+ 目标:stopMessage/web_search/apply_patch_guard 等 followup 都走同一条路径。
183
+
184
+ - 强制:所有 handler 只负责“决定 injection”,不得自行构造 payload。
185
+ - `FollowupRequestBuilder` 从 capture 构造(深拷贝)并注入:
186
+ - entry endpoint meta(保证回路正确)
187
+ - disableStickyRoutes / preserveRouteHint 等框架策略
188
+ - route hint/stopMessage 状态推进策略
189
+
190
+ 验收标准:
191
+
192
+ - servertools 之间只允许注入内容不同,结构生成逻辑完全复用。
193
+ - 任意协议下 followup 构建一致,差异由 spec 控制。
194
+
195
+ ### Phase 4(语义迁移):把协议逻辑迁移到 Operation Table
196
+
197
+ 目标:把“协议分支中的语义实现”迁出,协议只保留映射表。
198
+
199
+ - 从通用语义开始迁移:streaming、tool choice、web_search、stopMessage。
200
+ - 再迁移协议特殊字段为 ops 映射(保持兼容 profile 仅做字段清理)。
201
+
202
+ 验收标准:
203
+
204
+ - semantic-mapper 逻辑显著减少,主要是字段搬运+映射。
205
+ - 新增语义能力只需新增 Operation(无需改多协议分支)。
206
+
207
+ ### Phase 5(删旧路径):删除独立执行逻辑,保证“只有一个执行路径”
208
+
209
+ 目标:结构性保证不再回到“各自实现”的状态。
210
+
211
+ - 标记旧的 builders/bridges 为 deprecated。
212
+ - 删除/封装所有允许绕过骨架的入口函数,仅保留:
213
+ - ProtocolSpec 注册
214
+ - PolicyEngine 执行
215
+ - Operation 执行器
216
+
217
+ ## 5. 测试与回归策略(保证可控演进)
218
+
219
+ 建议把回归分为三层,确保每一层都有“格式必正确”的断言:
220
+
221
+ 1) **PolicyEngine 单元测试**:每协议的 allowlist/layout/映射测试(可表驱动)。
222
+ 2) **HubPipeline 快照回归**:errorsamples(输入/输出/快照 meta)覆盖典型失败场景。
223
+ 3) **端到端(可选但建议)**:启动 mock upstream(如 antigravity)对 provider 直接请求,覆盖工具循环与 followup 行为。
224
+
225
+ ## 6. 风险与控制(如何避免“大改崩盘”)
226
+
227
+ - 风险:一次性收口会影响多协议行为。
228
+ - 控制:Phase 0 先观测,Phase 1 只动白名单与布局,逐步收紧断言。
229
+ - 风险:协议特殊 case 被误当作“违规字段”移入 extraFields。
230
+ - 控制:spec 明确声明允许字段;extraFields 仅作为保留槽,不应出站。
231
+ - 风险:开发绕过框架继续写独立逻辑。
232
+ - 控制:CI 增加“边界断言 + 禁止导入/调用某些 builder”的 lint 规则(后续实现)。
233
+
234
+ ## 7. 需要你审批的“下一步落地切入点”
235
+
236
+ 为了最小风险、最大收益,建议优先落地:
237
+
238
+ - **Phase 0**:PolicyEngine observe-only(不改行为)
239
+ - **Phase 1**:参数白名单与字段位置收口(把出站组包入口统一)
240
+
241
+ 审批点建议:
242
+
243
+ - ProtocolSpec 的最小字段集合(V1 先覆盖 parametersPolicy + wireShape 的关键布局规则)。
244
+ - PolicyEngine 的运行模式(CI hard assert / prod 采样)。
245
+ - followup 的统一 builder 是否在 Phase 1 还是 Phase 3 再收口(取决于当前回归压力)。
@@ -0,0 +1,181 @@
1
+ # Provider 管理视图(基于 Config V2)的 UI 设计草案
2
+
3
+ > 目标:在现有 Daemon / Token 管理 UI 之外,增加一层 **“基于 Config V2 的 Provider 管理视图”**。
4
+ > 前端完全通过 API 读取 Config V2 的声明性配置,只读展示,不直接改 runtime,也不在 UI 内做 routing / tool 语义。
5
+
6
+ ---
7
+
8
+ ## 1. 数据来源与边界
9
+
10
+ - **数据来源**
11
+ - Config V2 中的 provider 定义(未来的 `provider-v2-loader` + `virtual-router-builder` 的输出),预期字段包括:
12
+ - `providerId` / `runtimeKey`
13
+ - `providerFamily`(`openai` / `anthropic` / `gemini` / `glm` / `antigravity` …)
14
+ - `protocol`(`openai-chat` / `openai-responses` / `gemini-chat` / `anthropic-messages` …)
15
+ - 绑定的 `targetRuntime` / route key
16
+ - 默认模型 / model aliases / series(`thinking` / `claude` / `gemini-pro` …)
17
+ - quota 策略 / cooldown 策略(如果在 V2 里挂)
18
+ - flags:`enabled` / `disabled`、`beta`、`internal-only` 等
19
+
20
+ - **边界约束**
21
+ - UI 只读 Config V2 的**声明性配置**,不直接操作虚拟路由 runtime。
22
+ - 真正的合并 / 组装仍然走 `bootstrapVirtualRouterConfig`,UI 只是把结果可视化。
23
+ - 不在这个视图里做工具语义或 routing 逻辑,只展示:
24
+ - “有哪些 provider”
25
+ - “它们绑定到哪些 runtime / route / credential”
26
+
27
+ ---
28
+
29
+ ## 2. UI 入口:Providers (Config V2) 子视图
30
+
31
+ - 顶层 Tab 仍然是 `Providers`(复用 daemon/token 管理 UI)。
32
+ - 在 `Providers` Tab 内增加二级切换:
33
+ - `Runtime health`:现有视图,展示虚拟路由 runtime 的健康状态(metrics、429 冷却等)。
34
+ - `Config V2`:**新视图**,只从 Config V2 读取 provider 定义,做表格 + 详情的只读展示。
35
+
36
+ > 设计原则:Runtime health = “实际运行状态”;Config V2 = “声明性配置视图”。两者同屏,但逻辑解耦。
37
+
38
+ ---
39
+
40
+ ## 3. Config V2 Providers 视图布局
41
+
42
+ ### 3.1 顶部 Summary 区
43
+
44
+ - **聚合统计**
45
+ - Providers 总数:`N`(从 Config V2 统计)
46
+ - 各 family 数量:OpenAI / Anthropic / Gemini / Antigravity / GLM …
47
+ - Enabled vs Disabled:`N_enabled` / `N_disabled`
48
+ - **Config 路径信息**
49
+ - 显示 Config V2 的主配置文件路径(只读),例如:
50
+ - `config/virtualrouter.v2.json`
51
+ - 或其它 V2 入口文件(如 modules 配置)
52
+
53
+ ### 3.2 Provider 列表(主表格)
54
+
55
+ - 建议列:
56
+ - **Provider ID**:如 `antigravity.jasonqueque.gemini-3-pro-low`
57
+ - **Family**:`Gemini` / `OpenAI` / `Anthropic` / `GLM` / `Antigravity` …
58
+ - **Protocol**:`gemini-chat` / `openai-responses` / `anthropic-messages` …
59
+ - **Runtime**:虚拟路由 runtime key(如 `antigravity.jasonqueque`)
60
+ - **Default route / series**:如 `default/thinking-primary`、`default/claude-series`
61
+ - **Enabled**:`Yes` / `No`
62
+ - **Source**:Config 文件标识(例如 `virtualrouter.v2.json#providers[3]`)
63
+ - **Bound credential**:从 daemon/credentials 关联过来的 credential 名称(只读,展示非敏感信息)
64
+
65
+ - 行级操作(设计层面,仅发起只读 API 调用):
66
+ - **Preview route**
67
+ - 调用 `/config/providers/v2/:id/preview-route`
68
+ - 展示该 provider 在虚拟路由中的匹配规则 / fallback 方案(人类可读文本)
69
+ - **View health**
70
+ - 切换到 `Runtime health` 子视图并带过滤条件,只看该 provider 的健康 + 429 情况
71
+ - **不提供直接 enable/disable**
72
+ - 避免在 UI 中直接修改 Config V2,保持“配置文件是唯一真相”的原则。
73
+ - 如果未来需要变更,可考虑“生成 patch 文件”而不是在线修改。
74
+
75
+ ### 3.3 Provider 详情(侧边栏 / Modal)
76
+
77
+ 点击表格某行,右侧弹出详情区域,包含:
78
+
79
+ - **基础信息**
80
+ - Provider ID / Runtime / Family / Protocol
81
+ - 所属 route / series(如 `route: "default"`, `series: "gemini-pro"`)
82
+
83
+ - **模型配置**
84
+ - 默认模型:如 `defaultModel: "gemini-3-pro-low"`
85
+ - 允许模型列表:`allowedModels: [...]`
86
+ - 模型别名映射:如 `thinking`, `fast`, `long-context` 等到具体 model 的映射
87
+
88
+ - **Quota / Cooldown 策略(如果在 Config V2 中声明)**
89
+ - per-minute / per-hour 限额(静态配置)
90
+ - series cooldown 策略(与 virtual router 概念对齐,但数据来自 config)
91
+
92
+ - **Credentials 绑定**
93
+ - 展示关联的 credential 引用(例如 `credentialsRef: "antigravity-oauth-2-jasonqueque.json"`)
94
+ - 只显示文件名 / project_id 等非敏感字段。
95
+ - 提供“查看凭证详情”按钮:
96
+ - 切换到 `Credentials` Tab,并自动筛选对应 credential。
97
+
98
+ - **只读说明**
99
+ - 在详情底部加一行固定提示:
100
+ - `All fields are read-only; edits must go through Config V2 files and a full RouteCodex reload.`
101
+
102
+ ---
103
+
104
+ ## 4. 后端 API 规划(只读,供 UI 使用)
105
+
106
+ > 仅为 UI 设计预留接口,不在本任务中实现。
107
+ > 真正实现时需要同时满足:本地访问安全 + 不泄露敏感字段(例如密钥)。
108
+
109
+ - `GET /config/providers/v2`
110
+ - 返回 provider 列表,示例形态:
111
+ ```jsonc
112
+ [
113
+ {
114
+ "id": "antigravity.jasonqueque.gemini-3-pro-low",
115
+ "family": "gemini",
116
+ "protocol": "gemini-chat",
117
+ "runtimeKey": "antigravity.jasonqueque",
118
+ "route": "default",
119
+ "series": "gemini-pro",
120
+ "enabled": true,
121
+ "source": "virtualrouter.v2.json#providers[3]",
122
+ "defaultModels": ["gemini-3-pro-low"],
123
+ "credentialsRef": "antigravity-oauth-2-jasonqueque.json"
124
+ }
125
+ ]
126
+ ```
127
+
128
+ - `GET /config/providers/v2/:id`
129
+ - 返回单个 provider 的完整配置,包括:
130
+ - 基础信息
131
+ - 模型列表 / 别名
132
+ - quota 配置
133
+ - override 标记
134
+ - 可选 notes / description
135
+
136
+ - `GET /config/providers/v2/:id/preview-route`
137
+ - 返回该 provider 在虚拟路由中的匹配 / fallback 逻辑(已经由后端渲染为人类可读文本)。
138
+ - 用于前端详情中的 “Preview route” 区块。
139
+
140
+ > 暂不设计任何 `POST` / `PATCH` API,未来若需要可以扩展为“生成配置 patch 文件”而不是直接改动 Config V2。
141
+
142
+ ---
143
+
144
+ ## 5. 与现有 Daemon / Token UI 的关系
145
+
146
+ - **Daemon / Token 管理 UI**
147
+ - 负责 token、credentials、health、quota 的运行时视图:
148
+ - Daemon 状态(进程 / uptime / 监听端口)
149
+ - Token / Quota 使用情况、429 冷却
150
+ - Credentials 列表与验证
151
+ - Runtime health(per provider / per series)
152
+
153
+ - **Config V2 Provider 管理视图**
154
+ - 负责 “有哪些 provider 以及它们在 Config V2 中如何声明”:
155
+ - Provider ID / family / protocol / runtime / route / series
156
+ - Config 来源文件
157
+ - 声明性的 quota / cooldown 策略
158
+ - 绑定到哪个 credential
159
+
160
+ - **两者的关联方式**
161
+ - 通过 `runtimeKey` + `credentialsRef` 进行关联:
162
+ - 在 Providers (Config V2) 视图中展示绑定的 credential 名称。
163
+ - 在 Credentials 视图中可以反查“这个 credential 被哪些 provider 使用”。
164
+ - Runtime 健康信息仍然来自虚拟路由实际状态,Config V2 视图不直接读 health,而是通过跳转 / filter 进行联动。
165
+
166
+ ---
167
+
168
+ ## 6. 后续实现路线(高层 TODO,仅做规划)
169
+
170
+ 1. **后端只读 API 草案实现**
171
+ - 在 daemon / host 中实现 `/config/providers/v2*` 只读接口。
172
+ - 确保敏感字段(密钥、token 值)不会出现在返回数据中。
173
+ 2. **在现有 `daemon-admin-ui.html` 里接入 Providers(Config V2) 子视图**
174
+ - 添加二级 Tab 切换。
175
+ - 用静态假数据先跑通布局,再替换为 API 请求。
176
+ 3. **与 Credentials / Runtime health 联动**
177
+ - Providers 视图中点击 credential / health 操作时,跳转到对应 Tab 并带筛选条件。
178
+ 4. **Config V2 ready 之后对齐实际 schema**
179
+ - 一旦 Config V2 schema 固定,更新此文档中的字段命名与示例。
180
+ - 清理临时字段,保持“Config 驱动”原则:UI 只读配置,不干预 llmswitch-core 的路由 / 工具逻辑。
181
+
@@ -0,0 +1,129 @@
1
+ # Provider Quota / Health 管理(文件落盘设计草案)
2
+
3
+ > 目标:把 provider 健康与流控统一抽象为 quota,通过 daemon 维护一份落盘快照;virtual-router 只读快照决定是否进入路由池与调度优先级。
4
+
5
+ ## 1. 文件结构
6
+
7
+ - 根目录:`~/.routecodex/quota/`
8
+ - `provider-quota.json`:当前生效的 quota 快照(virtual-router 只读)。
9
+ - `provider-errors.ndjson`:错误事件流水(daemon 可选使用,用于恢复 / 调试)。
10
+
11
+ ### 1.1 `provider-quota.json`
12
+
13
+ ```jsonc
14
+ {
15
+ "version": 1,
16
+ "updatedAt": "2026-01-15T09:30:12.345Z",
17
+ "providers": {
18
+ "antigravity.alias1.gemini-3-pro-high": {
19
+ "providerKey": "antigravity.alias1.gemini-3-pro-high",
20
+ "providerId": "antigravity.alias1",
21
+ "inPool": false,
22
+ "reason": "cooldown", // ok|cooldown|blacklist|quotaDepleted|fatal
23
+ "priorityTier": 100,
24
+ "rateLimitPerMinute": null, // null = 不限制
25
+ "tokenLimitPerMinute": null,
26
+ "totalTokenLimit": null,
27
+ "windowStartMs": 1768439400000,
28
+ "requestsThisWindow": 12,
29
+ "tokensThisWindow": 8200,
30
+ "totalTokensUsed": 120000,
31
+ "cooldownUntil": 1768439700000, // ms since epoch,null 表示无
32
+ "blacklistUntil": null,
33
+ "lastErrorSeries": "E429",
34
+ "consecutiveErrorCount": 2
35
+ }
36
+ }
37
+ }
38
+ ```
39
+
40
+ - 静态 quota:
41
+ - `priorityTier`:优先级,未配置统一为 `100`。
42
+ - `rateLimitPerMinute`:每分钟请求数,默认不限制。
43
+ - `tokenLimitPerMinute` / `totalTokenLimit`:默认不限制。
44
+ - 动态状态:
45
+ - `inPool` + `reason`:是否参与路由池以及原因。
46
+ - `cooldownUntil` / `blacklistUntil`:冷却与锁定窗口。
47
+ - `consecutiveErrorCount` / `lastErrorSeries`:用于“连续多次同类错误”的判定(默认第 4 次进入黑名单)。
48
+
49
+ ### 1.2 `provider-errors.ndjson`
50
+
51
+ 每行一条错误事件,供 daemon 消费或调试:
52
+
53
+ ```json
54
+ {"ts":"2026-01-15T09:14:20.123Z","providerKey":"antigravity.alias1.gemini-3-pro-high","errorCode":"429","series":"E429","route":"thinking","requestId":"...","httpStatus":429,"retryable":true}
55
+ ```
56
+
57
+ ## 2. 逻辑规则摘要
58
+
59
+ ### 2.1 错误到 quota 的映射
60
+
61
+ - 错误 series:`seriesKey = providerKey + ':' + normalizedErrorCode`
62
+ - `E429`:HTTP 429 / rate-limit。
63
+ - `E5xx`:稳定性问题(5xx)。
64
+ - `ENET`:网络 / 超时。
65
+ - `EFATAL`:不可恢复(配置错误、认证失败、非法模型等)。
66
+
67
+ #### 429 与其它可恢复错误
68
+
69
+ - 单一 series 内,连续错误次数 `n`:
70
+ - 第 1 次:`cooldownUntil = now + 1min`,`inPool=false`。
71
+ - 第 2 次:`cooldownUntil = now + 3min`。
72
+ - 第 3 次:`cooldownUntil = now + 5min`。
73
+ - 同一 series 连续 4 次错误:
74
+ - `blacklistUntil = now + 6h`,`inPool=false`,`reason='blacklist'`。
75
+ - 任意成功事件:
76
+ - 清零该 provider 的所有 `consecutiveErrorCount`;
77
+ - 若无有效 `blacklistUntil` 且 `cooldownUntil` 已过期,则恢复 `inPool=true, reason='ok'`。
78
+
79
+ #### 不可恢复错误(EFATAL)
80
+
81
+ - 直接:
82
+ - `blacklistUntil = now + 6h`;
83
+ - `inPool=false, reason='fatal'`。
84
+ - 恢复依赖时间到期或管理操作,成功事件不会自动解除。
85
+
86
+ ### 2.2 静态 quota(apikey provider)
87
+
88
+ - 优先级:
89
+ - 由配置文件提供 `priorityTier`,未配置统一为 `100`。
90
+ - virtual-router 构建池时按 tier 从小到大分组,同一 tier 内做轮询或加权轮询。
91
+ - 时间流控:
92
+ - `rateLimitPerMinute`:按 1 分钟窗口统计 `requestsThisWindow`,超过则标记 `reason='quotaDepleted'`,直到窗口翻转。
93
+ - token 控制:
94
+ - `tokenLimitPerMinute`:按 1 分钟窗口统计 `tokensThisWindow`。
95
+ - `totalTokenLimit`:累加 `totalTokensUsed`,超过后可直接锁定或标记 `quotaDepleted`。
96
+
97
+ ## 3. 分阶段落地路线(先测试再接线)
98
+
99
+ ### Phase 1:纯逻辑(无 I/O)
100
+
101
+ - 新增 `provider-quota-center`(纯函数,不依赖文件):
102
+ - `applyErrorEvent` / `applySuccessEvent` / `applyUsageEvent` / `tickWindow`。
103
+ - 在 tests 中为上述规则写完整单元测试:
104
+ - 429 / 其它错误的 1/3/5 分钟与三连错 6 小时;
105
+ - 成功会清零“连续”错误计数;
106
+ - 静态 `priorityTier` 默认 100,quota 默认无限制。
107
+
108
+ ### Phase 2:文件存储层
109
+
110
+ - 实现 `provider-quota-store`:
111
+ - `loadSnapshot` / `saveSnapshot` 基于 `provider-quota.json`,原子写入。
112
+ - `appendErrorEvent` 追加写 `provider-errors.ndjson`。
113
+ - 提供一个 `scripts/quota-dryrun.mjs`:
114
+ - 从事件 fixture 读入,驱动 quota center,输出 `provider-quota.json` 供人工检查。
115
+
116
+ ### Phase 3:Quota Daemon(独立运行)
117
+
118
+ - 在 daemon 进程中集成 quota center 与 store:
119
+ - 从错误 / 成功 / usage 事件源消费消息;
120
+ - 周期性更新内存状态并写回 `provider-quota.json`。
121
+ - 提供 `--dry-run` / `--once` 模式,仅读取 `provider-errors.ndjson` 和 config,生成一次快照后退出,用于验证逻辑。
122
+
123
+ ### Phase 4:virtual-router 接线(可通过 feature flag 控制)
124
+
125
+ - 在 virtual-router 构建 provider 池时:
126
+ - 可选读取 `~/.routecodex/quota/provider-quota.json`:
127
+ - 过滤 `inPool !== true` 或 `cooldownUntil/blacklistUntil > now` 的 provider。
128
+ - 按 `priorityTier` 做 tier 调度。
129
+ - 初期通过环境变量开启(例如 `ROUTECODEX_QUOTA_ENABLED=1`),待稳定后再作为默认路径。