@jsonstudio/rcc 0.89.1189 → 0.89.1348

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (337) hide show
  1. package/README.md +17 -0
  2. package/configsamples/config.json +426 -0
  3. package/configsamples/config.reference.json +58 -0
  4. package/configsamples/provider/crs/config.v1.json +46 -0
  5. package/configsamples/provider/glm/config.v1.json +81 -0
  6. package/configsamples/provider/glm-anthropic/config.v1.json +45 -0
  7. package/configsamples/provider/iflow/config.v1.json +74 -0
  8. package/configsamples/provider/kimi/config.v1.json +41 -0
  9. package/configsamples/provider/lmstudio/config.v1.json +101 -0
  10. package/configsamples/provider/mimo/config.v1.json +35 -0
  11. package/configsamples/provider/modelscope/config.v1.json +96 -0
  12. package/configsamples/provider/qwen/config.v1.json +38 -0
  13. package/configsamples/provider/tab/config.v1.json +50 -0
  14. package/configsamples/provider/tabglm/config.v1.json +49 -0
  15. package/dist/build-info.js +2 -2
  16. package/dist/cli/commands/code.js +12 -6
  17. package/dist/cli/commands/code.js.map +1 -1
  18. package/dist/cli/commands/config.d.ts +2 -1
  19. package/dist/cli/commands/config.js +74 -103
  20. package/dist/cli/commands/config.js.map +1 -1
  21. package/dist/cli/commands/examples.js +6 -6
  22. package/dist/cli/commands/examples.js.map +1 -1
  23. package/dist/cli/commands/init.d.ts +28 -0
  24. package/dist/cli/commands/init.js +91 -0
  25. package/dist/cli/commands/init.js.map +1 -0
  26. package/dist/cli/commands/port.js +10 -2
  27. package/dist/cli/commands/port.js.map +1 -1
  28. package/dist/cli/commands/restart.js +5 -2
  29. package/dist/cli/commands/restart.js.map +1 -1
  30. package/dist/cli/commands/start.js +25 -22
  31. package/dist/cli/commands/start.js.map +1 -1
  32. package/dist/cli/commands/status.js +1 -0
  33. package/dist/cli/commands/status.js.map +1 -1
  34. package/dist/cli/commands/stop.js +1 -0
  35. package/dist/cli/commands/stop.js.map +1 -1
  36. package/dist/cli/config/bundled-docs.d.ts +20 -0
  37. package/dist/cli/config/bundled-docs.js +91 -0
  38. package/dist/cli/config/bundled-docs.js.map +1 -0
  39. package/dist/cli/config/init-config.d.ts +36 -0
  40. package/dist/cli/config/init-config.js +180 -0
  41. package/dist/cli/config/init-config.js.map +1 -0
  42. package/dist/cli/config/init-provider-catalog.d.ts +8 -0
  43. package/dist/cli/config/init-provider-catalog.js +187 -0
  44. package/dist/cli/config/init-provider-catalog.js.map +1 -0
  45. package/dist/cli/register/init-command.d.ts +3 -0
  46. package/dist/cli/register/init-command.js +5 -0
  47. package/dist/cli/register/init-command.js.map +1 -0
  48. package/dist/cli.js +28 -3
  49. package/dist/cli.js.map +1 -1
  50. package/dist/client/gemini-cli/gemini-cli-protocol-client.js +1 -1
  51. package/dist/client/gemini-cli/gemini-cli-protocol-client.js.map +1 -1
  52. package/dist/config/risk-control-config.d.ts +94 -0
  53. package/dist/config/risk-control-config.js +196 -0
  54. package/dist/config/risk-control-config.js.map +1 -0
  55. package/dist/constants/index.d.ts +6 -0
  56. package/dist/constants/index.js +13 -0
  57. package/dist/constants/index.js.map +1 -1
  58. package/dist/docs/daemon-admin-ui.html +2113 -190
  59. package/dist/index.js +0 -1
  60. package/dist/index.js.map +1 -1
  61. package/dist/manager/modules/health/index.d.ts +1 -1
  62. package/dist/manager/modules/quota/antigravity-quota-manager.d.ts +70 -0
  63. package/dist/manager/modules/quota/antigravity-quota-manager.js +442 -0
  64. package/dist/manager/modules/quota/antigravity-quota-manager.js.map +1 -0
  65. package/dist/manager/modules/quota/index.d.ts +3 -127
  66. package/dist/manager/modules/quota/index.js +2 -1093
  67. package/dist/manager/modules/quota/index.js.map +1 -1
  68. package/dist/manager/modules/quota/provider-key-normalization.d.ts +3 -0
  69. package/dist/manager/modules/quota/provider-key-normalization.js +155 -0
  70. package/dist/manager/modules/quota/provider-key-normalization.js.map +1 -0
  71. package/dist/manager/modules/quota/provider-quota-daemon.cooldown.d.ts +9 -0
  72. package/dist/manager/modules/quota/provider-quota-daemon.cooldown.js +115 -0
  73. package/dist/manager/modules/quota/provider-quota-daemon.cooldown.js.map +1 -0
  74. package/dist/manager/modules/quota/provider-quota-daemon.d.ts +77 -0
  75. package/dist/manager/modules/quota/provider-quota-daemon.events.d.ts +12 -0
  76. package/dist/manager/modules/quota/provider-quota-daemon.events.js +237 -0
  77. package/dist/manager/modules/quota/provider-quota-daemon.events.js.map +1 -0
  78. package/dist/manager/modules/quota/provider-quota-daemon.js +404 -0
  79. package/dist/manager/modules/quota/provider-quota-daemon.js.map +1 -0
  80. package/dist/manager/modules/quota/provider-quota-daemon.model-backoff.d.ts +11 -0
  81. package/dist/manager/modules/quota/provider-quota-daemon.model-backoff.js +189 -0
  82. package/dist/manager/modules/quota/provider-quota-daemon.model-backoff.js.map +1 -0
  83. package/dist/manager/modules/quota/provider-quota-daemon.snapshot.d.ts +8 -0
  84. package/dist/manager/modules/quota/provider-quota-daemon.snapshot.js +96 -0
  85. package/dist/manager/modules/quota/provider-quota-daemon.snapshot.js.map +1 -0
  86. package/dist/manager/modules/quota/provider-quota-daemon.view.d.ts +19 -0
  87. package/dist/manager/modules/quota/provider-quota-daemon.view.js +37 -0
  88. package/dist/manager/modules/quota/provider-quota-daemon.view.js.map +1 -0
  89. package/dist/manager/modules/routing/index.d.ts +1 -0
  90. package/dist/manager/modules/routing/index.js +11 -25
  91. package/dist/manager/modules/routing/index.js.map +1 -1
  92. package/dist/manager/quota/provider-quota-center.d.ts +2 -0
  93. package/dist/manager/quota/provider-quota-center.js +80 -82
  94. package/dist/manager/quota/provider-quota-center.js.map +1 -1
  95. package/dist/modules/llmswitch/bridge.d.ts +16 -18
  96. package/dist/modules/llmswitch/bridge.js +314 -71
  97. package/dist/modules/llmswitch/bridge.js.map +1 -1
  98. package/dist/modules/llmswitch/core-loader.d.ts +4 -2
  99. package/dist/modules/llmswitch/core-loader.js +32 -20
  100. package/dist/modules/llmswitch/core-loader.js.map +1 -1
  101. package/dist/modules/pipeline/utils/colored-logger.js +3 -2
  102. package/dist/modules/pipeline/utils/colored-logger.js.map +1 -1
  103. package/dist/modules/pipeline/utils/debug-logger.js +1 -1
  104. package/dist/modules/pipeline/utils/debug-logger.js.map +1 -1
  105. package/dist/providers/auth/iflow-cookie-auth.js +0 -2
  106. package/dist/providers/auth/iflow-cookie-auth.js.map +1 -1
  107. package/dist/providers/auth/oauth-lifecycle.js +2 -23
  108. package/dist/providers/auth/oauth-lifecycle.js.map +1 -1
  109. package/dist/providers/core/config/camoufox-launcher.js +35 -4
  110. package/dist/providers/core/config/camoufox-launcher.js.map +1 -1
  111. package/dist/providers/core/runtime/antigravity-quota-client.js +6 -3
  112. package/dist/providers/core/runtime/antigravity-quota-client.js.map +1 -1
  113. package/dist/providers/core/runtime/base-provider.d.ts +2 -2
  114. package/dist/providers/core/runtime/base-provider.js +74 -69
  115. package/dist/providers/core/runtime/base-provider.js.map +1 -1
  116. package/dist/providers/core/runtime/gemini-cli-http-provider.js +6 -4
  117. package/dist/providers/core/runtime/gemini-cli-http-provider.js.map +1 -1
  118. package/dist/providers/core/runtime/http-request-executor.js +2 -2
  119. package/dist/providers/core/runtime/http-request-executor.js.map +1 -1
  120. package/dist/providers/core/runtime/http-transport-provider.d.ts +14 -0
  121. package/dist/providers/core/runtime/http-transport-provider.js +111 -5
  122. package/dist/providers/core/runtime/http-transport-provider.js.map +1 -1
  123. package/dist/providers/core/runtime/provider-error-classifier.js +10 -0
  124. package/dist/providers/core/runtime/provider-error-classifier.js.map +1 -1
  125. package/dist/providers/core/runtime/provider-factory.js +7 -5
  126. package/dist/providers/core/runtime/provider-factory.js.map +1 -1
  127. package/dist/providers/core/runtime/provider-runtime-metadata.d.ts +6 -0
  128. package/dist/providers/core/runtime/provider-runtime-metadata.js.map +1 -1
  129. package/dist/providers/core/runtime/responses-provider.d.ts +1 -7
  130. package/dist/providers/core/runtime/responses-provider.js +12 -93
  131. package/dist/providers/core/runtime/responses-provider.js.map +1 -1
  132. package/dist/providers/core/strategies/oauth-auth-code-flow.js +12 -8
  133. package/dist/providers/core/strategies/oauth-auth-code-flow.js.map +1 -1
  134. package/dist/providers/core/utils/http-client.js +16 -3
  135. package/dist/providers/core/utils/http-client.js.map +1 -1
  136. package/dist/providers/core/utils/provider-error-logger.d.ts +1 -1
  137. package/dist/providers/core/utils/provider-error-reporter.d.ts +3 -1
  138. package/dist/providers/core/utils/provider-error-reporter.js +3 -0
  139. package/dist/providers/core/utils/provider-error-reporter.js.map +1 -1
  140. package/dist/providers/core/utils/snapshot-writer.js +1 -4
  141. package/dist/providers/core/utils/snapshot-writer.js.map +1 -1
  142. package/dist/providers/mock/mock-provider-runtime.js +57 -27
  143. package/dist/providers/mock/mock-provider-runtime.js.map +1 -1
  144. package/dist/scripts/camoufox/launch-auth.mjs +193 -58
  145. package/dist/server/handlers/handler-utils.js +3 -2
  146. package/dist/server/handlers/handler-utils.js.map +1 -1
  147. package/dist/server/runtime/http-server/daemon-admin/auth-handler.d.ts +2 -0
  148. package/dist/server/runtime/http-server/daemon-admin/auth-handler.js +103 -0
  149. package/dist/server/runtime/http-server/daemon-admin/auth-handler.js.map +1 -0
  150. package/dist/server/runtime/http-server/daemon-admin/auth-session.d.ts +5 -0
  151. package/dist/server/runtime/http-server/daemon-admin/auth-session.js +77 -0
  152. package/dist/server/runtime/http-server/daemon-admin/auth-session.js.map +1 -0
  153. package/dist/server/runtime/http-server/daemon-admin/auth-store.d.ts +18 -0
  154. package/dist/server/runtime/http-server/daemon-admin/auth-store.js +89 -0
  155. package/dist/server/runtime/http-server/daemon-admin/auth-store.js.map +1 -0
  156. package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js +1 -2
  157. package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js.map +1 -1
  158. package/dist/server/runtime/http-server/daemon-admin/providers-handler.js +226 -24
  159. package/dist/server/runtime/http-server/daemon-admin/providers-handler.js.map +1 -1
  160. package/dist/server/runtime/http-server/daemon-admin/quota-handler.js +47 -8
  161. package/dist/server/runtime/http-server/daemon-admin/quota-handler.js.map +1 -1
  162. package/dist/server/runtime/http-server/daemon-admin/restart-handler.js +1 -1
  163. package/dist/server/runtime/http-server/daemon-admin/restart-handler.js.map +1 -1
  164. package/dist/server/runtime/http-server/daemon-admin/stats-handler.js +1 -1
  165. package/dist/server/runtime/http-server/daemon-admin/stats-handler.js.map +1 -1
  166. package/dist/server/runtime/http-server/daemon-admin/status-handler.js +68 -4
  167. package/dist/server/runtime/http-server/daemon-admin/status-handler.js.map +1 -1
  168. package/dist/server/runtime/http-server/daemon-admin-routes.d.ts +3 -4
  169. package/dist/server/runtime/http-server/daemon-admin-routes.js +9 -14
  170. package/dist/server/runtime/http-server/daemon-admin-routes.js.map +1 -1
  171. package/dist/server/runtime/http-server/executor-metadata.js +1 -1
  172. package/dist/server/runtime/http-server/executor-metadata.js.map +1 -1
  173. package/dist/server/runtime/http-server/executor-response.js +0 -16
  174. package/dist/server/runtime/http-server/executor-response.js.map +1 -1
  175. package/dist/server/runtime/http-server/hub-shadow-compare.d.ts +18 -0
  176. package/dist/server/runtime/http-server/hub-shadow-compare.js +256 -0
  177. package/dist/server/runtime/http-server/hub-shadow-compare.js.map +1 -0
  178. package/dist/server/runtime/http-server/index.d.ts +7 -2
  179. package/dist/server/runtime/http-server/index.js +287 -49
  180. package/dist/server/runtime/http-server/index.js.map +1 -1
  181. package/dist/server/runtime/http-server/middleware.js +19 -1
  182. package/dist/server/runtime/http-server/middleware.js.map +1 -1
  183. package/dist/server/runtime/http-server/request-executor.js +10 -19
  184. package/dist/server/runtime/http-server/request-executor.js.map +1 -1
  185. package/dist/server/runtime/http-server/routes.js +8 -2
  186. package/dist/server/runtime/http-server/routes.js.map +1 -1
  187. package/dist/server/runtime/http-server/session-dir.d.ts +2 -0
  188. package/dist/server/runtime/http-server/session-dir.js +59 -0
  189. package/dist/server/runtime/http-server/session-dir.js.map +1 -0
  190. package/dist/server/runtime/http-server/types.d.ts +0 -4
  191. package/dist/server/utils/utf8-chunk-buffer.js +6 -3
  192. package/dist/server/utils/utf8-chunk-buffer.js.map +1 -1
  193. package/dist/server/utils/warmup-storm-tracker.js +1 -1
  194. package/dist/server/utils/warmup-storm-tracker.js.map +1 -1
  195. package/dist/server-factory.d.ts +6 -28
  196. package/dist/server-factory.js +8 -93
  197. package/dist/server-factory.js.map +1 -1
  198. package/dist/token-daemon/index.js +2 -2
  199. package/dist/token-daemon/index.js.map +1 -1
  200. package/dist/token-daemon/provider-registry.js +0 -1
  201. package/dist/token-daemon/provider-registry.js.map +1 -1
  202. package/dist/token-daemon/server-utils.js +8 -9
  203. package/dist/token-daemon/server-utils.js.map +1 -1
  204. package/dist/token-daemon/token-utils.js +1 -1
  205. package/dist/token-daemon/token-utils.js.map +1 -1
  206. package/dist/tools/semantic-replay.js +2 -2
  207. package/dist/tools/semantic-replay.js.map +1 -1
  208. package/dist/tools/stats-request-events.d.ts +1 -1
  209. package/dist/tools/stats-usage.js +6 -3
  210. package/dist/tools/stats-usage.js.map +1 -1
  211. package/dist/utils/errorsamples.d.ts +5 -0
  212. package/dist/utils/errorsamples.js +27 -0
  213. package/dist/utils/errorsamples.js.map +1 -0
  214. package/dist/utils/llms-engine-shadow.d.ts +19 -0
  215. package/dist/utils/llms-engine-shadow.js +209 -0
  216. package/dist/utils/llms-engine-shadow.js.map +1 -0
  217. package/dist/utils/runtime-versions.d.ts +1 -0
  218. package/dist/utils/runtime-versions.js +39 -0
  219. package/dist/utils/runtime-versions.js.map +1 -0
  220. package/docs/ARCHITECTURE.md +402 -0
  221. package/docs/CODEX_AND_CLAUDE_CODE.md +69 -0
  222. package/docs/CONFIG_ARCHITECTURE.md +517 -0
  223. package/docs/ERROR_HANDLING_AUDIT.md +0 -0
  224. package/docs/GCLI2API_PARITY_GAPS.md +98 -0
  225. package/docs/INSTALLATION_AND_QUICKSTART.md +74 -0
  226. package/docs/INSTRUCTION_MARKUP.md +89 -0
  227. package/docs/MODULE_ENHANCEMENT_SYSTEM.md +666 -0
  228. package/docs/PORTS.md +36 -0
  229. package/docs/PROVIDERS_BUILTIN.md +111 -0
  230. package/docs/PROVIDER_TYPES.md +55 -0
  231. package/docs/SERVERTOOL_CLOCK_DESIGN.md +233 -0
  232. package/docs/USAGE_HANDLING_ANALYSIS.md +335 -0
  233. package/docs/USER_CONFIG_PARSER_CHANGES.md +175 -0
  234. package/docs/V3_INBOUND_OUTBOUND_DESIGN.md +86 -0
  235. package/docs/VIRTUAL_ROUTER_PRIORITY_AND_HEALTH.md +125 -0
  236. package/docs/anthropic-request-golden-samples.md +50 -0
  237. package/docs/ccr-alignment-enhancetool.md +105 -0
  238. package/docs/chat-glm-500-analysis.md +79 -0
  239. package/docs/chat-request-golden-samples.md +42 -0
  240. package/docs/chat-semantic-expansion-plan.md +82 -0
  241. package/docs/cli-command-inventory.md +76 -0
  242. package/docs/codex-samples-replay.md +50 -0
  243. package/docs/daemon-admin-api-design.md +350 -0
  244. package/docs/daemon-admin-module-structure.md +169 -0
  245. package/docs/daemon-admin-ui.html +3394 -0
  246. package/docs/debug-system-design.md +734 -0
  247. package/docs/debugging/gemini-sse-root-cause.md +52 -0
  248. package/docs/debugging/sse_encoding_failure_analysis.md +53 -0
  249. package/docs/dry-run/README.md +721 -0
  250. package/docs/error-handling-v2.md +92 -0
  251. package/docs/exec-command-guard-policy.example.v1.json +42 -0
  252. package/docs/fixes/gemini-protocol-mapping.md +57 -0
  253. package/docs/fixes/oauth-portal-timing-fix.md +202 -0
  254. package/docs/fixes/web-search-hop3-fix.md +265 -0
  255. package/docs/glm-api-reference.md +390 -0
  256. package/docs/glm-chat-completions.md +1779 -0
  257. package/docs/glm-history-inline-images.md +44 -0
  258. package/docs/golden-ci-library.md +66 -0
  259. package/docs/lmstudio-dry-run-summary.md +203 -0
  260. package/docs/lmstudio-tool-calling.md +214 -0
  261. package/docs/mapping-tables/anthropic-to-openai.json +290 -0
  262. package/docs/mapping-tables/iflow-to-openai.json +215 -0
  263. package/docs/mapping-tables/openai-passthrough.json +190 -0
  264. package/docs/mapping-tables/openai-to-iflow.json +227 -0
  265. package/docs/monitoring/Design.md +61 -0
  266. package/docs/multi-token-auth-guide.md +66 -0
  267. package/docs/oauth-authentication-guide.md +168 -0
  268. package/docs/oauth-iflow-implementation.md +153 -0
  269. package/docs/pipeline-routing-report.md +209 -0
  270. package/docs/plans/manager-daemon/PLAN.md +86 -0
  271. package/docs/plans/provider-config-v2-plan.md +176 -0
  272. package/docs/plans/provider-runtime-manager-plan.md +209 -0
  273. package/docs/plans/transparent-429-failover.md +89 -0
  274. package/docs/plans/unified-hub-framework-v1.md +245 -0
  275. package/docs/provider-config-v2-ui-design.md +181 -0
  276. package/docs/provider-quota-design.md +129 -0
  277. package/docs/providers/gemini-provider.md +62 -0
  278. package/docs/providers/lmstudio-v2-migration-report.md +102 -0
  279. package/docs/providers/provider-composite-design.md +142 -0
  280. package/docs/providers/provider-composite-testing.md +98 -0
  281. package/docs/providers/provider-type-only-migration.md +111 -0
  282. package/docs/rccx-wasm-migration.md +74 -0
  283. package/docs/refactoring/architecture-comparison-diagram.md +140 -0
  284. package/docs/refactoring/compatibility-v2-architecture-design.md +738 -0
  285. package/docs/refactoring/workflow-compatibility-refactoring-design.md +361 -0
  286. package/docs/reports/routing-classification-report.json +24 -0
  287. package/docs/reports/routing-classification-report.md +18 -0
  288. package/docs/reports/thinking-keywords-report.json +19 -0
  289. package/docs/responses/README.md +156 -0
  290. package/docs/responses-generic-provider.md +86 -0
  291. package/docs/responses-passthrough-provider-design.md +202 -0
  292. package/docs/routing-awrr-health-weighted-round-robin.md +179 -0
  293. package/docs/routing-instructions.md +393 -0
  294. package/docs/stop-message-auto.md +225 -0
  295. package/docs/streaming-flow.html +30 -0
  296. package/docs/streaming-flow.md +182 -0
  297. package/docs/token-daemon-preview.html +490 -0
  298. package/docs/token-refresh-daemon-plan.md +269 -0
  299. package/docs/transformation-tables/Gemini-FinishReason/345/256/214/346/225/264/350/275/254/346/215/242/350/241/250.json +233 -0
  300. package/docs/transformation-tables/README.md +225 -0
  301. package/docs/transformation-tables/claude-code-router-anthropic-to-gemini.json +283 -0
  302. package/docs/transformation-tables/claude-code-router-anthropic-to-openai.json +208 -0
  303. package/docs/transformation-tables/claude-code-router-openai-to-anthropic.json +261 -0
  304. package/docs/transformation-tables/claude-code-router-openai-to-gemini.json +208 -0
  305. package/docs/transformation-tables/claude-code-router-openai-to-lmstudio.json +182 -0
  306. package/docs/transformation-tables/claude-code-router-openai-to-ollama.json +250 -0
  307. package/docs/transformation-tables/claude-code-router-openai-to-textgenwebui.json +295 -0
  308. package/docs/transformation-tables/claude-code-router-provider-conversions.json +193 -0
  309. 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
  310. 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
  311. 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
  312. 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
  313. 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
  314. 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
  315. 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
  316. package/docs/v2-architecture/IMPLEMENTATION-ROADMAP.md +367 -0
  317. package/docs/v2-architecture/OPTIMIZED-DESIGN.md +827 -0
  318. package/docs/v2-architecture/PRERUN-CONNECTION-DESIGN.md +716 -0
  319. package/docs/v2-architecture/README.md +551 -0
  320. package/docs/verification/modelscope-verify.md +59 -0
  321. package/docs/web-search-service-design.md +322 -0
  322. package/package.json +12 -7
  323. package/scripts/camoufox/launch-auth.mjs +193 -58
  324. package/scripts/monitor-diff.mjs +126 -0
  325. package/scripts/pack-mode.mjs +19 -1
  326. package/scripts/pack-rcc.mjs +63 -0
  327. package/scripts/unified-hub-shadow-compare.mjs +33 -13
  328. package/scripts/verify-e2e-toolcall.mjs +115 -26
  329. package/dist/modules/llmswitch/pipeline-registry.d.ts +0 -57
  330. package/dist/modules/llmswitch/pipeline-registry.js +0 -229
  331. package/dist/modules/llmswitch/pipeline-registry.js.map +0 -1
  332. package/dist/server/RouteCodexServer.d.ts +0 -13
  333. package/dist/server/RouteCodexServer.js +0 -25
  334. package/dist/server/RouteCodexServer.js.map +0 -1
  335. package/dist/v2/conversion/hub/snapshot-recorder.d.ts +0 -12
  336. package/dist/v2/conversion/hub/snapshot-recorder.js +0 -22
  337. package/dist/v2/conversion/hub/snapshot-recorder.js.map +0 -1
@@ -21,7 +21,7 @@ import { registerHttpRoutes, registerOAuthPortalRoute } from './routes.js';
21
21
  import { mapProviderProtocol, normalizeProviderType, resolveProviderIdentity, asRecord } from './provider-utils.js';
22
22
  import { resolveRepoRoot } from './llmswitch-loader.js';
23
23
  import { enhanceProviderRequestId } from '../../utils/request-id-manager.js';
24
- import { convertProviderResponse as bridgeConvertProviderResponse, createSnapshotRecorder as bridgeCreateSnapshotRecorder, rebindResponsesConversationRequestId, bootstrapVirtualRouterConfig, getHubPipelineCtor } from '../../../modules/llmswitch/bridge.js';
24
+ import { convertProviderResponse as bridgeConvertProviderResponse, createSnapshotRecorder as bridgeCreateSnapshotRecorder, rebindResponsesConversationRequestId, extractSessionIdentifiersFromMetadata, bootstrapVirtualRouterConfig, getHubPipelineCtor } from '../../../modules/llmswitch/bridge.js';
25
25
  import { initializeRouteErrorHub, reportRouteError } from '../../../error-handling/route-error-hub.js';
26
26
  import { writeClientSnapshot } from '../../../providers/core/utils/snapshot-writer.js';
27
27
  import { createServerColoredLogger } from './colored-logger.js';
@@ -32,8 +32,22 @@ import { ManagerDaemon } from '../../../manager/index.js';
32
32
  import { HealthManagerModule } from '../../../manager/modules/health/index.js';
33
33
  import { RoutingStateManagerModule } from '../../../manager/modules/routing/index.js';
34
34
  import { TokenManagerModule } from '../../../manager/modules/token/index.js';
35
+ import { ensureServerScopedSessionDir } from './session-dir.js';
35
36
  import { StatsManager } from './stats-manager.js';
36
37
  import { loadRouteCodexConfig } from '../../../config/routecodex-config-loader.js';
38
+ import { buildInfo } from '../../../build-info.js';
39
+ import { recordHubShadowCompareDiff, resolveHubShadowCompareConfig, shouldRunHubShadowCompare } from './hub-shadow-compare.js';
40
+ import { recordLlmsEngineShadowDiff, isLlmsEngineShadowEnabledForSubpath, resolveLlmsEngineShadowConfig, shouldRunLlmsEngineShadowForSubpath } from '../../../utils/llms-engine-shadow.js';
41
+ import { resolveLlmswitchCoreVersion } from '../../../utils/runtime-versions.js';
42
+ const DEFAULT_MAX_PROVIDER_ATTEMPTS = 6;
43
+ function resolveMaxProviderAttempts() {
44
+ const raw = String(process.env.ROUTECODEX_MAX_PROVIDER_ATTEMPTS || process.env.RCC_MAX_PROVIDER_ATTEMPTS || '')
45
+ .trim()
46
+ .toLowerCase();
47
+ const parsed = raw ? Number.parseInt(raw, 10) : NaN;
48
+ const candidate = Number.isFinite(parsed) ? parsed : DEFAULT_MAX_PROVIDER_ATTEMPTS;
49
+ return Math.max(1, Math.min(20, candidate));
50
+ }
37
51
  /**
38
52
  * RouteCodex Server V2
39
53
  *
@@ -66,16 +80,19 @@ export class RouteCodexHttpServer {
66
80
  managerDaemon = null;
67
81
  stats = new StatsManager();
68
82
  restartChain = Promise.resolve();
83
+ hubShadowCompareConfig = resolveHubShadowCompareConfig();
84
+ llmsEngineShadowConfig = resolveLlmsEngineShadowConfig();
85
+ hubPolicyMode = null;
86
+ hubPipelineEngineShadow = null;
87
+ hubPipelineConfigForShadow = null;
69
88
  constructor(config) {
70
89
  this.config = config;
71
90
  this.app = express();
72
91
  this.errorHandling = new QuietErrorHandlingCenter();
73
92
  this.stageLoggingEnabled = isStageLoggingEnabled();
74
93
  this.repoRoot = resolveRepoRoot(import.meta.url);
75
- const envFlag = (process.env.ROUTECODEX_USE_HUB_PIPELINE || '').trim().toLowerCase();
76
- if (config.pipeline?.useHubPipeline === false || envFlag === '0' || envFlag === 'false') {
77
- console.warn('[RouteCodexHttpServer] Super pipeline has been removed; falling back to Hub pipeline.');
78
- }
94
+ // Ensure session-scoped routing state does not leak across server instances.
95
+ ensureServerScopedSessionDir(`${this.config.server.host}:${this.config.server.port}`);
79
96
  try {
80
97
  this.pipelineLogger = new PipelineDebugLoggerImpl({ colored: this.coloredLogger }, { enableConsoleLogging: true });
81
98
  }
@@ -111,20 +128,11 @@ export class RouteCodexHttpServer {
111
128
  /**
112
129
  * Register Daemon Admin UI route.
113
130
  * Serves docs/daemon-admin-ui.html as a static page.
114
- * - If `httpserver.apikey` is not configured: localhost-only.
115
- * - If `httpserver.apikey` is configured: allow remote UI access (API calls still require apikey).
131
+ * Note: daemon-admin UI/API now uses password login (stored at ~/.routecodex/login) instead of httpserver.apikey.
116
132
  */
117
133
  registerDaemonAdminUiRoute() {
118
134
  this.app.get('/daemon/admin', async (req, res) => {
119
135
  try {
120
- const ip = req.socket?.remoteAddress || '';
121
- const isLocal = ip === '127.0.0.1' || ip === '::1' || ip === '::ffff:127.0.0.1';
122
- const expectedKey = typeof this.config?.server?.apikey === 'string' ? this.config.server.apikey.trim() : '';
123
- const hasConfiguredKey = Boolean(expectedKey);
124
- if (!isLocal && !hasConfiguredKey) {
125
- res.status(403).json({ error: { message: 'forbidden', code: 'forbidden' } });
126
- return;
127
- }
128
136
  const fs = await import('node:fs/promises');
129
137
  let html = '';
130
138
  try {
@@ -353,6 +361,46 @@ export class RouteCodexHttpServer {
353
361
  this.hubPipelineCtor = ctorFactory;
354
362
  return this.hubPipelineCtor;
355
363
  }
364
+ async ensureHubPipelineEngineShadow() {
365
+ if (this.hubPipelineEngineShadow) {
366
+ return this.hubPipelineEngineShadow;
367
+ }
368
+ if (!this.hubPipelineConfigForShadow) {
369
+ throw new Error('Hub pipeline shadow config is not initialized');
370
+ }
371
+ const baseConfig = this.hubPipelineConfigForShadow;
372
+ const shadowConfig = { ...baseConfig };
373
+ // Avoid double side effects when shadow-running the pipeline: keep reads, drop writes.
374
+ const routingStateStore = baseConfig.routingStateStore;
375
+ if (routingStateStore && typeof routingStateStore.loadSync === 'function') {
376
+ shadowConfig.routingStateStore = {
377
+ loadSync: routingStateStore.loadSync.bind(routingStateStore),
378
+ saveAsync: () => { }
379
+ };
380
+ }
381
+ const healthStore = baseConfig.healthStore;
382
+ if (healthStore && typeof healthStore.loadInitialSnapshot === 'function') {
383
+ shadowConfig.healthStore = {
384
+ loadInitialSnapshot: healthStore.loadInitialSnapshot.bind(healthStore)
385
+ };
386
+ }
387
+ const quotaViewReadOnly = baseConfig.quotaViewReadOnly;
388
+ if (typeof quotaViewReadOnly === 'function') {
389
+ shadowConfig.quotaView = quotaViewReadOnly;
390
+ }
391
+ const bridge = (await import('../../../modules/llmswitch/bridge.js'));
392
+ const getCtor = bridge.getHubPipelineCtorForImpl;
393
+ if (typeof getCtor !== 'function') {
394
+ throw new Error('llmswitch bridge does not expose getHubPipelineCtorForImpl');
395
+ }
396
+ const ctorFactory = await getCtor('engine');
397
+ const hubCtor = ctorFactory;
398
+ if (!('virtualRouter' in shadowConfig)) {
399
+ throw new Error('HubPipeline shadow config missing virtualRouter');
400
+ }
401
+ this.hubPipelineEngineShadow = new hubCtor(shadowConfig);
402
+ return this.hubPipelineEngineShadow;
403
+ }
356
404
  isPipelineReady() {
357
405
  return Boolean(this.hubPipeline);
358
406
  }
@@ -656,6 +704,7 @@ export class RouteCodexHttpServer {
656
704
  const hubPolicyMode = hubPolicyModeRaw === 'off' || hubPolicyModeRaw === '0' || hubPolicyModeRaw === 'false'
657
705
  ? null
658
706
  : (hubPolicyModeRaw === 'observe' || hubPolicyModeRaw === 'enforce' ? hubPolicyModeRaw : 'enforce');
707
+ this.hubPolicyMode = hubPolicyMode ?? 'off';
659
708
  if (hubPolicyMode) {
660
709
  const sampleRateRaw = String(process.env.ROUTECODEX_HUB_POLICY_SAMPLE_RATE || '').trim();
661
710
  const sampleRate = sampleRateRaw ? Number(sampleRateRaw) : undefined;
@@ -664,6 +713,40 @@ export class RouteCodexHttpServer {
664
713
  ...(Number.isFinite(sampleRate) ? { sampleRate } : {})
665
714
  };
666
715
  }
716
+ // Unified Hub Framework V1: tool surface rollout toggle (enforce by default in dev).
717
+ // - Disable via env: ROUTECODEX_HUB_TOOL_SURFACE_MODE=off
718
+ // - Observe via env: ROUTECODEX_HUB_TOOL_SURFACE_MODE=observe
719
+ // - Shadow (diff-only, no rewrites) via env: ROUTECODEX_HUB_TOOL_SURFACE_MODE=shadow
720
+ // - Enforce (rewrite outbound payload) via env: ROUTECODEX_HUB_TOOL_SURFACE_MODE=enforce
721
+ const toolSurfaceModeRaw = String(process.env.ROUTECODEX_HUB_TOOL_SURFACE_MODE || '').trim().toLowerCase();
722
+ const toolSurfaceMode = toolSurfaceModeRaw === 'off' || toolSurfaceModeRaw === '0' || toolSurfaceModeRaw === 'false'
723
+ ? null
724
+ : toolSurfaceModeRaw === 'observe' || toolSurfaceModeRaw === 'shadow' || toolSurfaceModeRaw === 'enforce'
725
+ ? toolSurfaceModeRaw
726
+ : buildInfo.mode === 'dev'
727
+ ? 'enforce'
728
+ : null;
729
+ if (toolSurfaceMode) {
730
+ const sampleRateRaw = String(process.env.ROUTECODEX_HUB_TOOL_SURFACE_SAMPLE_RATE || '').trim();
731
+ const sampleRate = sampleRateRaw ? Number(sampleRateRaw) : undefined;
732
+ hubConfig.toolSurface = {
733
+ mode: toolSurfaceMode,
734
+ ...(Number.isFinite(sampleRate) ? { sampleRate } : {})
735
+ };
736
+ // Also export the resolved mode to env so llmswitch-core response conversion
737
+ // (convertProviderResponse) can observe tool surface mismatches consistently.
738
+ if (!process.env.ROUTECODEX_HUB_TOOL_SURFACE_MODE) {
739
+ process.env.ROUTECODEX_HUB_TOOL_SURFACE_MODE = toolSurfaceMode;
740
+ }
741
+ }
742
+ // Unified Hub Framework V1: followup (servertool) shadow compare toggle.
743
+ // Implemented in llmswitch-core servertool engine; controlled by env for progressive rollout.
744
+ // Default: shadow in dev builds; off in release builds.
745
+ if (!process.env.ROUTECODEX_HUB_FOLLOWUP_MODE) {
746
+ if (buildInfo.mode === 'dev') {
747
+ process.env.ROUTECODEX_HUB_FOLLOWUP_MODE = 'shadow';
748
+ }
749
+ }
667
750
  const healthModule = this.managerDaemon?.getModule('health');
668
751
  const healthStore = healthModule?.getHealthStore();
669
752
  if (healthStore) {
@@ -677,6 +760,9 @@ export class RouteCodexHttpServer {
677
760
  const quotaModule = this.managerDaemon?.getModule('provider-quota');
678
761
  if (this.isQuotaRoutingEnabled() && quotaModule && typeof quotaModule.getQuotaView === 'function') {
679
762
  hubConfig.quotaView = quotaModule.getQuotaView();
763
+ if (typeof quotaModule.getQuotaViewReadOnly === 'function') {
764
+ hubConfig.quotaViewReadOnly = quotaModule.getQuotaViewReadOnly();
765
+ }
680
766
  }
681
767
  if (!this.hubPipeline) {
682
768
  this.hubPipeline = new hubCtor(hubConfig);
@@ -695,6 +781,9 @@ export class RouteCodexHttpServer {
695
781
  }
696
782
  this.hubPipeline.updateVirtualRouterConfig(bootstrapArtifacts.config);
697
783
  }
784
+ // llms-engine shadow: capture the latest hub config and reset shadow pipeline to avoid stale deps.
785
+ this.hubPipelineConfigForShadow = hubConfig;
786
+ this.hubPipelineEngineShadow = null;
698
787
  await this.initializeProviderRuntimes(bootstrapArtifacts);
699
788
  }
700
789
  buildHandlerContext() {
@@ -924,11 +1013,12 @@ export class RouteCodexHttpServer {
924
1013
  }
925
1014
  const pipelineLabel = 'hub';
926
1015
  const iterationMetadata = initialMetadata;
927
- const _followupTriggered = false;
928
- // 单次 HTTP 请求内最多做一次 failover(不在 Provider 层做重试):
1016
+ // _followupTriggered = false;
1017
+ // 单次 HTTP 请求内允许多次 failover(不在 Provider 层做重试):
929
1018
  // - 让 VirtualRouter 根据 excludedProviderKeys 跳过失败目标
930
1019
  // - 避免客户端“一次就断”导致对话破裂(尤其是 429 / prompt too long 等可恢复错误)
931
- const maxAttempts = 2;
1020
+ // - 通过 env 允许按部署/客户端调整:ROUTECODEX_MAX_PROVIDER_ATTEMPTS / RCC_MAX_PROVIDER_ATTEMPTS
1021
+ const maxAttempts = resolveMaxProviderAttempts();
932
1022
  let attempt = 0;
933
1023
  let firstError = null;
934
1024
  const originalBodySnapshot = this.cloneRequestPayload(input.body);
@@ -1102,9 +1192,13 @@ export class RouteCodexHttpServer {
1102
1192
  const sessionId = typeof mergedMetadata.sessionId === "string" && mergedMetadata.sessionId.trim()
1103
1193
  ? mergedMetadata.sessionId.trim()
1104
1194
  : undefined;
1105
- const conversationId = typeof mergedMetadata.conversationId === "string" && mergedMetadata.conversationId.trim()
1195
+ let conversationId = typeof mergedMetadata.conversationId === "string" && mergedMetadata.conversationId.trim()
1106
1196
  ? mergedMetadata.conversationId.trim()
1107
1197
  : undefined;
1198
+ // 对称补齐:如果只有 session_id,则回传 conversation_id=session_id
1199
+ if (!conversationId && sessionId) {
1200
+ conversationId = sessionId;
1201
+ }
1108
1202
  if (sessionId || conversationId) {
1109
1203
  if (!converted.headers) {
1110
1204
  converted.headers = {};
@@ -1167,11 +1261,18 @@ export class RouteCodexHttpServer {
1167
1261
  throw new Error('Hub pipeline runtime is not initialized');
1168
1262
  }
1169
1263
  const payload = asRecord(input.body);
1264
+ const isInternalFollowup = metadata.serverToolFollowup === true;
1265
+ const wantsShadowCompare = !isInternalFollowup && shouldRunHubShadowCompare(this.hubShadowCompareConfig);
1170
1266
  const pipelineInput = {
1171
1267
  ...input,
1268
+ id: input.requestId,
1269
+ endpoint: input.entryEndpoint,
1172
1270
  metadata: {
1173
1271
  ...metadata,
1174
- logger: this.coloredLogger
1272
+ logger: this.coloredLogger,
1273
+ ...(wantsShadowCompare
1274
+ ? { __hubShadowCompare: { baselineMode: this.hubShadowCompareConfig.baselineMode } }
1275
+ : {})
1175
1276
  },
1176
1277
  payload
1177
1278
  };
@@ -1187,6 +1288,156 @@ export class RouteCodexHttpServer {
1187
1288
  const derivedRequestId = typeof resultRecord.requestId === 'string'
1188
1289
  ? resultRecord.requestId
1189
1290
  : input.requestId;
1291
+ const llmsEngineShadowEnabled = !isInternalFollowup &&
1292
+ isLlmsEngineShadowEnabledForSubpath(this.llmsEngineShadowConfig, 'conversion/hub/pipeline');
1293
+ if (llmsEngineShadowEnabled) {
1294
+ // Fail fast: if shadow is enabled for this module, engine core must be available.
1295
+ await this.ensureHubPipelineEngineShadow();
1296
+ }
1297
+ const wantsLlmsEngineShadow = llmsEngineShadowEnabled &&
1298
+ shouldRunLlmsEngineShadowForSubpath(this.llmsEngineShadowConfig, 'conversion/hub/pipeline');
1299
+ // Unified Hub Framework V1: runtime black-box shadow compare (baseline policy vs current policy).
1300
+ // - baseline payload is computed in the SAME hub pipeline execution (single-pass)
1301
+ // - only writes errorsample when diff exists
1302
+ try {
1303
+ const shadow = result.metadata?.hubShadowCompare;
1304
+ const baselineProviderPayload = shadow && typeof shadow === 'object' && !Array.isArray(shadow)
1305
+ ? shadow.baselineProviderPayload
1306
+ : undefined;
1307
+ if (wantsShadowCompare && baselineProviderPayload && typeof baselineProviderPayload === 'object') {
1308
+ const entryEndpoint = String(input.entryEndpoint || '/v1/chat/completions');
1309
+ const routeHint = typeof metadata.routeHint === 'string'
1310
+ ? String(metadata.routeHint)
1311
+ : undefined;
1312
+ const excludedProviderKeys = Array.isArray(metadata.excludedProviderKeys)
1313
+ ? metadata.excludedProviderKeys
1314
+ : [];
1315
+ const cloneJsonSafe = (value) => {
1316
+ try {
1317
+ return JSON.parse(JSON.stringify(value));
1318
+ }
1319
+ catch {
1320
+ return value;
1321
+ }
1322
+ };
1323
+ const candidateOut = {
1324
+ providerPayload: cloneJsonSafe(result.providerPayload),
1325
+ target: cloneJsonSafe(result.target),
1326
+ metadata: {
1327
+ entryEndpoint: result.metadata?.entryEndpoint,
1328
+ providerProtocol: result.metadata?.providerProtocol,
1329
+ processMode: result.metadata?.processMode,
1330
+ stream: result.metadata?.stream,
1331
+ routeHint: result.metadata?.routeHint
1332
+ }
1333
+ };
1334
+ void (async () => {
1335
+ try {
1336
+ const baselineOut = {
1337
+ providerPayload: cloneJsonSafe(baselineProviderPayload),
1338
+ target: shadow && typeof shadow === 'object' && !Array.isArray(shadow) && shadow.baselineTarget
1339
+ ? cloneJsonSafe(shadow.baselineTarget)
1340
+ : cloneJsonSafe(result.target),
1341
+ metadata: {
1342
+ entryEndpoint: result.metadata?.entryEndpoint,
1343
+ providerProtocol: result.metadata?.providerProtocol,
1344
+ processMode: result.metadata?.processMode,
1345
+ stream: result.metadata?.stream,
1346
+ routeHint: result.metadata?.routeHint
1347
+ }
1348
+ };
1349
+ await recordHubShadowCompareDiff({
1350
+ requestId: derivedRequestId,
1351
+ entryEndpoint,
1352
+ routeHint,
1353
+ excludedProviderKeys,
1354
+ baselineMode: this.hubShadowCompareConfig.baselineMode,
1355
+ candidateMode: typeof shadow?.candidateMode === 'string' ? shadow.candidateMode : (this.hubPolicyMode ?? undefined),
1356
+ baselineOut,
1357
+ candidateOut
1358
+ });
1359
+ }
1360
+ catch (error) {
1361
+ // eslint-disable-next-line no-console
1362
+ console.error('[unified-hub-shadow-runtime] baseline compare failed:', error);
1363
+ }
1364
+ })();
1365
+ }
1366
+ }
1367
+ catch {
1368
+ // best-effort only
1369
+ }
1370
+ // llms-engine: runtime black-box shadow compare (TS vs engine) for hub pipeline.
1371
+ if (wantsLlmsEngineShadow) {
1372
+ const cloneJsonSafe = (value) => {
1373
+ try {
1374
+ return JSON.parse(JSON.stringify(value));
1375
+ }
1376
+ catch {
1377
+ return value;
1378
+ }
1379
+ };
1380
+ const entryEndpoint = String(input.entryEndpoint || '/v1/chat/completions');
1381
+ const routeHint = typeof metadata.routeHint === 'string'
1382
+ ? String(metadata.routeHint)
1383
+ : undefined;
1384
+ const baselineOut = {
1385
+ providerPayload: cloneJsonSafe(result.providerPayload),
1386
+ target: cloneJsonSafe(result.target),
1387
+ metadata: {
1388
+ entryEndpoint: result.metadata?.entryEndpoint,
1389
+ providerProtocol: result.metadata?.providerProtocol,
1390
+ processMode: result.metadata?.processMode,
1391
+ stream: result.metadata?.stream,
1392
+ routeHint: result.metadata?.routeHint
1393
+ }
1394
+ };
1395
+ void (async () => {
1396
+ try {
1397
+ const shadowPipeline = await this.ensureHubPipelineEngineShadow();
1398
+ const shadowRequestId = `${input.requestId}__llms_engine_shadow`;
1399
+ const baseMeta = pipelineInput.metadata;
1400
+ const shadowInput = {
1401
+ ...pipelineInput,
1402
+ id: shadowRequestId,
1403
+ endpoint: input.entryEndpoint,
1404
+ metadata: {
1405
+ ...(baseMeta && typeof baseMeta === 'object' ? baseMeta : {}),
1406
+ __llmsEngineShadow: { baselineRequestId: derivedRequestId, entryEndpoint, routeHint }
1407
+ },
1408
+ payload: cloneJsonSafe(payload)
1409
+ };
1410
+ const shadowResult = await shadowPipeline.execute(shadowInput);
1411
+ if (!shadowResult?.providerPayload || !shadowResult?.target) {
1412
+ return;
1413
+ }
1414
+ const candidateOut = {
1415
+ providerPayload: cloneJsonSafe(shadowResult.providerPayload),
1416
+ target: cloneJsonSafe(shadowResult.target),
1417
+ metadata: {
1418
+ entryEndpoint: shadowResult.metadata?.entryEndpoint,
1419
+ providerProtocol: shadowResult.metadata?.providerProtocol,
1420
+ processMode: shadowResult.metadata?.processMode,
1421
+ stream: shadowResult.metadata?.stream,
1422
+ routeHint: shadowResult.metadata?.routeHint
1423
+ }
1424
+ };
1425
+ await recordLlmsEngineShadowDiff({
1426
+ group: 'hub-pipeline',
1427
+ requestId: derivedRequestId,
1428
+ subpath: 'conversion/hub/pipeline',
1429
+ baselineImpl: 'ts',
1430
+ candidateImpl: 'engine',
1431
+ baselineOut,
1432
+ candidateOut
1433
+ });
1434
+ }
1435
+ catch (error) {
1436
+ // eslint-disable-next-line no-console
1437
+ console.error('[llms-engine-shadow] hub pipeline shadow failed:', error);
1438
+ }
1439
+ })();
1440
+ }
1190
1441
  return {
1191
1442
  requestId: derivedRequestId,
1192
1443
  providerPayload: result.providerPayload,
@@ -1209,6 +1460,8 @@ export class RouteCodexHttpServer {
1209
1460
  : inboundOriginator;
1210
1461
  const routeHint = this.extractRouteHint(input) ?? userMeta.routeHint;
1211
1462
  const processMode = userMeta.processMode || 'chat';
1463
+ const runtimeFromUser = asRecord(userMeta.runtime);
1464
+ const llmsVersion = resolveLlmswitchCoreVersion();
1212
1465
  const metadata = {
1213
1466
  ...userMeta,
1214
1467
  entryEndpoint: input.entryEndpoint,
@@ -1217,6 +1470,15 @@ export class RouteCodexHttpServer {
1217
1470
  stage: 'inbound',
1218
1471
  routeHint,
1219
1472
  stream: userMeta.stream === true,
1473
+ runtime: {
1474
+ ...(runtimeFromUser ?? {}),
1475
+ routecodex: {
1476
+ version: buildInfo.version,
1477
+ mode: buildInfo.mode
1478
+ },
1479
+ llmswitchCore: llmsVersion ? { version: llmsVersion } : undefined,
1480
+ node: { version: process.version }
1481
+ },
1220
1482
  ...(resolvedUserAgent ? { userAgent: resolvedUserAgent } : {}),
1221
1483
  ...(resolvedOriginator ? { clientOriginator: resolvedOriginator } : {})
1222
1484
  };
@@ -1244,19 +1506,12 @@ export class RouteCodexHttpServer {
1244
1506
  }
1245
1507
  // 在 Host 入口统一解析会话标识,后续 HubPipeline / servertool 等模块仅依赖
1246
1508
  // sessionId / conversationId 字段,不再重复解析 clientHeaders。
1247
- try {
1248
- // eslint-disable-next-line @typescript-eslint/no-var-requires
1249
- const { extractSessionIdentifiersFromMetadata } = require('../../../../sharedmodule/llmswitch-core/dist/conversion/hub/pipeline/session-identifiers.js');
1250
- const identifiers = extractSessionIdentifiersFromMetadata(metadata);
1251
- if (identifiers.sessionId) {
1252
- metadata.sessionId = identifiers.sessionId;
1253
- }
1254
- if (identifiers.conversationId) {
1255
- metadata.conversationId = identifiers.conversationId;
1256
- }
1509
+ const identifiers = extractSessionIdentifiersFromMetadata(metadata);
1510
+ if (identifiers.sessionId) {
1511
+ metadata.sessionId = identifiers.sessionId;
1257
1512
  }
1258
- catch {
1259
- // best-effort:解析失败时不影响主流程
1513
+ if (identifiers.conversationId) {
1514
+ metadata.conversationId = identifiers.conversationId;
1260
1515
  }
1261
1516
  return metadata;
1262
1517
  }
@@ -1468,7 +1723,6 @@ export class RouteCodexHttpServer {
1468
1723
  const reenterPipeline = async (reenterOpts) => {
1469
1724
  const nestedEntry = reenterOpts.entryEndpoint || options.entryEndpoint || entry;
1470
1725
  const nestedExtra = asRecord(reenterOpts.metadata) ?? {};
1471
- const nestedEntryLower = nestedEntry.toLowerCase();
1472
1726
  // 基于首次 HubPipeline metadata + 调用方注入的 metadata 构建新的请求 metadata。
1473
1727
  // 不在 Host 层编码 servertool/web_search 等语义,由 llmswitch-core 负责。
1474
1728
  const nestedMetadata = {
@@ -1484,22 +1738,6 @@ export class RouteCodexHttpServer {
1484
1738
  delete nestedMetadata.clientHeaders;
1485
1739
  delete nestedMetadata.clientRequestId;
1486
1740
  }
1487
- // 针对 reenterPipeline 的入口端点,纠正 providerProtocol,避免沿用外层协议。
1488
- if (nestedEntryLower.includes('/v1/chat/completions')) {
1489
- nestedMetadata.providerProtocol = 'openai-chat';
1490
- }
1491
- else if (nestedEntryLower.includes('/v1/responses')) {
1492
- nestedMetadata.providerProtocol = 'openai-responses';
1493
- }
1494
- else if (nestedEntryLower.includes('/v1/messages')) {
1495
- nestedMetadata.providerProtocol = 'anthropic-messages';
1496
- }
1497
- const followupProtocol = typeof nestedExtra.serverToolFollowupProtocol === 'string'
1498
- ? nestedExtra.serverToolFollowupProtocol
1499
- : undefined;
1500
- if (followupProtocol) {
1501
- nestedMetadata.providerProtocol = followupProtocol;
1502
- }
1503
1741
  const nestedInput = {
1504
1742
  entryEndpoint: nestedEntry,
1505
1743
  method: 'POST',