@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
@@ -1,146 +1,42 @@
1
- import { countRequestTokens } from './token-counter.js';
1
+ import { detectExtendedThinkingKeyword, detectImageAttachment, detectKeyword, extractMessageText, getLatestMessageRole, getLatestUserMessage } from './message-utils.js';
2
+ import { detectCodingTool, detectLastAssistantToolCategory, detectVisionTool, detectWebTool, extractMeaningfulDeclaredToolNames } from './tool-signals.js';
3
+ import { computeRequestTokens } from './token-estimator.js';
2
4
  const THINKING_KEYWORDS = ['let me think', 'chain of thought', 'cot', 'reason step', 'deliberate'];
3
- const WEB_TOOL_KEYWORDS = ['websearch', 'web_search', 'web-search', 'webfetch', 'web_fetch', 'web_request', 'search_web', 'internet_search'];
4
- const READ_TOOL_EXACT = new Set([
5
- 'read_file',
6
- 'read_text',
7
- 'view_file',
8
- 'view_code',
9
- 'view_document',
10
- 'open_file',
11
- 'get_file',
12
- 'download_file',
13
- 'describe_current_request',
14
- 'list_dir',
15
- 'list_directory',
16
- 'list_files',
17
- 'list_documents',
18
- 'list_resources',
19
- 'search_files',
20
- 'find_files'
21
- ]);
22
- const WRITE_TOOL_EXACT = new Set([
23
- 'apply_patch',
24
- 'write_file',
25
- 'create_file',
26
- 'modify_file',
27
- 'edit_file',
28
- 'update_file',
29
- 'save_file',
30
- 'append_file',
31
- 'replace_file',
32
- 'delete_file',
33
- 'remove_file',
34
- 'rename_file',
35
- 'move_file',
36
- 'copy_file',
37
- 'mkdir',
38
- 'rmdir'
39
- ]);
40
- const SEARCH_TOOL_EXACT = new Set(['websearch', 'web_search', 'search_web', 'internet_search', 'webfetch', 'web_fetch']);
41
- const READ_TOOL_KEYWORDS = ['read', 'list', 'view', 'download', 'open', 'show', 'fetch', 'inspect'];
42
- const WRITE_TOOL_KEYWORDS = ['write', 'patch', 'modify', 'edit', 'create', 'update', 'append', 'replace', 'delete', 'remove'];
43
- const SEARCH_TOOL_KEYWORDS = ['search', 'websearch', 'web_fetch', 'webfetch', 'web-request', 'web_request', 'internet'];
44
- const SHELL_TOOL_NAMES = new Set(['shell_command', 'shell', 'bash']);
45
- const SHELL_HEREDOC_PATTERN = /<<\s*['"]?[a-z0-9_-]+/i;
46
- const SHELL_WRITE_PATTERNS = [
47
- 'apply_patch',
48
- 'sed -i',
49
- 'perl -pi',
50
- 'tee ',
51
- 'cat <<',
52
- 'cat >',
53
- 'printf >',
54
- 'touch ',
55
- 'truncate',
56
- 'mkdir',
57
- 'mktemp',
58
- 'rmdir',
59
- 'rm ',
60
- 'rm-',
61
- 'unlink',
62
- 'mv ',
63
- 'cp ',
64
- 'ln -',
65
- 'chmod',
66
- 'chown',
67
- 'chgrp',
68
- 'tar ',
69
- 'git add',
70
- 'git commit',
71
- 'git apply',
72
- 'git am',
73
- 'git rebase',
74
- 'git checkout',
75
- 'git merge',
76
- 'patch <<',
77
- 'npm install',
78
- 'pnpm install',
79
- 'yarn add',
80
- 'yarn install',
81
- 'pip install',
82
- 'pip3 install',
83
- 'brew install',
84
- 'cargo add',
85
- 'cargo install',
86
- 'go install',
87
- 'make install'
88
- ];
89
- const SHELL_SEARCH_PATTERNS = [
90
- 'rg ',
91
- 'rg-',
92
- 'grep ',
93
- 'grep-',
94
- 'ripgrep',
95
- 'find ',
96
- 'fd ',
97
- 'locate ',
98
- 'search ',
99
- 'ack ',
100
- 'ag ',
101
- 'where ',
102
- 'which ',
103
- 'codesearch'
104
- ];
105
- const SHELL_READ_PATTERNS = [
106
- 'ls',
107
- 'dir ',
108
- 'pwd',
109
- 'cat ',
110
- 'type ',
111
- 'head ',
112
- 'tail ',
113
- 'stat',
114
- 'tree',
115
- 'wc ',
116
- 'du ',
117
- 'printf "',
118
- 'python - <<',
119
- 'python -c',
120
- 'node - <<',
121
- 'node -e'
122
- ];
123
5
  export function buildRoutingFeatures(request, metadata) {
124
6
  const latestUserMessage = getLatestUserMessage(request.messages);
7
+ const latestMessageRole = getLatestMessageRole(request.messages);
125
8
  const assistantMessages = request.messages.filter((msg) => msg.role === 'assistant');
126
9
  const latestUserText = latestUserMessage ? extractMessageText(latestUserMessage) : '';
127
10
  const normalizedUserText = latestUserText.toLowerCase();
128
- const hasTools = Array.isArray(request.tools) && request.tools.length > 0;
11
+ const meaningfulDeclaredTools = extractMeaningfulDeclaredToolNames(request.tools);
12
+ const hasTools = meaningfulDeclaredTools.length > 0;
129
13
  const hasToolCallResponses = assistantMessages.some((msg) => Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0);
130
14
  const estimatedTokens = computeRequestTokens(request, latestUserText);
131
15
  const hasThinking = detectKeyword(normalizedUserText, THINKING_KEYWORDS);
132
16
  const hasVisionTool = detectVisionTool(request);
133
- const hasImageAttachment = hasVisionTool && detectImageAttachment(latestUserMessage);
17
+ const hasImageAttachment = detectImageAttachment(latestUserMessage);
134
18
  const hasCodingTool = detectCodingTool(request);
135
19
  const hasWebTool = detectWebTool(request);
136
20
  const hasThinkingKeyword = hasThinking || detectExtendedThinkingKeyword(normalizedUserText);
137
21
  const lastAssistantTool = detectLastAssistantToolCategory(assistantMessages);
22
+ const lastAssistantToolLabel = (() => {
23
+ if (!lastAssistantTool) {
24
+ return undefined;
25
+ }
26
+ if (lastAssistantTool.commandSnippet && lastAssistantTool.commandSnippet.trim()) {
27
+ return lastAssistantTool.commandSnippet.trim();
28
+ }
29
+ if (lastAssistantTool.name && lastAssistantTool.name.trim()) {
30
+ return lastAssistantTool.name.trim();
31
+ }
32
+ return undefined;
33
+ })();
138
34
  return {
139
35
  requestId: metadata.requestId,
140
36
  model: request.model,
141
37
  totalMessages: request.messages?.length ?? 0,
142
38
  userTextSample: latestUserText.slice(0, 2000),
143
- toolCount: request.tools?.length ?? 0,
39
+ toolCount: meaningfulDeclaredTools.length,
144
40
  hasTools,
145
41
  hasToolCallResponses,
146
42
  hasVisionTool,
@@ -150,342 +46,11 @@ export function buildRoutingFeatures(request, metadata) {
150
46
  hasThinkingKeyword,
151
47
  estimatedTokens,
152
48
  lastAssistantToolCategory: lastAssistantTool?.category,
153
- lastAssistantToolName: lastAssistantTool?.name,
49
+ lastAssistantToolSnippet: lastAssistantTool?.commandSnippet,
50
+ lastAssistantToolLabel,
51
+ latestMessageFromUser: latestMessageRole === 'user',
154
52
  metadata: {
155
53
  ...metadata
156
54
  }
157
55
  };
158
56
  }
159
- function getLatestUserMessage(messages) {
160
- for (let idx = messages.length - 1; idx >= 0; idx -= 1) {
161
- if (messages[idx]?.role === 'user') {
162
- return messages[idx];
163
- }
164
- }
165
- return undefined;
166
- }
167
- function extractMessageText(message) {
168
- if (typeof message.content === 'string' && message.content.trim()) {
169
- return message.content;
170
- }
171
- return '';
172
- }
173
- function detectKeyword(text, keywords) {
174
- if (!text)
175
- return false;
176
- return keywords.some((keyword) => text.includes(keyword.toLowerCase()));
177
- }
178
- function detectImageAttachment(message) {
179
- if (!message)
180
- return false;
181
- if (!message.metadata || typeof message.metadata !== 'object') {
182
- return false;
183
- }
184
- const meta = message.metadata;
185
- const attachments = (meta.attachments ?? null);
186
- if (Array.isArray(attachments)) {
187
- return attachments.some((attachment) => {
188
- const candidate = attachment;
189
- const typeValue = typeof candidate.type === 'string' ? candidate.type.toLowerCase() : '';
190
- const urlValue = typeof candidate.url === 'string'
191
- ? candidate.url
192
- : typeof candidate.src === 'string'
193
- ? candidate.src
194
- : typeof candidate.image_url === 'string'
195
- ? candidate.image_url
196
- : typeof candidate.image_url?.url === 'string'
197
- ? candidate.image_url.url
198
- : '';
199
- return typeValue.includes('image') && urlValue.trim().length > 0;
200
- });
201
- }
202
- if (typeof meta.attachmentType === 'string' && meta.attachmentType.toLowerCase().includes('image')) {
203
- const urlCandidate = typeof meta.attachmentUrl === 'string' ? meta.attachmentUrl : '';
204
- return urlCandidate.trim().length > 0;
205
- }
206
- return false;
207
- }
208
- function detectVisionTool(request) {
209
- if (!Array.isArray(request.tools)) {
210
- return false;
211
- }
212
- return request.tools.some((tool) => {
213
- const functionName = extractToolName(tool);
214
- const description = extractToolDescription(tool);
215
- return /vision|image|picture|photo/i.test(functionName) || /vision|image|picture|photo/i.test(description || '');
216
- });
217
- }
218
- function detectCodingTool(request) {
219
- if (!Array.isArray(request.tools)) {
220
- return false;
221
- }
222
- return request.tools.some((tool) => {
223
- const functionName = extractToolName(tool).toLowerCase();
224
- const description = (extractToolDescription(tool) || '').toLowerCase();
225
- if (!functionName && !description) {
226
- return false;
227
- }
228
- if (WRITE_TOOL_EXACT.has(functionName)) {
229
- return true;
230
- }
231
- return WRITE_TOOL_KEYWORDS.some((keyword) => functionName.includes(keyword.toLowerCase()) || description.includes(keyword.toLowerCase()));
232
- });
233
- }
234
- function detectWebTool(request) {
235
- if (!Array.isArray(request.tools)) {
236
- return false;
237
- }
238
- return request.tools.some((tool) => {
239
- const functionName = extractToolName(tool);
240
- const description = extractToolDescription(tool);
241
- const normalizedName = functionName.toLowerCase();
242
- const normalizedDesc = (description || '').toLowerCase();
243
- return (WEB_TOOL_KEYWORDS.some((keyword) => normalizedName.includes(keyword)) ||
244
- WEB_TOOL_KEYWORDS.some((keyword) => normalizedDesc.includes(keyword)));
245
- });
246
- }
247
- function detectExtendedThinkingKeyword(text) {
248
- if (!text) {
249
- return false;
250
- }
251
- const keywords = ['仔细分析', '思考', '超级思考', '深度思考', 'careful analysis', 'deep thinking', 'deliberate'];
252
- return keywords.some((keyword) => text.includes(keyword));
253
- }
254
- function computeRequestTokens(request, fallbackText) {
255
- try {
256
- return countRequestTokens(request);
257
- }
258
- catch {
259
- return fallbackEstimateTokens(fallbackText, request.messages?.length ?? 0);
260
- }
261
- }
262
- function fallbackEstimateTokens(text, messageCount) {
263
- if (!text) {
264
- return Math.max(32, Math.max(messageCount, 1) * 16);
265
- }
266
- const rough = Math.ceil(text.length / 4);
267
- return Math.max(rough, Math.max(messageCount, 1) * 32);
268
- }
269
- function extractToolName(tool) {
270
- if (!tool || typeof tool !== 'object') {
271
- return '';
272
- }
273
- const candidate = tool;
274
- const fromFunction = candidate.function;
275
- if (fromFunction && typeof fromFunction.name === 'string' && fromFunction.name.trim()) {
276
- return fromFunction.name;
277
- }
278
- if (typeof candidate.name === 'string' && candidate.name.trim()) {
279
- return candidate.name;
280
- }
281
- return '';
282
- }
283
- function extractToolDescription(tool) {
284
- if (!tool || typeof tool !== 'object') {
285
- return '';
286
- }
287
- const candidate = tool;
288
- const fromFunction = candidate.function;
289
- if (fromFunction && typeof fromFunction.description === 'string' && fromFunction.description.trim()) {
290
- return fromFunction.description;
291
- }
292
- if (typeof candidate.description === 'string' && candidate.description.trim()) {
293
- return candidate.description;
294
- }
295
- return '';
296
- }
297
- function detectLastAssistantToolCategory(messages) {
298
- for (let idx = messages.length - 1; idx >= 0; idx -= 1) {
299
- const msg = messages[idx];
300
- if (!msg || !Array.isArray(msg.tool_calls) || msg.tool_calls.length === 0) {
301
- continue;
302
- }
303
- let fallback;
304
- for (const call of msg.tool_calls) {
305
- const classification = classifyToolCall(call);
306
- if (!classification) {
307
- continue;
308
- }
309
- if (!fallback) {
310
- fallback = classification;
311
- }
312
- if (classification.category !== 'other') {
313
- return classification;
314
- }
315
- }
316
- if (fallback) {
317
- return fallback;
318
- }
319
- }
320
- return undefined;
321
- }
322
- function classifyToolCall(call) {
323
- if (!call || typeof call !== 'object') {
324
- return undefined;
325
- }
326
- const functionName = typeof call?.function?.name === 'string' && call.function.name.trim()
327
- ? canonicalizeToolName(call.function.name)
328
- : '';
329
- if (!functionName) {
330
- return undefined;
331
- }
332
- const argsObject = parseToolArguments(call?.function?.arguments);
333
- const commandText = extractCommandText(argsObject);
334
- const nameCategory = categorizeToolName(functionName);
335
- if (nameCategory === 'write' || nameCategory === 'read' || nameCategory === 'search') {
336
- return { category: nameCategory, name: functionName };
337
- }
338
- if (SHELL_TOOL_NAMES.has(functionName)) {
339
- const shellCategory = classifyShellCommand(commandText);
340
- return { category: shellCategory, name: functionName };
341
- }
342
- if (commandText) {
343
- const derivedCategory = classifyShellCommand(commandText);
344
- if (derivedCategory !== 'other') {
345
- return { category: derivedCategory, name: functionName };
346
- }
347
- }
348
- return { category: 'other', name: functionName };
349
- }
350
- function canonicalizeToolName(rawName) {
351
- const trimmed = rawName.trim();
352
- const markerIndex = trimmed.indexOf('arg_');
353
- if (markerIndex > 0) {
354
- return trimmed.slice(0, markerIndex);
355
- }
356
- return trimmed;
357
- }
358
- function parseToolArguments(rawArguments) {
359
- if (!rawArguments) {
360
- return undefined;
361
- }
362
- if (typeof rawArguments === 'string') {
363
- try {
364
- return JSON.parse(rawArguments);
365
- }
366
- catch {
367
- return rawArguments;
368
- }
369
- }
370
- if (typeof rawArguments === 'object') {
371
- return rawArguments;
372
- }
373
- return undefined;
374
- }
375
- function extractCommandText(args) {
376
- if (!args) {
377
- return '';
378
- }
379
- if (typeof args === 'string') {
380
- return args;
381
- }
382
- if (Array.isArray(args)) {
383
- return args.map((item) => (typeof item === 'string' ? item : '')).filter(Boolean).join(' ');
384
- }
385
- if (typeof args === 'object') {
386
- const record = args;
387
- const command = record.command;
388
- const input = record.input;
389
- const nestedArgs = record.args;
390
- if (typeof command === 'string') {
391
- return command;
392
- }
393
- if (Array.isArray(command)) {
394
- return command.map((item) => (typeof item === 'string' ? item : '')).filter(Boolean).join(' ');
395
- }
396
- if (typeof input === 'string') {
397
- return input;
398
- }
399
- if (typeof nestedArgs === 'string') {
400
- return nestedArgs;
401
- }
402
- if (Array.isArray(nestedArgs)) {
403
- return nestedArgs.map((item) => (typeof item === 'string' ? item : '')).filter(Boolean).join(' ');
404
- }
405
- }
406
- return '';
407
- }
408
- function categorizeToolName(name) {
409
- const normalized = name.toLowerCase();
410
- if (SEARCH_TOOL_EXACT.has(normalized) ||
411
- SEARCH_TOOL_KEYWORDS.some((keyword) => normalized.includes(keyword.toLowerCase()))) {
412
- return 'search';
413
- }
414
- if (READ_TOOL_EXACT.has(normalized) ||
415
- READ_TOOL_KEYWORDS.some((keyword) => normalized.includes(keyword.toLowerCase()))) {
416
- return 'read';
417
- }
418
- if (WRITE_TOOL_EXACT.has(normalized) ||
419
- WRITE_TOOL_KEYWORDS.some((keyword) => normalized.includes(keyword.toLowerCase()))) {
420
- return 'write';
421
- }
422
- return 'other';
423
- }
424
- function classifyShellCommand(command) {
425
- if (!command) {
426
- return 'other';
427
- }
428
- if (SHELL_HEREDOC_PATTERN.test(command)) {
429
- return 'write';
430
- }
431
- const segments = splitCommandSegments(command).map(stripShellWrapper);
432
- if (segments.some((segment) => matchesAnyPattern(segment, SHELL_WRITE_PATTERNS))) {
433
- return 'write';
434
- }
435
- if (segments.some((segment) => matchesAnyPattern(segment, SHELL_SEARCH_PATTERNS))) {
436
- return 'search';
437
- }
438
- if (segments.some((segment) => matchesAnyPattern(segment, SHELL_READ_PATTERNS))) {
439
- return 'read';
440
- }
441
- const stripped = stripShellWrapper(command);
442
- if (matchesAnyPattern(stripped, SHELL_WRITE_PATTERNS)) {
443
- return 'write';
444
- }
445
- if (matchesAnyPattern(stripped, SHELL_SEARCH_PATTERNS)) {
446
- return 'search';
447
- }
448
- if (matchesAnyPattern(stripped, SHELL_READ_PATTERNS)) {
449
- return 'read';
450
- }
451
- return 'other';
452
- }
453
- function splitCommandSegments(command) {
454
- return command
455
- .split(/(?:\r?\n|&&|\|\||;)/)
456
- .map((segment) => segment.trim())
457
- .filter(Boolean);
458
- }
459
- function matchesAnyPattern(text, patterns) {
460
- if (!text) {
461
- return false;
462
- }
463
- const trimmed = text.trim().toLowerCase();
464
- const normalized = trimmed.startsWith('sudo ') ? trimmed.slice(5).trim() : trimmed;
465
- return patterns.some((pattern) => {
466
- const lowered = pattern.toLowerCase().trim();
467
- return normalized.startsWith(lowered);
468
- });
469
- }
470
- function stripShellWrapper(segment) {
471
- let normalized = segment.trim();
472
- const wrappers = ['bash -lc ', 'bash -lc', 'sh -c ', 'sh -c', '/bin/sh -c ', '/bin/sh -c', 'env -i bash -lc ', 'env -i bash -lc'];
473
- for (const wrapper of wrappers) {
474
- if (normalized.toLowerCase().startsWith(wrapper)) {
475
- normalized = normalized.slice(wrapper.length).trim();
476
- break;
477
- }
478
- }
479
- normalized = trimEnclosingQuotes(normalized);
480
- if (normalized.startsWith('sudo ')) {
481
- normalized = normalized.slice(5).trim();
482
- }
483
- return normalized;
484
- }
485
- function trimEnclosingQuotes(value) {
486
- if ((value.startsWith('"') && value.endsWith('"') && value.length > 1) ||
487
- (value.startsWith("'") && value.endsWith("'") && value.length > 1)) {
488
- return value.slice(1, -1).trim();
489
- }
490
- return value;
491
- }
@@ -35,13 +35,8 @@ export class ProviderHealthManager {
35
35
  if (reason) {
36
36
  state.reason = reason;
37
37
  }
38
- if (state.failureCount >= this.config.failureThreshold) {
39
- state.state = 'tripped';
40
- state.cooldownExpiresAt = Date.now() + this.config.cooldownMs;
41
- if (reason) {
42
- state.reason = reason;
43
- }
44
- }
38
+ // 在新版策略中,普通失败仅用于监控;不再根据 failureThreshold 自动熔断。
39
+ // 只有显式 fatal 或 tripProvider 调用时才会进入 tripped 状态。
45
40
  return state;
46
41
  }
47
42
  recordSuccess(providerKey) {
@@ -0,0 +1,7 @@
1
+ import type { StandardizedMessage } from '../../conversion/hub/types/standardized.js';
2
+ export declare function getLatestUserMessage(messages: StandardizedMessage[]): StandardizedMessage | undefined;
3
+ export declare function getLatestMessageRole(messages: StandardizedMessage[]): string | undefined;
4
+ export declare function extractMessageText(message: StandardizedMessage): string;
5
+ export declare function detectKeyword(text: string, keywords: string[]): boolean;
6
+ export declare function detectExtendedThinkingKeyword(text: string): boolean;
7
+ export declare function detectImageAttachment(message: StandardizedMessage | undefined): boolean;
@@ -0,0 +1,78 @@
1
+ export function getLatestUserMessage(messages) {
2
+ for (let idx = messages.length - 1; idx >= 0; idx -= 1) {
3
+ if (messages[idx]?.role === 'user') {
4
+ return messages[idx];
5
+ }
6
+ }
7
+ return undefined;
8
+ }
9
+ export function getLatestMessageRole(messages) {
10
+ if (!Array.isArray(messages) || !messages.length) {
11
+ return undefined;
12
+ }
13
+ const last = messages[messages.length - 1];
14
+ if (last && typeof last.role === 'string' && last.role.trim()) {
15
+ return last.role.trim();
16
+ }
17
+ return undefined;
18
+ }
19
+ export function extractMessageText(message) {
20
+ if (typeof message.content === 'string' && message.content.trim()) {
21
+ return message.content;
22
+ }
23
+ return '';
24
+ }
25
+ export function detectKeyword(text, keywords) {
26
+ if (!text)
27
+ return false;
28
+ return keywords.some((keyword) => text.includes(keyword.toLowerCase()));
29
+ }
30
+ export function detectExtendedThinkingKeyword(text) {
31
+ if (!text) {
32
+ return false;
33
+ }
34
+ const keywords = ['仔细分析', '思考', '超级思考', '深度思考', 'careful analysis', 'deep thinking', 'deliberate'];
35
+ return keywords.some((keyword) => text.includes(keyword));
36
+ }
37
+ export function detectImageAttachment(message) {
38
+ if (!message)
39
+ return false;
40
+ // 仅基于标准 Chat 语义判断是否携带图片:
41
+ // - content 为数组时查找 { type: 'image' | 'image_url' | 'input_image', ... } 块;
42
+ // - 不再依赖 metadata.attachments,也不再用纯文本关键字或剪贴板标记作为信号。
43
+ if (Array.isArray(message.content)) {
44
+ for (const part of message.content) {
45
+ if (!part || typeof part !== 'object') {
46
+ continue;
47
+ }
48
+ const record = part;
49
+ const typeValue = typeof record.type === 'string' ? record.type.toLowerCase() : '';
50
+ // For chat/standardized content, images may appear as:
51
+ // - { type: "image_url", image_url: { url } }
52
+ // - { type: "image", uri: "...", data: "...", url: "..." }
53
+ // - { type: "input_image", image_url: "data:..." }
54
+ // Treat any non-empty URL/URI/data on an image-* block as a signal.
55
+ let imageCandidate = '';
56
+ if (typeof record.image_url === 'string') {
57
+ imageCandidate = record.image_url ?? '';
58
+ }
59
+ else if (record.image_url &&
60
+ typeof record.image_url?.url === 'string') {
61
+ imageCandidate = record.image_url?.url ?? '';
62
+ }
63
+ else if (typeof record.url === 'string') {
64
+ imageCandidate = record.url ?? '';
65
+ }
66
+ else if (typeof record.uri === 'string') {
67
+ imageCandidate = record.uri ?? '';
68
+ }
69
+ else if (typeof record.data === 'string') {
70
+ imageCandidate = record.data ?? '';
71
+ }
72
+ if (typeValue.includes('image') && imageCandidate.trim().length > 0) {
73
+ return true;
74
+ }
75
+ }
76
+ }
77
+ return false;
78
+ }
@@ -42,7 +42,9 @@ export class ProviderRegistry {
42
42
  runtimeKey: profile.runtimeKey,
43
43
  modelId,
44
44
  processMode: profile.processMode || 'chat',
45
- responsesConfig: profile.responsesConfig
45
+ responsesConfig: profile.responsesConfig,
46
+ streaming: profile.streaming,
47
+ maxContextTokens: profile.maxContextTokens
46
48
  };
47
49
  }
48
50
  static normalizeProfile(key, profile) {
@@ -58,7 +60,10 @@ export class ProviderRegistry {
58
60
  runtimeKey: profile.runtimeKey,
59
61
  modelId,
60
62
  processMode: profile.processMode || 'chat',
61
- responsesConfig: profile.responsesConfig
63
+ responsesConfig: profile.responsesConfig,
64
+ streaming: profile.streaming,
65
+ maxContextTokens: profile.maxContextTokens,
66
+ ...(profile.serverToolsDisabled ? { serverToolsDisabled: true } : {})
62
67
  };
63
68
  }
64
69
  }
@@ -78,11 +78,22 @@ function encodeContent(content, encoder) {
78
78
  total += encodeText(part, encoder);
79
79
  }
80
80
  else if (part && typeof part === 'object') {
81
- if (typeof part.text === 'string') {
82
- total += encodeText(part.text, encoder);
81
+ const record = part;
82
+ const typeValue = typeof record.type === 'string' ? record.type.toLowerCase() : '';
83
+ // Large binary/image payloads (data URIs, base64, etc.) should not
84
+ // dominate context estimation. For image-like blocks, only count a
85
+ // small textual placeholder instead of the full JSON/body.
86
+ if (typeValue.startsWith('image')) {
87
+ const caption = typeof record.caption === 'string' && record.caption.trim().length
88
+ ? record.caption
89
+ : '[image]';
90
+ total += encodeText(caption, encoder);
91
+ }
92
+ else if (typeof record.text === 'string') {
93
+ total += encodeText(record.text, encoder);
83
94
  }
84
95
  else {
85
- total += encodeText(JSON.stringify(part), encoder);
96
+ total += encodeText(JSON.stringify(record), encoder);
86
97
  }
87
98
  }
88
99
  }
@@ -0,0 +1,2 @@
1
+ import type { ProcessedRequest, StandardizedRequest } from '../../conversion/hub/types/standardized.js';
2
+ export declare function computeRequestTokens(request: StandardizedRequest | ProcessedRequest, fallbackText: string): number;
@@ -0,0 +1,16 @@
1
+ import { countRequestTokens } from './token-counter.js';
2
+ export function computeRequestTokens(request, fallbackText) {
3
+ try {
4
+ return countRequestTokens(request);
5
+ }
6
+ catch {
7
+ return fallbackEstimateTokens(fallbackText, request.messages?.length ?? 0);
8
+ }
9
+ }
10
+ function fallbackEstimateTokens(text, messageCount) {
11
+ if (!text) {
12
+ return Math.max(32, Math.max(messageCount, 1) * 16);
13
+ }
14
+ const rough = Math.ceil(text.length / 4);
15
+ return Math.max(rough, Math.max(messageCount, 1) * 32);
16
+ }