@jsonstudio/rcc 0.89.168 → 0.89.524

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 (431) hide show
  1. package/README.md +18 -15
  2. package/dist/build-info.js +3 -3
  3. package/dist/build-info.js.map +1 -1
  4. package/dist/cli.js +94 -0
  5. package/dist/cli.js.map +1 -1
  6. package/dist/client/gemini-cli/gemini-cli-protocol-client.js +28 -5
  7. package/dist/client/gemini-cli/gemini-cli-protocol-client.js.map +1 -1
  8. package/dist/commands/token-daemon.d.ts +2 -0
  9. package/dist/commands/token-daemon.js +183 -0
  10. package/dist/commands/token-daemon.js.map +1 -0
  11. package/dist/error-handling/quiet-error-handling-center.d.ts +9 -0
  12. package/dist/error-handling/quiet-error-handling-center.js +141 -0
  13. package/dist/error-handling/quiet-error-handling-center.js.map +1 -0
  14. package/dist/error-handling/route-error-hub.js +8 -2
  15. package/dist/error-handling/route-error-hub.js.map +1 -1
  16. package/dist/index.js +4 -3
  17. package/dist/index.js.map +1 -1
  18. package/dist/modules/llmswitch/bridge.d.ts +1 -1
  19. package/dist/modules/llmswitch/bridge.js +3 -2
  20. package/dist/modules/llmswitch/bridge.js.map +1 -1
  21. package/dist/modules/pipeline/utils/colored-logger.d.ts +2 -0
  22. package/dist/modules/pipeline/utils/colored-logger.js +22 -3
  23. package/dist/modules/pipeline/utils/colored-logger.js.map +1 -1
  24. package/dist/providers/auth/antigravity-userinfo-helper.d.ts +10 -0
  25. package/dist/providers/auth/antigravity-userinfo-helper.js +140 -0
  26. package/dist/providers/auth/antigravity-userinfo-helper.js.map +1 -0
  27. package/dist/providers/auth/gemini-cli-userinfo-helper.js +12 -2
  28. package/dist/providers/auth/gemini-cli-userinfo-helper.js.map +1 -1
  29. package/dist/providers/auth/oauth-lifecycle.js +395 -24
  30. package/dist/providers/auth/oauth-lifecycle.js.map +1 -1
  31. package/dist/providers/auth/token-scanner/index.d.ts +32 -0
  32. package/dist/providers/auth/token-scanner/index.js +86 -0
  33. package/dist/providers/auth/token-scanner/index.js.map +1 -0
  34. package/dist/providers/auth/tokenfile-auth.d.ts +17 -0
  35. package/dist/providers/auth/tokenfile-auth.js +27 -5
  36. package/dist/providers/auth/tokenfile-auth.js.map +1 -1
  37. package/dist/providers/core/api/provider-types.d.ts +10 -0
  38. package/dist/providers/core/config/oauth-flows.d.ts +25 -0
  39. package/dist/providers/core/config/oauth-flows.js +92 -5
  40. package/dist/providers/core/config/oauth-flows.js.map +1 -1
  41. package/dist/providers/core/config/provider-oauth-configs.js +93 -2
  42. package/dist/providers/core/config/provider-oauth-configs.js.map +1 -1
  43. package/dist/providers/core/config/service-profiles.js +18 -10
  44. package/dist/providers/core/config/service-profiles.js.map +1 -1
  45. package/dist/providers/core/runtime/base-provider.d.ts +2 -0
  46. package/dist/providers/core/runtime/base-provider.js +135 -15
  47. package/dist/providers/core/runtime/base-provider.js.map +1 -1
  48. package/dist/providers/core/runtime/gemini-cli-http-provider.d.ts +8 -3
  49. package/dist/providers/core/runtime/gemini-cli-http-provider.js +332 -67
  50. package/dist/providers/core/runtime/gemini-cli-http-provider.js.map +1 -1
  51. package/dist/providers/core/runtime/http-request-executor.d.ts +1 -0
  52. package/dist/providers/core/runtime/http-request-executor.js +41 -1
  53. package/dist/providers/core/runtime/http-request-executor.js.map +1 -1
  54. package/dist/providers/core/runtime/http-transport-provider.d.ts +27 -0
  55. package/dist/providers/core/runtime/http-transport-provider.js +342 -69
  56. package/dist/providers/core/runtime/http-transport-provider.js.map +1 -1
  57. package/dist/providers/core/runtime/provider-error-classifier.d.ts +2 -2
  58. package/dist/providers/core/runtime/provider-error-classifier.js +14 -4
  59. package/dist/providers/core/runtime/provider-error-classifier.js.map +1 -1
  60. package/dist/providers/core/runtime/provider-factory.d.ts +1 -0
  61. package/dist/providers/core/runtime/provider-factory.js +37 -8
  62. package/dist/providers/core/runtime/provider-factory.js.map +1 -1
  63. package/dist/providers/core/runtime/responses-provider.d.ts +3 -3
  64. package/dist/providers/core/runtime/responses-provider.js +56 -117
  65. package/dist/providers/core/runtime/responses-provider.js.map +1 -1
  66. package/dist/providers/core/runtime/vision-debug-utils.d.ts +13 -0
  67. package/dist/providers/core/runtime/vision-debug-utils.js +114 -0
  68. package/dist/providers/core/runtime/vision-debug-utils.js.map +1 -0
  69. package/dist/providers/core/strategies/oauth-auth-code-flow.js +82 -25
  70. package/dist/providers/core/strategies/oauth-auth-code-flow.js.map +1 -1
  71. package/dist/providers/core/utils/http-client.d.ts +5 -0
  72. package/dist/providers/core/utils/http-client.js +31 -4
  73. package/dist/providers/core/utils/http-client.js.map +1 -1
  74. package/dist/providers/core/utils/provider-error-reporter.js +8 -2
  75. package/dist/providers/core/utils/provider-error-reporter.js.map +1 -1
  76. package/dist/providers/core/utils/snapshot-writer.d.ts +1 -1
  77. package/dist/providers/core/utils/snapshot-writer.js +5 -1
  78. package/dist/providers/core/utils/snapshot-writer.js.map +1 -1
  79. package/dist/providers/profile/provider-profile-loader.js +8 -4
  80. package/dist/providers/profile/provider-profile-loader.js.map +1 -1
  81. package/dist/runtime/runtime-flags.d.ts +4 -0
  82. package/dist/runtime/runtime-flags.js +32 -0
  83. package/dist/runtime/runtime-flags.js.map +1 -0
  84. package/dist/server/handlers/handler-utils.js +29 -2
  85. package/dist/server/handlers/handler-utils.js.map +1 -1
  86. package/dist/server/handlers/messages-handler.js +27 -26
  87. package/dist/server/handlers/messages-handler.js.map +1 -1
  88. package/dist/server/handlers/responses-handler.js +35 -1
  89. package/dist/server/handlers/responses-handler.js.map +1 -1
  90. package/dist/server/handlers/sse-dispatcher.js +22 -2
  91. package/dist/server/handlers/sse-dispatcher.js.map +1 -1
  92. package/dist/server/runtime/http-server/index.d.ts +10 -0
  93. package/dist/server/runtime/http-server/index.js +551 -148
  94. package/dist/server/runtime/http-server/index.js.map +1 -1
  95. package/dist/server/runtime/http-server/request-executor.d.ts +14 -0
  96. package/dist/server/runtime/http-server/request-executor.js +638 -149
  97. package/dist/server/runtime/http-server/request-executor.js.map +1 -1
  98. package/dist/server/runtime/http-server/routes.d.ts +5 -0
  99. package/dist/server/runtime/http-server/routes.js +69 -0
  100. package/dist/server/runtime/http-server/routes.js.map +1 -1
  101. package/dist/server/runtime/http-server/runtime-manager.js +18 -0
  102. package/dist/server/runtime/http-server/runtime-manager.js.map +1 -1
  103. package/dist/server/utils/sse-request-parser.d.ts +1 -0
  104. package/dist/server/utils/sse-request-parser.js +17 -6
  105. package/dist/server/utils/sse-request-parser.js.map +1 -1
  106. package/dist/server/utils/utf8-chunk-buffer.d.ts +43 -0
  107. package/dist/server/utils/utf8-chunk-buffer.js +132 -0
  108. package/dist/server/utils/utf8-chunk-buffer.js.map +1 -0
  109. package/dist/server/utils/warmup-detector.d.ts +7 -0
  110. package/dist/server/utils/warmup-detector.js +125 -0
  111. package/dist/server/utils/warmup-detector.js.map +1 -0
  112. package/dist/server/utils/warmup-storm-tracker.d.ts +9 -0
  113. package/dist/server/utils/warmup-storm-tracker.js +61 -0
  114. package/dist/server/utils/warmup-storm-tracker.js.map +1 -0
  115. package/dist/token-daemon/index.d.ts +7 -0
  116. package/dist/token-daemon/index.js +242 -0
  117. package/dist/token-daemon/index.js.map +1 -0
  118. package/dist/token-daemon/server-utils.d.ts +33 -0
  119. package/dist/token-daemon/server-utils.js +155 -0
  120. package/dist/token-daemon/server-utils.js.map +1 -0
  121. package/dist/token-daemon/token-daemon.d.ts +20 -0
  122. package/dist/token-daemon/token-daemon.js +144 -0
  123. package/dist/token-daemon/token-daemon.js.map +1 -0
  124. package/dist/token-daemon/token-types.d.ts +44 -0
  125. package/dist/token-daemon/token-types.js +18 -0
  126. package/dist/token-daemon/token-types.js.map +1 -0
  127. package/dist/token-daemon/token-utils.d.ts +17 -0
  128. package/dist/token-daemon/token-utils.js +153 -0
  129. package/dist/token-daemon/token-utils.js.map +1 -0
  130. package/dist/tools/semantic-replay.js +7 -6
  131. package/dist/tools/semantic-replay.js.map +1 -1
  132. package/dist/utils/debug-utils.js +14 -0
  133. package/dist/utils/debug-utils.js.map +1 -1
  134. package/dist/utils/error-handler-registry.d.ts +36 -0
  135. package/dist/utils/error-handler-registry.js +99 -12
  136. package/dist/utils/error-handler-registry.js.map +1 -1
  137. package/dist/utils/error-handling-utils.js +4 -3
  138. package/dist/utils/error-handling-utils.js.map +1 -1
  139. package/dist/utils/log-helpers.d.ts +6 -0
  140. package/dist/utils/log-helpers.js +90 -0
  141. package/dist/utils/log-helpers.js.map +1 -0
  142. package/dist/utils/logger.d.ts +8 -0
  143. package/dist/utils/logger.js +55 -2
  144. package/dist/utils/logger.js.map +1 -1
  145. package/dist/utils/snapshot-writer.js +2 -6
  146. package/dist/utils/snapshot-writer.js.map +1 -1
  147. package/node_modules/@jsonstudio/llms/README.md +2 -0
  148. package/node_modules/@jsonstudio/llms/dist/conversion/codecs/gemini-openai-codec.js +152 -6
  149. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/auto-thinking.d.ts +6 -0
  150. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/auto-thinking.js +25 -0
  151. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/field-mapping.d.ts +14 -0
  152. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/field-mapping.js +155 -0
  153. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/gemini-web-search.d.ts +17 -0
  154. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/gemini-web-search.js +68 -0
  155. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/glm-image-content.d.ts +2 -0
  156. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/glm-image-content.js +83 -0
  157. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/glm-tool-extraction.d.ts +2 -0
  158. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/glm-tool-extraction.js +264 -0
  159. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/glm-vision-prompt.d.ts +11 -0
  160. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/glm-vision-prompt.js +177 -0
  161. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/glm-web-search.d.ts +2 -0
  162. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/glm-web-search.js +63 -0
  163. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/qwen-transform.d.ts +3 -0
  164. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/qwen-transform.js +209 -0
  165. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/request-rules.d.ts +24 -0
  166. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/request-rules.js +63 -0
  167. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/response-blacklist.d.ts +14 -0
  168. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/response-blacklist.js +85 -0
  169. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/response-normalize.d.ts +5 -0
  170. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/response-normalize.js +121 -0
  171. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/response-validate.d.ts +5 -0
  172. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/response-validate.js +76 -0
  173. package/{dist/providers/compat/utils/snapshot-writer.d.ts → node_modules/@jsonstudio/llms/dist/conversion/compat/actions/snapshot.d.ts} +2 -2
  174. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/snapshot.js +21 -0
  175. package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/tool-schema.d.ts +6 -0
  176. package/{dist/providers/compat/glm/utils/tool-schema-helpers.js → node_modules/@jsonstudio/llms/dist/conversion/compat/actions/tool-schema.js} +6 -1
  177. package/{dist/providers/compat/filters → node_modules/@jsonstudio/llms/dist/conversion/compat/actions}/universal-shape-filter.d.ts +17 -22
  178. package/{dist/providers/compat/filters → node_modules/@jsonstudio/llms/dist/conversion/compat/actions}/universal-shape-filter.js +46 -99
  179. package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/chat-gemini.json +17 -0
  180. package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/chat-glm.json +196 -13
  181. package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/chat-iflow.json +194 -26
  182. package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/chat-lmstudio.json +43 -35
  183. package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/chat-qwen.json +20 -16
  184. package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/responses-c4m.json +42 -42
  185. package/node_modules/@jsonstudio/llms/dist/conversion/config/sample-config.json +1 -1
  186. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/compat/compat-engine.d.ts +7 -2
  187. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/compat/compat-engine.js +5 -665
  188. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/compat/compat-pipeline-executor.d.ts +9 -0
  189. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/compat/compat-pipeline-executor.js +869 -0
  190. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/compat/compat-types.d.ts +55 -0
  191. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/hub-pipeline.d.ts +2 -0
  192. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/hub-pipeline.js +74 -5
  193. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage3_compat/index.js +2 -2
  194. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/target-utils.js +9 -0
  195. package/node_modules/@jsonstudio/llms/dist/conversion/hub/process/chat-process.js +213 -1
  196. package/node_modules/@jsonstudio/llms/dist/conversion/hub/response/provider-response.d.ts +34 -0
  197. package/node_modules/@jsonstudio/llms/dist/conversion/hub/response/provider-response.js +84 -24
  198. package/node_modules/@jsonstudio/llms/dist/conversion/hub/response/response-runtime.js +19 -2
  199. package/node_modules/@jsonstudio/llms/dist/conversion/hub/response/server-side-tools.d.ts +26 -0
  200. package/node_modules/@jsonstudio/llms/dist/conversion/hub/response/server-side-tools.js +383 -0
  201. package/node_modules/@jsonstudio/llms/dist/conversion/hub/semantic-mappers/gemini-mapper.js +241 -14
  202. package/node_modules/@jsonstudio/llms/dist/conversion/hub/semantic-mappers/responses-mapper.js +17 -1
  203. package/node_modules/@jsonstudio/llms/dist/conversion/hub/standardized-bridge.js +14 -0
  204. package/node_modules/@jsonstudio/llms/dist/conversion/hub/types/standardized.d.ts +1 -0
  205. package/node_modules/@jsonstudio/llms/dist/conversion/responses/responses-host-policy.d.ts +6 -0
  206. package/node_modules/@jsonstudio/llms/dist/conversion/responses/responses-host-policy.js +14 -0
  207. package/node_modules/@jsonstudio/llms/dist/conversion/responses/responses-openai-bridge.js +133 -5
  208. package/node_modules/@jsonstudio/llms/dist/conversion/shared/anthropic-message-utils.js +98 -3
  209. package/node_modules/@jsonstudio/llms/dist/conversion/shared/bridge-message-utils.js +137 -10
  210. package/node_modules/@jsonstudio/llms/dist/conversion/shared/responses-output-builder.js +43 -2
  211. package/node_modules/@jsonstudio/llms/dist/conversion/shared/responses-reasoning-registry.d.ts +4 -0
  212. package/node_modules/@jsonstudio/llms/dist/conversion/shared/responses-reasoning-registry.js +62 -1
  213. package/node_modules/@jsonstudio/llms/dist/conversion/shared/responses-response-utils.js +23 -1
  214. package/node_modules/@jsonstudio/llms/dist/conversion/shared/snapshot-utils.js +17 -47
  215. package/node_modules/@jsonstudio/llms/dist/conversion/shared/tool-canonicalizer.d.ts +2 -0
  216. package/node_modules/@jsonstudio/llms/dist/conversion/shared/tool-filter-pipeline.js +12 -0
  217. package/node_modules/@jsonstudio/llms/dist/conversion/shared/tool-mapping.js +25 -2
  218. package/node_modules/@jsonstudio/llms/dist/index.d.ts +1 -0
  219. package/node_modules/@jsonstudio/llms/dist/index.js +1 -0
  220. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/bootstrap.js +540 -36
  221. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/classifier.js +12 -11
  222. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/context-advisor.d.ts +19 -0
  223. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/context-advisor.js +64 -0
  224. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/engine.d.ts +26 -0
  225. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/engine.js +450 -54
  226. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/features.js +23 -458
  227. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/health-manager.js +2 -7
  228. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/message-utils.d.ts +7 -0
  229. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/message-utils.js +78 -0
  230. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/provider-registry.js +7 -2
  231. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/token-counter.js +14 -3
  232. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/token-estimator.d.ts +2 -0
  233. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/token-estimator.js +16 -0
  234. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/token-file-scanner.d.ts +15 -0
  235. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/token-file-scanner.js +56 -0
  236. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/tool-signals.d.ts +13 -0
  237. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/tool-signals.js +403 -0
  238. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/types.d.ts +86 -2
  239. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/types.js +3 -1
  240. package/node_modules/@jsonstudio/llms/dist/servertool/engine.d.ts +27 -0
  241. package/node_modules/@jsonstudio/llms/dist/servertool/engine.js +60 -0
  242. package/node_modules/@jsonstudio/llms/dist/servertool/flow-types.d.ts +40 -0
  243. package/node_modules/@jsonstudio/llms/dist/servertool/flow-types.js +1 -0
  244. package/node_modules/@jsonstudio/llms/dist/servertool/handlers/vision.d.ts +1 -0
  245. package/node_modules/@jsonstudio/llms/dist/servertool/handlers/vision.js +194 -0
  246. package/node_modules/@jsonstudio/llms/dist/servertool/handlers/web-search.d.ts +1 -0
  247. package/node_modules/@jsonstudio/llms/dist/servertool/handlers/web-search.js +638 -0
  248. package/node_modules/@jsonstudio/llms/dist/servertool/orchestration-types.d.ts +33 -0
  249. package/node_modules/@jsonstudio/llms/dist/servertool/orchestration-types.js +1 -0
  250. package/node_modules/@jsonstudio/llms/dist/servertool/registry.d.ts +18 -0
  251. package/node_modules/@jsonstudio/llms/dist/servertool/registry.js +27 -0
  252. package/node_modules/@jsonstudio/llms/dist/servertool/server-side-tools.d.ts +8 -0
  253. package/node_modules/@jsonstudio/llms/dist/servertool/server-side-tools.js +208 -0
  254. package/node_modules/@jsonstudio/llms/dist/servertool/types.d.ts +88 -0
  255. package/node_modules/@jsonstudio/llms/dist/servertool/types.js +1 -0
  256. package/node_modules/@jsonstudio/llms/dist/servertool/vision-tool.d.ts +2 -0
  257. package/node_modules/@jsonstudio/llms/dist/servertool/vision-tool.js +185 -0
  258. package/node_modules/@jsonstudio/llms/dist/sse/json-to-sse/event-generators/responses.js +15 -3
  259. package/node_modules/@jsonstudio/llms/dist/sse/sse-to-json/builders/response-builder.js +6 -3
  260. package/node_modules/@jsonstudio/llms/dist/sse/sse-to-json/gemini-sse-to-json-converter.js +27 -1
  261. package/node_modules/@jsonstudio/llms/dist/sse/types/gemini-types.d.ts +20 -1
  262. package/node_modules/@jsonstudio/llms/dist/sse/types/responses-types.js +1 -1
  263. package/node_modules/@jsonstudio/llms/dist/telemetry/stats-center.d.ts +73 -0
  264. package/node_modules/@jsonstudio/llms/dist/telemetry/stats-center.js +280 -0
  265. package/node_modules/@jsonstudio/llms/package.json +2 -2
  266. package/package.json +11 -10
  267. package/scripts/README.md +26 -12
  268. package/scripts/auth-antigravity-token.mjs +64 -0
  269. package/scripts/auth-gemini-cli-token.mjs +96 -0
  270. package/scripts/auth-iflow-manual.mjs +81 -0
  271. package/scripts/auth-iflow-token-direct.mjs +87 -0
  272. package/scripts/auth-iflow-token.mjs +77 -0
  273. package/scripts/copy-compat-assets.mjs +3 -15
  274. package/scripts/install-verify.mjs +1 -0
  275. package/scripts/pack-mode.mjs +2 -1
  276. package/scripts/publish-rcc.mjs +20 -4
  277. package/scripts/replay-codex-sample.mjs +13 -8
  278. package/scripts/tests/chat-pipeline-blackbox.mjs +1 -1
  279. package/scripts/tests/virtual-router-health.mjs +141 -6
  280. package/scripts/tools/capture-provider-goldens.mjs +8 -7
  281. package/scripts/verify-client-headers.mjs +224 -0
  282. package/dist/providers/compat/base-compatibility.d.ts +0 -27
  283. package/dist/providers/compat/base-compatibility.js +0 -143
  284. package/dist/providers/compat/base-compatibility.js.map +0 -1
  285. package/dist/providers/compat/compat-directory-loader.d.ts +0 -4
  286. package/dist/providers/compat/compat-directory-loader.js +0 -85
  287. package/dist/providers/compat/compat-directory-loader.js.map +0 -1
  288. package/dist/providers/compat/compatibility-adapter.d.ts +0 -18
  289. package/dist/providers/compat/compatibility-adapter.js +0 -104
  290. package/dist/providers/compat/compatibility-adapter.js.map +0 -1
  291. package/dist/providers/compat/compatibility-factory.d.ts +0 -57
  292. package/dist/providers/compat/compatibility-factory.js +0 -155
  293. package/dist/providers/compat/compatibility-factory.js.map +0 -1
  294. package/dist/providers/compat/compatibility-interface.d.ts +0 -35
  295. package/dist/providers/compat/compatibility-interface.js +0 -2
  296. package/dist/providers/compat/compatibility-interface.js.map +0 -1
  297. package/dist/providers/compat/compatibility-manager.d.ts +0 -85
  298. package/dist/providers/compat/compatibility-manager.js +0 -368
  299. package/dist/providers/compat/compatibility-manager.js.map +0 -1
  300. package/dist/providers/compat/config/config-compatibility.d.ts +0 -28
  301. package/dist/providers/compat/config/config-compatibility.js +0 -95
  302. package/dist/providers/compat/config/config-compatibility.js.map +0 -1
  303. package/dist/providers/compat/field-mapping.d.ts +0 -102
  304. package/dist/providers/compat/field-mapping.js +0 -447
  305. package/dist/providers/compat/field-mapping.js.map +0 -1
  306. package/dist/providers/compat/filters/blacklist-sanitizer.d.ts +0 -45
  307. package/dist/providers/compat/filters/blacklist-sanitizer.js +0 -133
  308. package/dist/providers/compat/filters/blacklist-sanitizer.js.map +0 -1
  309. package/dist/providers/compat/filters/response-blacklist-sanitizer.d.ts +0 -28
  310. package/dist/providers/compat/filters/response-blacklist-sanitizer.js +0 -138
  311. package/dist/providers/compat/filters/response-blacklist-sanitizer.js.map +0 -1
  312. package/dist/providers/compat/filters/universal-shape-filter.js.map +0 -1
  313. package/dist/providers/compat/glm/config/blacklist-rules.json +0 -22
  314. package/dist/providers/compat/glm/config/field-mappings.json +0 -92
  315. package/dist/providers/compat/glm/config/response-blacklist.json +0 -7
  316. package/dist/providers/compat/glm/config/shape-filters.json +0 -37
  317. package/dist/providers/compat/glm/field-mapping/field-mapping-processor.d.ts +0 -28
  318. package/dist/providers/compat/glm/field-mapping/field-mapping-processor.js +0 -306
  319. package/dist/providers/compat/glm/field-mapping/field-mapping-processor.js.map +0 -1
  320. package/dist/providers/compat/glm/functions/glm-processor.d.ts +0 -50
  321. package/dist/providers/compat/glm/functions/glm-processor.js +0 -134
  322. package/dist/providers/compat/glm/functions/glm-processor.js.map +0 -1
  323. package/dist/providers/compat/glm/glm-compatibility.d.ts +0 -34
  324. package/dist/providers/compat/glm/glm-compatibility.js +0 -117
  325. package/dist/providers/compat/glm/glm-compatibility.js.map +0 -1
  326. package/dist/providers/compat/glm/hooks/base-hook.d.ts +0 -21
  327. package/dist/providers/compat/glm/hooks/base-hook.js +0 -53
  328. package/dist/providers/compat/glm/hooks/base-hook.js.map +0 -1
  329. package/dist/providers/compat/glm/hooks/glm-request-validation-hook.d.ts +0 -24
  330. package/dist/providers/compat/glm/hooks/glm-request-validation-hook.js +0 -268
  331. package/dist/providers/compat/glm/hooks/glm-request-validation-hook.js.map +0 -1
  332. package/dist/providers/compat/glm/hooks/glm-response-normalization-hook.d.ts +0 -21
  333. package/dist/providers/compat/glm/hooks/glm-response-normalization-hook.js +0 -171
  334. package/dist/providers/compat/glm/hooks/glm-response-normalization-hook.js.map +0 -1
  335. package/dist/providers/compat/glm/hooks/glm-response-validation-hook.d.ts +0 -25
  336. package/dist/providers/compat/glm/hooks/glm-response-validation-hook.js +0 -236
  337. package/dist/providers/compat/glm/hooks/glm-response-validation-hook.js.map +0 -1
  338. package/dist/providers/compat/glm/hooks/glm-tool-cleaning-hook.d.ts +0 -26
  339. package/dist/providers/compat/glm/hooks/glm-tool-cleaning-hook.js +0 -186
  340. package/dist/providers/compat/glm/hooks/glm-tool-cleaning-hook.js.map +0 -1
  341. package/dist/providers/compat/glm/index.d.ts +0 -24
  342. package/dist/providers/compat/glm/index.js +0 -29
  343. package/dist/providers/compat/glm/index.js.map +0 -1
  344. package/dist/providers/compat/glm/utils/tool-schema-helpers.d.ts +0 -3
  345. package/dist/providers/compat/glm/utils/tool-schema-helpers.js.map +0 -1
  346. package/dist/providers/compat/iflow/config/field-mappings.json +0 -92
  347. package/dist/providers/compat/iflow/config/shape-filters.json +0 -37
  348. package/dist/providers/compat/iflow/field-mapping/iflow-field-mapping-processor.d.ts +0 -34
  349. package/dist/providers/compat/iflow/field-mapping/iflow-field-mapping-processor.js +0 -386
  350. package/dist/providers/compat/iflow/field-mapping/iflow-field-mapping-processor.js.map +0 -1
  351. package/dist/providers/compat/iflow/functions/iflow-processor.d.ts +0 -53
  352. package/dist/providers/compat/iflow/functions/iflow-processor.js +0 -215
  353. package/dist/providers/compat/iflow/functions/iflow-processor.js.map +0 -1
  354. package/dist/providers/compat/iflow/hooks/base-hook.d.ts +0 -23
  355. package/dist/providers/compat/iflow/hooks/base-hook.js +0 -59
  356. package/dist/providers/compat/iflow/hooks/base-hook.js.map +0 -1
  357. package/dist/providers/compat/iflow/hooks/iflow-request-validation-hook.d.ts +0 -23
  358. package/dist/providers/compat/iflow/hooks/iflow-request-validation-hook.js +0 -279
  359. package/dist/providers/compat/iflow/hooks/iflow-request-validation-hook.js.map +0 -1
  360. package/dist/providers/compat/iflow/hooks/iflow-response-normalization-hook.d.ts +0 -20
  361. package/dist/providers/compat/iflow/hooks/iflow-response-normalization-hook.js +0 -180
  362. package/dist/providers/compat/iflow/hooks/iflow-response-normalization-hook.js.map +0 -1
  363. package/dist/providers/compat/iflow/hooks/iflow-response-validation-hook.d.ts +0 -23
  364. package/dist/providers/compat/iflow/hooks/iflow-response-validation-hook.js +0 -232
  365. package/dist/providers/compat/iflow/hooks/iflow-response-validation-hook.js.map +0 -1
  366. package/dist/providers/compat/iflow/hooks/iflow-tool-cleaning-hook.d.ts +0 -25
  367. package/dist/providers/compat/iflow/hooks/iflow-tool-cleaning-hook.js +0 -216
  368. package/dist/providers/compat/iflow/hooks/iflow-tool-cleaning-hook.js.map +0 -1
  369. package/dist/providers/compat/iflow/iflow-compatibility.d.ts +0 -24
  370. package/dist/providers/compat/iflow/iflow-compatibility.js +0 -94
  371. package/dist/providers/compat/iflow/iflow-compatibility.js.map +0 -1
  372. package/dist/providers/compat/index.d.ts +0 -59
  373. package/dist/providers/compat/index.js +0 -83
  374. package/dist/providers/compat/index.js.map +0 -1
  375. package/dist/providers/compat/lmstudio-compatibility.d.ts +0 -44
  376. package/dist/providers/compat/lmstudio-compatibility.js +0 -193
  377. package/dist/providers/compat/lmstudio-compatibility.js.map +0 -1
  378. package/dist/providers/compat/passthrough-compatibility.d.ts +0 -29
  379. package/dist/providers/compat/passthrough-compatibility.js +0 -83
  380. package/dist/providers/compat/passthrough-compatibility.js.map +0 -1
  381. package/dist/providers/compat/profiles/chat/glm/index.d.ts +0 -6
  382. package/dist/providers/compat/profiles/chat/glm/index.js +0 -6
  383. package/dist/providers/compat/profiles/chat/glm/index.js.map +0 -1
  384. package/dist/providers/compat/profiles/chat/iflow/index.d.ts +0 -6
  385. package/dist/providers/compat/profiles/chat/iflow/index.js +0 -6
  386. package/dist/providers/compat/profiles/chat/iflow/index.js.map +0 -1
  387. package/dist/providers/compat/profiles/chat/lmstudio/index.d.ts +0 -6
  388. package/dist/providers/compat/profiles/chat/lmstudio/index.js +0 -6
  389. package/dist/providers/compat/profiles/chat/lmstudio/index.js.map +0 -1
  390. package/dist/providers/compat/profiles/chat/qwen/index.d.ts +0 -6
  391. package/dist/providers/compat/profiles/chat/qwen/index.js +0 -6
  392. package/dist/providers/compat/profiles/chat/qwen/index.js.map +0 -1
  393. package/dist/providers/compat/profiles/compat/passthrough/index.d.ts +0 -6
  394. package/dist/providers/compat/profiles/compat/passthrough/index.js +0 -6
  395. package/dist/providers/compat/profiles/compat/passthrough/index.js.map +0 -1
  396. package/dist/providers/compat/profiles/responses/c4m/index.d.ts +0 -6
  397. package/dist/providers/compat/profiles/responses/c4m/index.js +0 -6
  398. package/dist/providers/compat/profiles/responses/c4m/index.js.map +0 -1
  399. package/dist/providers/compat/profiles/responses/default/index.d.ts +0 -6
  400. package/dist/providers/compat/profiles/responses/default/index.js +0 -6
  401. package/dist/providers/compat/profiles/responses/default/index.js.map +0 -1
  402. package/dist/providers/compat/profiles/responses/fai/index.d.ts +0 -6
  403. package/dist/providers/compat/profiles/responses/fai/index.js +0 -6
  404. package/dist/providers/compat/profiles/responses/fai/index.js.map +0 -1
  405. package/dist/providers/compat/profiles/responses/fc/index.d.ts +0 -6
  406. package/dist/providers/compat/profiles/responses/fc/index.js +0 -6
  407. package/dist/providers/compat/profiles/responses/fc/index.js.map +0 -1
  408. package/dist/providers/compat/qwen/index.d.ts +0 -4
  409. package/dist/providers/compat/qwen/index.js +0 -6
  410. package/dist/providers/compat/qwen/index.js.map +0 -1
  411. package/dist/providers/compat/qwen-compatibility.d.ts +0 -52
  412. package/dist/providers/compat/qwen-compatibility.js +0 -330
  413. package/dist/providers/compat/qwen-compatibility.js.map +0 -1
  414. package/dist/providers/compat/register-compat-module.d.ts +0 -8
  415. package/dist/providers/compat/register-compat-module.js +0 -53
  416. package/dist/providers/compat/register-compat-module.js.map +0 -1
  417. package/dist/providers/compat/responses/c4m-responses-compatibility.d.ts +0 -27
  418. package/dist/providers/compat/responses/c4m-responses-compatibility.js +0 -197
  419. package/dist/providers/compat/responses/c4m-responses-compatibility.js.map +0 -1
  420. package/dist/providers/compat/standard-compatibility-utils.d.ts +0 -1
  421. package/dist/providers/compat/standard-compatibility-utils.js +0 -77
  422. package/dist/providers/compat/standard-compatibility-utils.js.map +0 -1
  423. package/dist/providers/compat/standard-compatibility.d.ts +0 -31
  424. package/dist/providers/compat/standard-compatibility.js +0 -118
  425. package/dist/providers/compat/standard-compatibility.js.map +0 -1
  426. package/dist/providers/compat/utils/snapshot-writer.js +0 -62
  427. package/dist/providers/compat/utils/snapshot-writer.js.map +0 -1
  428. package/dist/tools/replay-request.d.ts +0 -0
  429. package/dist/tools/replay-request.js +0 -2
  430. package/dist/tools/replay-request.js.map +0 -1
  431. package/scripts/check-glm-compat.mjs +0 -47
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env node
2
+ import os from 'os';
3
+ import path from 'path';
4
+ import fs from 'fs/promises';
5
+ import { createProviderOAuthStrategy } from '../dist/providers/core/config/provider-oauth-configs.js';
6
+
7
+ async function resolveIflowTokenPath() {
8
+ const envFile = process.env.IFLOW_TOKEN_FILE;
9
+ if (envFile && envFile.trim()) {
10
+ const normalized = envFile.startsWith('~') ? envFile.replace(/^~\//, `${os.homedir()}/`) : envFile;
11
+ return { tokenPath: normalized, duplicates: [] };
12
+ }
13
+
14
+ const authDir = path.join(os.homedir(), '.routecodex', 'auth');
15
+ const seq = 1;
16
+ const prefix = `iflow-oauth-${seq}`;
17
+ let entries = [];
18
+ try {
19
+ entries = await fs.readdir(authDir);
20
+ } catch {
21
+ // directory may not exist yet
22
+ }
23
+ const matches = entries
24
+ .filter((entry) => entry.endsWith('.json'))
25
+ .filter((entry) => entry === `${prefix}.json` || entry.startsWith(`${prefix}-`));
26
+ matches.sort();
27
+ if (matches.length > 0) {
28
+ const canonical = path.join(authDir, matches[0]);
29
+ const duplicates = matches.slice(1).map((name) => path.join(authDir, name));
30
+ return { tokenPath: canonical, duplicates };
31
+ }
32
+ const canonical = path.join(authDir, `${prefix}-primary.json`);
33
+ return { tokenPath: canonical, duplicates: [] };
34
+ }
35
+
36
+ async function run() {
37
+ const { tokenPath, duplicates } = await resolveIflowTokenPath();
38
+ console.log(`[iflow-manual] Manual auth for: ${tokenPath}`);
39
+
40
+ // ensure token file exists
41
+ await fs.mkdir(path.dirname(tokenPath), { recursive: true });
42
+ try { await fs.access(tokenPath); } catch { await fs.writeFile(tokenPath, '{}', 'utf-8'); }
43
+
44
+ // Use device code flow but let user open the URL manually
45
+ const strategy = createProviderOAuthStrategy('iflow', {
46
+ flowType: 'device_code',
47
+ endpoints: {
48
+ deviceCodeUrl: 'https://iflow.cn/oauth/device/code',
49
+ tokenUrl: 'https://iflow.cn/oauth/token',
50
+ userInfoUrl: 'https://iflow.cn/api/oauth/getUserInfo'
51
+ },
52
+ client: { clientId: '10009311001', scopes: ['openid','profile','email','api'] }
53
+ }, tokenPath);
54
+
55
+ // Manually trigger device code flow
56
+ const deviceCodeData = await strategy.initiateDeviceCodeFlow();
57
+ console.log('Please open this URL in your browser:');
58
+ console.log(deviceCodeData.verification_uri);
59
+ console.log('User code:', deviceCodeData.user_code);
60
+ console.log('Press Enter when you have authorized...');
61
+
62
+ await new Promise(resolve => process.stdin.once('data', resolve));
63
+
64
+ const token = await strategy.pollForToken(deviceCodeData);
65
+ await strategy.saveToken(token);
66
+
67
+ // clean up duplicate token files for the same sequence
68
+ for (const dup of duplicates) {
69
+ if (dup === tokenPath) continue;
70
+ try {
71
+ await fs.unlink(dup);
72
+ console.log(`[iflow-manual] Removed duplicate token file: ${dup}`);
73
+ } catch {
74
+ // ignore
75
+ }
76
+ }
77
+
78
+ console.log(`[iflow-manual] Token saved to: ${tokenPath}`);
79
+ }
80
+
81
+ run().catch(err => { console.error('[iflow-manual] Error:', err); process.exit(1); });
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env node
2
+ // iFlow token auth using direct device flow - no browser redirect
3
+ // Usage: ILOW_TOKEN_FILE="~/.routecodex/auth/iflow-oauth-1-xxx.json" node scripts/auth-iflow-token-direct.mjs
4
+
5
+ import os from 'os';
6
+ import path from 'path';
7
+ import fs from 'fs/promises';
8
+
9
+ async function resolveIflowTokenPath() {
10
+ const envFile = process.env.IFLOW_TOKEN_FILE;
11
+ if (envFile && envFile.trim()) {
12
+ const normalized = envFile.startsWith('~') ? envFile.replace(/^~\//, `${os.homedir()}/`) : envFile;
13
+ return { tokenPath: normalized, duplicates: [] };
14
+ }
15
+
16
+ const authDir = path.join(os.homedir(), '.routecodex', 'auth');
17
+ const seq = 1;
18
+ const prefix = `iflow-oauth-${seq}`;
19
+ let entries = [];
20
+ try {
21
+ entries = await fs.readdir(authDir);
22
+ } catch {
23
+ // directory may not exist yet
24
+ }
25
+ const matches = entries
26
+ .filter((entry) => entry.endsWith('.json'))
27
+ .filter((entry) => entry === `${prefix}.json` || entry.startsWith(`${prefix}-`));
28
+ matches.sort();
29
+ if (matches.length > 0) {
30
+ const canonical = path.join(authDir, matches[0]);
31
+ const duplicates = matches.slice(1).map((name) => path.join(authDir, name));
32
+ return { tokenPath: canonical, duplicates };
33
+ }
34
+ const canonical = path.join(authDir, `${prefix}-primary.json`);
35
+ return { tokenPath: canonical, duplicates: [] };
36
+ }
37
+
38
+ async function run() {
39
+ const { tokenPath, duplicates } = await resolveIflowTokenPath();
40
+ console.log(`[iflow-auth-direct] Starting device flow for: ${tokenPath}`);
41
+
42
+ // ensure token file exists so re-auth can recreate after delete
43
+ await fs.mkdir(path.dirname(tokenPath), { recursive: true });
44
+ try {
45
+ await fs.access(tokenPath);
46
+ } catch {
47
+ await fs.writeFile(tokenPath, '{}', 'utf-8');
48
+ }
49
+
50
+ const { createProviderOAuthStrategy } = await import('../dist/providers/core/config/provider-oauth-configs.js');
51
+
52
+ // Use device code flow instead of auth code flow
53
+ const strategy = createProviderOAuthStrategy('iflow', {
54
+ flowType: 'device_code',
55
+ endpoints: {
56
+ deviceCodeUrl: 'https://iflow.cn/oauth/device/code',
57
+ tokenUrl: 'https://iflow.cn/oauth/token',
58
+ userInfoUrl: 'https://iflow.cn/api/oauth/getUserInfo'
59
+ },
60
+ client: {
61
+ clientId: process.env.IFLOW_CLIENT_ID || 'iflow-desktop-client',
62
+ scopes: ['openid','profile','email','api']
63
+ }
64
+ }, tokenPath);
65
+
66
+ console.log('[iflow-auth-direct] Opening browser for device code flow...');
67
+ const token = await strategy.authenticate({ openBrowser: true });
68
+ await strategy.saveToken(token);
69
+
70
+ // clean up duplicate token files for the same sequence
71
+ for (const dup of duplicates) {
72
+ if (dup === tokenPath) continue;
73
+ try {
74
+ await fs.unlink(dup);
75
+ console.log(`[iflow-auth-direct] Removed duplicate token file: ${dup}`);
76
+ } catch {
77
+ // ignore
78
+ }
79
+ }
80
+
81
+ console.log(`[iflow-auth-direct] Token saved to: ${tokenPath}`);
82
+ }
83
+
84
+ run().catch(err => {
85
+ console.error('[iflow-auth-direct] Error:', err);
86
+ process.exit(1);
87
+ });
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env node
2
+ // iFlow token authentication script for specific token file
3
+ // Usage: ILOW_TOKEN_FILE="~/.routecodex/auth/iflow-oauth-1-xxx.json" node scripts/auth-iflow-token.mjs
4
+
5
+ import os from 'os';
6
+ import path from 'path';
7
+ import fs from 'fs/promises';
8
+
9
+ async function resolveIflowTokenPath() {
10
+ const envFile = process.env.IFLOW_TOKEN_FILE;
11
+ if (envFile && envFile.trim()) {
12
+ const normalized = envFile.startsWith('~') ? envFile.replace(/^~\//, `${os.homedir()}/`) : envFile;
13
+ return { tokenPath: normalized, duplicates: [] };
14
+ }
15
+
16
+ const authDir = path.join(os.homedir(), '.routecodex', 'auth');
17
+ const seq = 1;
18
+ const prefix = `iflow-oauth-${seq}`;
19
+ let entries = [];
20
+ try {
21
+ entries = await fs.readdir(authDir);
22
+ } catch {
23
+ // directory may not exist yet
24
+ }
25
+ const matches = entries
26
+ .filter((entry) => entry.endsWith('.json'))
27
+ .filter((entry) => entry === `${prefix}.json` || entry.startsWith(`${prefix}-`));
28
+ matches.sort();
29
+ if (matches.length > 0) {
30
+ const canonical = path.join(authDir, matches[0]);
31
+ const duplicates = matches.slice(1).map((name) => path.join(authDir, name));
32
+ return { tokenPath: canonical, duplicates };
33
+ }
34
+ const canonical = path.join(authDir, `${prefix}-primary.json`);
35
+ return { tokenPath: canonical, duplicates: [] };
36
+ }
37
+
38
+ async function run() {
39
+ const { tokenPath, duplicates } = await resolveIflowTokenPath();
40
+ console.log(`[iflow-auth] Authenticating token: ${tokenPath}`);
41
+
42
+ // ensure token file exists so re-auth can recreate after delete
43
+ await fs.mkdir(path.dirname(tokenPath), { recursive: true });
44
+ try {
45
+ await fs.access(tokenPath);
46
+ } catch {
47
+ await fs.writeFile(tokenPath, '{}', 'utf-8');
48
+ }
49
+
50
+ const { ensureValidOAuthToken } = await import('../dist/providers/auth/oauth-lifecycle.js');
51
+
52
+ await ensureValidOAuthToken('iflow', {
53
+ type: 'iflow-oauth',
54
+ tokenFile: tokenPath
55
+ }, {
56
+ forceReauthorize: true,
57
+ openBrowser: true
58
+ });
59
+
60
+ // clean up duplicate token files for the same sequence
61
+ for (const dup of duplicates) {
62
+ if (dup === tokenPath) continue;
63
+ try {
64
+ await fs.unlink(dup);
65
+ console.log(`[iflow-auth] Removed duplicate token file: ${dup}`);
66
+ } catch {
67
+ // ignore
68
+ }
69
+ }
70
+
71
+ console.log(`[iflow-auth] Token saved to: ${tokenPath}`);
72
+ }
73
+
74
+ run().catch(err => {
75
+ console.error('[iflow-auth] Error:', err);
76
+ process.exit(1);
77
+ });
@@ -15,23 +15,11 @@ async function ensureDir(p) {
15
15
  }
16
16
 
17
17
  async function main() {
18
- const SRC = path.resolve(process.cwd(), 'src/providers/compat');
19
- const DIST = path.resolve(process.cwd(), 'dist/providers/compat');
20
18
  const PROMPT_SRC = path.resolve(process.cwd(), 'src/config/system-prompts');
21
19
  const PROMPT_DIST = path.resolve(process.cwd(), 'dist/config/system-prompts');
22
- const copied = [];
23
20
  const promptCopied = [];
24
21
  try {
25
- for await (const file of walk(SRC)) {
26
- if (file.endsWith('.json') && file.includes(`${path.sep}config${path.sep}`)) {
27
- const rel = path.relative(SRC, file);
28
- const dest = path.join(DIST, rel);
29
- await ensureDir(path.dirname(dest));
30
- await fs.copyFile(file, dest);
31
- copied.push(rel);
32
- }
33
- }
34
- // copy system prompt artifacts
22
+ // copy system prompt artifacts only; provider compat assets are owned by llmswitch-core
35
23
  try {
36
24
  for await (const file of walk(PROMPT_SRC)) {
37
25
  const stats = await fs.stat(file);
@@ -46,8 +34,8 @@ async function main() {
46
34
  } catch (promptErr) {
47
35
  if (promptErr && promptErr.code !== 'ENOENT') throw promptErr;
48
36
  }
49
- // 不再复制 pipeline-config.generated.json dist;统一从 ~/.routecodex/config/generated 读取
50
- console.log(`[copy-compat-assets] copied ${copied.length} JSON assets; prompts: ${promptCopied.length}`);
37
+ // 不再复制 provider compat 资产;兼容层由 sharedmodule/llmswitch-core 提供
38
+ console.log(`[copy-compat-assets] prompts copied: ${promptCopied.length}`);
51
39
  } catch (err) {
52
40
  console.error('[copy-compat-assets] failed:', err?.message || String(err));
53
41
  process.exit(1);
@@ -1027,6 +1027,7 @@ async function main() {
1027
1027
  messages: [...chatMessages, assistantMsg, toolMsg],
1028
1028
  tools: chatTools,
1029
1029
  stream: false,
1030
+ tool_choice: 'auto'
1030
1031
  };
1031
1032
 
1032
1033
  console.log('📨 提交工具输出...');
@@ -59,11 +59,12 @@ try {
59
59
  if (args.name === 'routecodex' || args.name === 'rcc') {
60
60
  mutated.bundledDependencies = [];
61
61
  mutated.bundleDependencies = [];
62
+ const llmsVersion = original.dependencies?.['@jsonstudio/llms'] || '^0.6.230';
62
63
  mutated.dependencies = {
63
64
  ...(original.dependencies || {}),
64
65
  "ajv": original.dependencies?.ajv || "^8.17.1",
65
66
  "zod": original.dependencies?.zod || "^3.23.8",
66
- "@jsonstudio/llms": original.dependencies?.["@jsonstudio/llms"] || "^0.4.3"
67
+ "@jsonstudio/llms": llmsVersion
67
68
  };
68
69
  }
69
70
  fs.writeFileSync(pkgPath, JSON.stringify(mutated, null, 2));
@@ -7,10 +7,7 @@ import { fileURLToPath } from 'node:url';
7
7
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
8
8
  const PROJECT_ROOT = path.resolve(__dirname, '..');
9
9
  const PACK_SCRIPT = path.join(PROJECT_ROOT, 'scripts', 'pack-mode.mjs');
10
- const packageJson = JSON.parse(fs.readFileSync(path.join(PROJECT_ROOT, 'package.json'), 'utf-8'));
11
- const version = packageJson.version;
12
- const tarballName = `jsonstudio-rcc-${version}.tgz`;
13
- const tarballPath = path.join(PROJECT_ROOT, tarballName);
10
+ const pkgPath = path.join(PROJECT_ROOT, 'package.json');
14
11
 
15
12
  function run(command, args, options = {}) {
16
13
  const res = spawnSync(command, args, { stdio: 'inherit', ...options });
@@ -20,11 +17,30 @@ function run(command, args, options = {}) {
20
17
  }
21
18
 
22
19
  try {
20
+ // 1) 使用 release 模式构建 dist(依赖 npm 上的 @jsonstudio/llms)
21
+ run('npm', ['run', 'build:min'], {
22
+ cwd: PROJECT_ROOT,
23
+ env: { ...process.env, BUILD_MODE: 'release' }
24
+ });
25
+
26
+ // 2) 通过 pack-mode 生成 rcc tarball(内部会临时切换 package.json.name/bin 并确保 llms 为 release 包)
23
27
  run(process.execPath, [PACK_SCRIPT, '--name', '@jsonstudio/rcc', '--bin', 'rcc'], { cwd: PROJECT_ROOT });
28
+
29
+ // 构建过程中版本号可能被 bump(gen-build-info 会 auto-bump),因此需要在 pack 之后重新读取版本号
30
+ const updatedPkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
31
+ const version = updatedPkg.version;
32
+ const tarballName = `jsonstudio-rcc-${version}.tgz`;
33
+ const tarballPath = path.join(PROJECT_ROOT, tarballName);
34
+
24
35
  if (!fs.existsSync(tarballPath)) {
25
36
  throw new Error(`tarball not found: ${tarballPath}`);
26
37
  }
38
+
39
+ // 3) 发布 npm 包
27
40
  run('npm', ['publish', tarballName], { cwd: PROJECT_ROOT });
41
+
42
+ // 4) pack-mode 会在内部检测 dev 链接并调用 ensure-llmswitch-mode 恢复 dev 模式,
43
+ // 因此此处不再额外修改 BUILD_MODE 或重新 link。后续本地如需 dev build,可单独运行 `npm run build:dev`。
28
44
  } catch (err) {
29
45
  console.error('[publish-rcc] failed:', err.message);
30
46
  process.exit(1);
@@ -39,21 +39,26 @@ function readJson(file) {
39
39
  }
40
40
 
41
41
  function extractEndpoint(doc) {
42
- return doc?.data?.url || doc?.endpoint || '/v1/responses';
42
+ return doc?.data?.url || doc?.url || doc?.endpoint || '/v1/responses';
43
43
  }
44
44
 
45
45
  function extractBody(doc) {
46
- const body = doc?.data?.body;
47
- if (!body) return undefined;
48
- if (typeof body.body === 'object') return body.body;
49
- if (typeof body === 'object') return body;
50
- if (typeof doc.data.data === 'object') return doc.data.data;
46
+ const bodyNode = doc?.data?.body || doc?.body;
47
+ if (!bodyNode) {
48
+ if (typeof doc?.data?.data === 'object') return doc.data.data;
49
+ if (typeof doc?.body?.data === 'object') return doc.body.data;
50
+ return undefined;
51
+ }
52
+ if (typeof bodyNode.body === 'object') return bodyNode.body;
53
+ if (typeof bodyNode === 'object') return bodyNode;
54
+ if (typeof doc?.data?.data === 'object') return doc.data.data;
55
+ if (typeof doc?.body?.data === 'object') return doc.body.data;
51
56
  return undefined;
52
57
  }
53
58
 
54
59
  function detectStream(doc, requestBody) {
55
- if (doc?.data?.meta?.stream === true) return true;
56
- if (doc?.data?.body?.metadata?.stream === true) return true;
60
+ if (doc?.data?.meta?.stream === true || doc?.meta?.stream === true) return true;
61
+ if (doc?.data?.body?.metadata?.stream === true || doc?.body?.metadata?.stream === true) return true;
57
62
  if (requestBody?.stream === true) return true;
58
63
  return false;
59
64
  }
@@ -191,7 +191,7 @@ function resolveGoldenExpectations(sample) {
191
191
  if (sample.meta?.endpoint && sample.meta?.requestId) {
192
192
  const reqId = sample.meta.requestId;
193
193
  const endpoint = sample.meta.endpoint;
194
- const baseDir = path.join(os.homedir(), '.routecodex', 'golden_samples');
194
+ const baseDir = path.join(os.homedir(), '.routecodex', 'codex-samples');
195
195
  const folder = endpoint.includes('/messages')
196
196
  ? 'anthropic-messages'
197
197
  : endpoint.includes('/responses')
@@ -13,7 +13,7 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
13
13
 
14
14
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
15
15
  const ROOT = path.resolve(__dirname, '../..');
16
- const CORE_DIST = path.join(ROOT, 'sharedmodule', 'llmswitch-core', 'dist', 'v2', 'router', 'virtual-router');
16
+ const CORE_DIST = path.join(ROOT, 'sharedmodule', 'llmswitch-core', 'dist', 'router', 'virtual-router');
17
17
 
18
18
  async function loadCoreModule(rel) {
19
19
  const file = path.join(CORE_DIST, rel);
@@ -21,16 +21,19 @@ async function loadCoreModule(rel) {
21
21
  }
22
22
 
23
23
  const { VirtualRouterEngine } = await loadCoreModule('engine.js');
24
+ const { bootstrapVirtualRouterConfig } = await loadCoreModule('bootstrap.js');
24
25
  const { providerErrorCenter } = await loadCoreModule('error-center.js');
25
26
  const { VirtualRouterError } = await loadCoreModule('types.js');
26
27
 
27
28
  function parseArgs(argv) {
28
- const args = { out: null };
29
+ const args = { out: null, config: null };
29
30
  const list = [...argv];
30
31
  while (list.length) {
31
32
  const cur = list.shift();
32
33
  if (cur === '--out' || cur === '--output') {
33
34
  args.out = list.shift() || null;
35
+ } else if (cur === '--config') {
36
+ args.config = list.shift() || null;
34
37
  } else if (cur === '--help' || cur === '-h') {
35
38
  args.help = true;
36
39
  }
@@ -57,9 +60,18 @@ function createRouterConfig() {
57
60
  'charlie.sim-model': buildProviderProfile('charlie.sim-model', 'https://charlie.local/v1')
58
61
  };
59
62
  const routing = {
60
- default: Object.keys(providers),
61
- coding: ['bravo.sim-model', 'charlie.sim-model'],
62
- thinking: ['charlie.sim-model', 'alpha.sim-model']
63
+ default: [
64
+ { id: 'default-primary', priority: 200, targets: ['alpha.sim-model', 'bravo.sim-model'] },
65
+ { id: 'default-backup', backup: true, priority: 100, targets: ['charlie.sim-model'] }
66
+ ],
67
+ coding: [
68
+ { id: 'coding-primary', priority: 200, targets: ['bravo.sim-model', 'charlie.sim-model'] },
69
+ { id: 'coding-backup', backup: true, priority: 100, targets: ['alpha.sim-model'] }
70
+ ],
71
+ thinking: [
72
+ { id: 'thinking-primary', priority: 200, targets: ['charlie.sim-model'] },
73
+ { id: 'thinking-backup', backup: true, priority: 100, targets: ['bravo.sim-model'] }
74
+ ]
63
75
  };
64
76
  return {
65
77
  routing,
@@ -227,16 +239,128 @@ async function scenarioScheduler(sim) {
227
239
  sim.runRoute('thinking');
228
240
  }
229
241
 
242
+ async function scenarioPriorityPools(sim) {
243
+ const first = sim.runRoute('thinking');
244
+ if (first !== 'charlie.sim-model') {
245
+ throw new Error(`expected primary thinking pool hit charlie.sim-model, got ${first}`);
246
+ }
247
+ sim.engine.handleProviderFailure({
248
+ providerKey: 'charlie.sim-model',
249
+ reason: 'priority-test',
250
+ fatal: true,
251
+ affectsHealth: true,
252
+ cooldownOverrideMs: 60_000
253
+ });
254
+ const second = sim.runRoute('thinking');
255
+ if (second !== 'bravo.sim-model') {
256
+ throw new Error(`expected thinking backup pool hit bravo.sim-model, got ${second}`);
257
+ }
258
+ }
259
+
230
260
  async function scenarioRoutingDirectives(sim) {
231
261
  sim.runRoute('baseline', '普通请求');
232
262
  sim.runRoute('forced-thinking', '请仔细分析这个问题 <**thinking**>');
233
263
  sim.runRoute('forced-provider', '请强制使用这个provider <**charlie.sim-model**> 来回答');
234
264
  }
235
265
 
266
+ async function scenarioRealConfig(configPath) {
267
+ const resolvedPath = path.resolve(configPath);
268
+ console.log(`\n=== Scenario: real-config (${resolvedPath}) ===`);
269
+ const source = JSON.parse(await fs.readFile(resolvedPath, 'utf-8'));
270
+ const section = source.virtualrouter && typeof source.virtualrouter === 'object' ? source.virtualrouter : source;
271
+ const { config } = bootstrapVirtualRouterConfig(section);
272
+ const engine = new VirtualRouterEngine();
273
+ engine.initialize(config);
274
+ const thinkingPools = config.routing.thinking ?? [];
275
+ const primaryPools = thinkingPools.filter((tier) => !tier.backup);
276
+ const backupPools = thinkingPools.filter((tier) => tier.backup);
277
+
278
+ const runThinking = (label) => {
279
+ const reqId = `real-config-${label}-${Date.now()}`;
280
+ const request = {
281
+ model: 'gpt-5.2-codex',
282
+ messages: [
283
+ { role: 'system', content: 'diagnostic' },
284
+ { role: 'user', content: `深入思考:${label}` }
285
+ ]
286
+ };
287
+ const metadata = {
288
+ requestId: reqId,
289
+ entryEndpoint: '/v1/responses',
290
+ processMode: 'chat',
291
+ stream: false,
292
+ direction: 'request',
293
+ providerProtocol: 'openai-responses'
294
+ };
295
+ const result = engine.route(request, metadata);
296
+ console.log(
297
+ JSON.stringify(
298
+ {
299
+ stage: 'real-config-route',
300
+ label,
301
+ providerKey: result.decision.providerKey,
302
+ route: result.decision.routeName,
303
+ poolId: result.decision.poolId
304
+ },
305
+ null,
306
+ 2
307
+ )
308
+ );
309
+ return result.decision.providerKey;
310
+ };
311
+
312
+ const markUnavailable = (targets, reason) => {
313
+ for (const key of targets || []) {
314
+ engine.handleProviderFailure({
315
+ providerKey: key,
316
+ fatal: true,
317
+ affectsHealth: true,
318
+ reason,
319
+ cooldownOverrideMs: 60_000
320
+ });
321
+ }
322
+ };
323
+
324
+ // Primary hit
325
+ const firstProvider = runThinking('primary-hit');
326
+ const primaryTargets = primaryPools.flatMap((pool) => pool.targets ?? []);
327
+ const backupTargets = backupPools.flatMap((pool) => pool.targets ?? []);
328
+ if (primaryTargets.length === 0) {
329
+ console.warn('[real-config] No explicit primary thinking pool configured.');
330
+ } else if (!primaryTargets.includes(firstProvider)) {
331
+ console.warn('[real-config] First provider is not part of primary tier:', firstProvider);
332
+ }
333
+
334
+ // Drain primary
335
+ markUnavailable(primaryTargets, 'primary-exhausted');
336
+ const secondProvider = runThinking('backup-hit');
337
+ if (backupTargets.length && !backupTargets.includes(secondProvider)) {
338
+ throw new Error(
339
+ `[real-config] Expected backup pool provider after draining primary, got ${secondProvider}`
340
+ );
341
+ }
342
+
343
+ // Drain backup -> should fall to default
344
+ markUnavailable(backupTargets, 'backup-exhausted');
345
+ const thirdProvider = runThinking('default-fallback');
346
+ const usedRoute = engine.getStatus().routes;
347
+ console.log(
348
+ JSON.stringify(
349
+ {
350
+ stage: 'real-config-summary',
351
+ thirdProvider,
352
+ routes: usedRoute
353
+ },
354
+ null,
355
+ 2
356
+ )
357
+ );
358
+ }
359
+
236
360
  async function main() {
237
361
  const args = parseArgs(process.argv.slice(2));
238
362
  if (args.help) {
239
- console.log('Usage: node scripts/tests/virtual-router-health.mjs [--out summary.json]');
363
+ console.log('Usage: node scripts/tests/virtual-router-health.mjs [--out summary.json] [--config ~/.routecodex/config.json]');
240
364
  return;
241
365
  }
242
366
 
@@ -247,6 +371,7 @@ async function main() {
247
371
  ['upstream', scenarioUpstream],
248
372
  ['timeout', scenarioTimeout],
249
373
  ['scheduler', scenarioScheduler],
374
+ ['priority-pools', scenarioPriorityPools],
250
375
  ['routing-directives', scenarioRoutingDirectives]
251
376
  ];
252
377
 
@@ -260,6 +385,16 @@ async function main() {
260
385
  });
261
386
  }
262
387
 
388
+ if (args.config) {
389
+ try {
390
+ await scenarioRealConfig(args.config);
391
+ summary.push({ name: 'real-config', status: 'ok', lastHealth: null });
392
+ } catch (error) {
393
+ console.error('[real-config] failed:', error);
394
+ summary.push({ name: 'real-config', status: 'failed', error: error?.message || String(error), lastHealth: null });
395
+ }
396
+ }
397
+
263
398
  if (args.out) {
264
399
  const outFile = path.resolve(process.cwd(), args.out);
265
400
  await fs.mkdir(path.dirname(outFile), { recursive: true });
@@ -13,18 +13,19 @@ const ROOT = path.resolve(__dirname, '../..');
13
13
 
14
14
  const HOME = os.homedir();
15
15
  const PROVIDER_ROOT = path.join(HOME, '.routecodex', 'provider');
16
- const SNAPSHOT_ROOT = path.join(HOME, '.routecodex', 'golden_samples');
17
- const PROVIDER_GOLDEN_ROOT = path.join(SNAPSHOT_ROOT, 'provider_golden_samples');
16
+ const RUNTIME_SNAPSHOT_ROOT = path.join(HOME, '.routecodex', 'codex-samples');
17
+ const GOLDEN_ROOT = path.join(HOME, '.routecodex', 'golden_samples');
18
+ const PROVIDER_GOLDEN_ROOT = path.join(GOLDEN_ROOT, 'provider_golden_samples');
18
19
  const CI_GOLDENS_ROOT = path.join(ROOT, 'samples', 'ci-goldens');
19
20
  const CUSTOM_SAMPLE_ROOTS = [
20
- path.join(SNAPSHOT_ROOT, 'new'),
21
+ path.join(GOLDEN_ROOT, 'new'),
21
22
  CI_GOLDENS_ROOT
22
23
  ];
23
24
  const TEMP_ROOT = path.join(process.cwd(), 'tmp', 'provider-captures');
24
25
  const STAGE_DIRS = {
25
- 'openai-chat': path.join(SNAPSHOT_ROOT, 'openai-chat'),
26
- 'openai-responses': path.join(SNAPSHOT_ROOT, 'openai-responses'),
27
- 'anthropic-messages': path.join(SNAPSHOT_ROOT, 'anthropic-messages')
26
+ 'openai-chat': path.join(RUNTIME_SNAPSHOT_ROOT, 'openai-chat'),
27
+ 'openai-responses': path.join(RUNTIME_SNAPSHOT_ROOT, 'openai-responses'),
28
+ 'anthropic-messages': path.join(RUNTIME_SNAPSHOT_ROOT, 'anthropic-messages')
28
29
  };
29
30
  const ENTRY_STAGE_MATRIX = {
30
31
  'openai-chat': {
@@ -437,7 +438,7 @@ function spawnServer(configPath, port) {
437
438
  }
438
439
 
439
440
  async function captureProvider(providerEntry, entryType, port, options, sanitizedProviderId) {
440
- const stageDir = path.join(SNAPSHOT_ROOT, ENTRY_DEFS[entryType].stageDir);
441
+ const stageDir = path.join(RUNTIME_SNAPSHOT_ROOT, ENTRY_DEFS[entryType].stageDir);
441
442
  const suffix = '_req_outbound_stage2_format_build.json';
442
443
  const before = snapshotStageFiles(stageDir, suffix);
443
444
  const baseUrl = `http://127.0.0.1:${port}`;