@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
@@ -17,6 +17,31 @@ const GENERATION_CONFIG_KEYS = [
17
17
  ];
18
18
  const PASSTHROUGH_METADATA_PREFIX = 'rcc_passthrough_';
19
19
  const PASSTHROUGH_PARAMETERS = ['tool_choice'];
20
+ const DUMMY_THOUGHT_SIGNATURE = 'skip_thought_signature_validator';
21
+ function coerceThoughtSignature(value) {
22
+ if (typeof value === 'string' && value.trim().length) {
23
+ return value.trim();
24
+ }
25
+ return undefined;
26
+ }
27
+ function extractThoughtSignatureFromToolCall(tc) {
28
+ if (!tc || typeof tc !== 'object') {
29
+ return undefined;
30
+ }
31
+ const node = tc;
32
+ const direct = coerceThoughtSignature(node.thought_signature ?? node.thoughtSignature);
33
+ if (direct) {
34
+ return direct;
35
+ }
36
+ const extra = node.extra_content ?? node.extraContent;
37
+ if (extra && typeof extra === 'object') {
38
+ const googleNode = extra.google ?? extra.Google;
39
+ if (googleNode && typeof googleNode === 'object') {
40
+ return coerceThoughtSignature(googleNode.thought_signature ?? googleNode.thoughtSignature);
41
+ }
42
+ }
43
+ return undefined;
44
+ }
20
45
  function normalizeToolOutputs(messages, missing) {
21
46
  const outputs = [];
22
47
  messages.forEach((msg, index) => {
@@ -35,6 +60,37 @@ function normalizeToolOutputs(messages, missing) {
35
60
  });
36
61
  return outputs.length ? outputs : undefined;
37
62
  }
63
+ function synthesizeToolOutputsFromMessages(messages) {
64
+ if (!Array.isArray(messages)) {
65
+ return [];
66
+ }
67
+ const outputs = [];
68
+ for (const message of messages) {
69
+ if (!message || typeof message !== 'object')
70
+ continue;
71
+ if (message.role !== 'assistant')
72
+ continue;
73
+ const toolCalls = Array.isArray(message.tool_calls)
74
+ ? message.tool_calls
75
+ : [];
76
+ for (const call of toolCalls) {
77
+ const callId = typeof call.id === 'string' ? call.id : undefined;
78
+ if (!callId) {
79
+ continue;
80
+ }
81
+ const existing = outputs.find((entry) => entry.tool_call_id === callId);
82
+ if (existing) {
83
+ continue;
84
+ }
85
+ outputs.push({
86
+ tool_call_id: callId,
87
+ content: '',
88
+ name: (call.function && call.function.name) || undefined
89
+ });
90
+ }
91
+ }
92
+ return outputs;
93
+ }
38
94
  function normalizeToolContent(value) {
39
95
  if (typeof value === 'string')
40
96
  return value;
@@ -47,6 +103,30 @@ function normalizeToolContent(value) {
47
103
  return String(value ?? '');
48
104
  }
49
105
  }
106
+ function convertToolMessageToOutput(message) {
107
+ const rawId = (message.tool_call_id ?? message.id);
108
+ const callId = typeof rawId === 'string' && rawId.trim().length ? rawId.trim() : undefined;
109
+ if (!callId) {
110
+ return null;
111
+ }
112
+ return {
113
+ tool_call_id: callId,
114
+ content: normalizeToolContent(message.content),
115
+ name: typeof message.name === 'string' ? message.name : undefined
116
+ };
117
+ }
118
+ function buildFunctionResponseEntry(output) {
119
+ const parsedPayload = safeParseJson(output.content);
120
+ const normalizedPayload = ensureFunctionResponsePayload(cloneAsJsonValue(parsedPayload));
121
+ const part = {
122
+ functionResponse: {
123
+ name: output.name || 'tool',
124
+ id: output.tool_call_id,
125
+ response: normalizedPayload
126
+ }
127
+ };
128
+ return { role: 'user', parts: [part] };
129
+ }
50
130
  function collectSystemSegments(systemInstruction) {
51
131
  if (!systemInstruction)
52
132
  return [];
@@ -91,22 +171,138 @@ function collectParameters(payload) {
91
171
  }
92
172
  return Object.keys(params).length ? params : undefined;
93
173
  }
174
+ function appendChatContentToGeminiParts(message, targetParts) {
175
+ const content = message.content;
176
+ if (typeof content === 'string') {
177
+ const text = content.trim();
178
+ if (text.length) {
179
+ targetParts.push({ text });
180
+ }
181
+ return;
182
+ }
183
+ if (!Array.isArray(content)) {
184
+ return;
185
+ }
186
+ const items = content;
187
+ for (const block of items) {
188
+ if (block == null)
189
+ continue;
190
+ if (typeof block === 'string') {
191
+ const text = block.trim();
192
+ if (text.length) {
193
+ targetParts.push({ text });
194
+ }
195
+ continue;
196
+ }
197
+ if (typeof block !== 'object') {
198
+ const text = String(block);
199
+ if (text.trim().length) {
200
+ targetParts.push({ text: text.trim() });
201
+ }
202
+ continue;
203
+ }
204
+ const record = block;
205
+ const rawType = record.type;
206
+ const type = typeof rawType === 'string' ? rawType.toLowerCase() : '';
207
+ // Text-style blocks
208
+ if (!type || type === 'text') {
209
+ const textValue = typeof record.text === 'string'
210
+ ? record.text
211
+ : typeof record.content === 'string'
212
+ ? record.content
213
+ : '';
214
+ const text = textValue.trim();
215
+ if (text.length) {
216
+ targetParts.push({ text });
217
+ }
218
+ continue;
219
+ }
220
+ // Image-style blocks -> Gemini inlineData
221
+ if (type === 'image' || type === 'image_url') {
222
+ // Prefer OpenAI-style image_url.url, but also accept uri/url/data.
223
+ let url;
224
+ const imageUrlRaw = record.image_url;
225
+ if (typeof imageUrlRaw === 'string') {
226
+ url = imageUrlRaw;
227
+ }
228
+ else if (imageUrlRaw && typeof imageUrlRaw === 'object' && typeof imageUrlRaw.url === 'string') {
229
+ url = imageUrlRaw.url;
230
+ }
231
+ else if (typeof record.uri === 'string') {
232
+ url = record.uri;
233
+ }
234
+ else if (typeof record.url === 'string') {
235
+ url = record.url;
236
+ }
237
+ else if (typeof record.data === 'string') {
238
+ url = record.data;
239
+ }
240
+ const trimmed = (url ?? '').trim();
241
+ if (!trimmed.length) {
242
+ // Fallback: at least emit a textual marker so内容不会完全丢失
243
+ targetParts.push({ text: '[image]' });
244
+ continue;
245
+ }
246
+ let mimeType;
247
+ let data;
248
+ // data:URL → inlineData { mimeType, data }
249
+ if (trimmed.startsWith('data:')) {
250
+ const match = /^data:([^;,]+)?(?:;base64)?,(.*)$/s.exec(trimmed);
251
+ if (match) {
252
+ mimeType = (match[1] || '').trim() || undefined;
253
+ data = match[2] || '';
254
+ }
255
+ }
256
+ if (data && data.trim().length) {
257
+ const inline = {
258
+ inlineData: {
259
+ data: data.trim()
260
+ }
261
+ };
262
+ if (mimeType && mimeType.length) {
263
+ inline.inlineData.mimeType = mimeType;
264
+ }
265
+ targetParts.push(inline);
266
+ }
267
+ else {
268
+ // 非 data: URL 暂时作为文本 URL 传递,保持语义可见
269
+ targetParts.push({ text: trimmed });
270
+ }
271
+ continue;
272
+ }
273
+ // 默认:回退为文本 JSON 表示,避免静默丢失内容
274
+ try {
275
+ const jsonText = JSON.stringify(record);
276
+ if (jsonText.trim().length) {
277
+ targetParts.push({ text: jsonText });
278
+ }
279
+ }
280
+ catch {
281
+ // ignore malformed block
282
+ }
283
+ }
284
+ }
94
285
  function buildGeminiRequestFromChat(chat, metadata) {
95
286
  const contents = [];
287
+ const emittedToolOutputs = new Set();
96
288
  for (const message of chat.messages) {
97
289
  if (!message || typeof message !== 'object')
98
290
  continue;
99
291
  if (message.role === 'system')
100
292
  continue;
101
- if (message.role === 'tool')
293
+ if (message.role === 'tool') {
294
+ const toolOutput = convertToolMessageToOutput(message);
295
+ if (toolOutput) {
296
+ contents.push(buildFunctionResponseEntry(toolOutput));
297
+ emittedToolOutputs.add(toolOutput.tool_call_id);
298
+ }
102
299
  continue;
300
+ }
103
301
  const entry = {
104
302
  role: mapChatRoleToGemini(message.role),
105
303
  parts: []
106
304
  };
107
- if (typeof message.content === 'string' && message.content.trim().length) {
108
- entry.parts.push({ text: message.content });
109
- }
305
+ appendChatContentToGeminiParts(message, entry.parts);
110
306
  const toolCalls = Array.isArray(message.tool_calls) ? message.tool_calls : [];
111
307
  for (const tc of toolCalls) {
112
308
  if (!tc || typeof tc !== 'object')
@@ -131,25 +327,37 @@ function buildGeminiRequestFromChat(chat, metadata) {
131
327
  if (typeof tc.id === 'string') {
132
328
  part.functionCall.id = tc.id;
133
329
  }
330
+ const thoughtSignature = extractThoughtSignatureFromToolCall(tc) ?? DUMMY_THOUGHT_SIGNATURE;
331
+ if (thoughtSignature) {
332
+ part.thoughtSignature = thoughtSignature;
333
+ }
134
334
  entry.parts.push(part);
135
335
  }
136
336
  if (entry.parts.length) {
137
337
  contents.push(entry);
138
338
  }
139
339
  }
340
+ const toolOutputMap = new Map();
140
341
  if (Array.isArray(chat.toolOutputs)) {
141
- for (const output of chat.toolOutputs) {
142
- const response = cloneAsJsonValue(safeParseJson(output.content));
143
- const part = {
144
- functionResponse: {
145
- name: output.name || 'tool',
146
- id: output.tool_call_id,
147
- response
148
- }
149
- };
150
- contents.push({ role: 'user', parts: [part] });
342
+ for (const entry of chat.toolOutputs) {
343
+ if (entry && typeof entry.tool_call_id === 'string' && entry.tool_call_id.trim().length) {
344
+ toolOutputMap.set(entry.tool_call_id.trim(), entry);
345
+ }
346
+ }
347
+ }
348
+ if (toolOutputMap.size === 0) {
349
+ const syntheticOutputs = synthesizeToolOutputsFromMessages(chat.messages);
350
+ for (const output of syntheticOutputs) {
351
+ toolOutputMap.set(output.tool_call_id, output);
151
352
  }
152
353
  }
354
+ for (const output of toolOutputMap.values()) {
355
+ if (emittedToolOutputs.has(output.tool_call_id)) {
356
+ continue;
357
+ }
358
+ contents.push(buildFunctionResponseEntry(output));
359
+ emittedToolOutputs.add(output.tool_call_id);
360
+ }
153
361
  const request = {
154
362
  model: chat.parameters?.model || 'models/gemini-pro',
155
363
  contents
@@ -235,6 +443,25 @@ function safeParseJson(value) {
235
443
  return value;
236
444
  }
237
445
  }
446
+ function ensureFunctionResponsePayload(value) {
447
+ // Gemini function_response.response 字段在 CloudCode/Gemini CLI 协议里对应的是
448
+ // protobuf Struct(JSON object),而不是顶层数组。
449
+ // 这里做一层规范化:
450
+ // - 对象:直接透传;
451
+ // - 数组:包一层 { result: [...] } 避免把数组作为 Struct 根节点;
452
+ // - 原始值:包一层 { result: value },并把 undefined 映射为 null。
453
+ if (value && typeof value === 'object') {
454
+ if (Array.isArray(value)) {
455
+ return {
456
+ result: value
457
+ };
458
+ }
459
+ return value;
460
+ }
461
+ return {
462
+ result: value === undefined ? null : value
463
+ };
464
+ }
238
465
  function cloneAsJsonValue(value) {
239
466
  try {
240
467
  return JSON.parse(JSON.stringify(value ?? null));
@@ -148,6 +148,20 @@ function serializeSystemContent(message) {
148
148
  }
149
149
  return undefined;
150
150
  }
151
+ function mergeMetadata(a, b) {
152
+ if (!a && !b) {
153
+ return undefined;
154
+ }
155
+ if (!a && b) {
156
+ return jsonClone(b);
157
+ }
158
+ if (a && !b) {
159
+ return jsonClone(a);
160
+ }
161
+ const left = jsonClone(a);
162
+ const right = jsonClone(b);
163
+ return { ...left, ...right };
164
+ }
151
165
  export class ResponsesSemanticMapper {
152
166
  async toChat(format, ctx) {
153
167
  const payload = format.payload || {};
@@ -209,13 +223,15 @@ export class ResponsesSemanticMapper {
209
223
  .map(message => serializeSystemContent(message))
210
224
  .filter((content) => typeof content === 'string' && content.length > 0);
211
225
  const capturedContext = chat.metadata?.responsesContext;
226
+ const envelopeMetadata = chat.metadata && isJsonObject(chat.metadata) ? chat.metadata : undefined;
212
227
  const responsesContext = isJsonObject(capturedContext)
213
228
  ? {
214
229
  ...capturedContext,
230
+ metadata: mergeMetadata(capturedContext.metadata, envelopeMetadata),
215
231
  originalSystemMessages
216
232
  }
217
233
  : {
218
- metadata: (chat.metadata && isJsonObject(chat.metadata) ? chat.metadata : undefined),
234
+ metadata: envelopeMetadata,
219
235
  originalSystemMessages
220
236
  };
221
237
  const responsesResult = buildResponsesRequestFromChat(requestShape, responsesContext);
@@ -60,6 +60,20 @@ export function standardizedToChatEnvelope(request, options) {
60
60
  const metadata = {
61
61
  context: adapterContext
62
62
  };
63
+ const sourceMeta = (request.metadata && typeof request.metadata === 'object'
64
+ ? request.metadata
65
+ : undefined);
66
+ if (sourceMeta) {
67
+ if (sourceMeta.webSearch && typeof sourceMeta.webSearch === 'object') {
68
+ metadata.webSearch = sourceMeta.webSearch;
69
+ }
70
+ if (sourceMeta.forceWebSearch === true) {
71
+ metadata.forceWebSearch = true;
72
+ }
73
+ if (sourceMeta.forceVision === true) {
74
+ metadata.forceVision = true;
75
+ }
76
+ }
63
77
  if (typeof adapterContext.toolCallIdStyle === 'string' && adapterContext.toolCallIdStyle.length) {
64
78
  metadata.toolCallIdStyle = adapterContext.toolCallIdStyle;
65
79
  }
@@ -65,6 +65,7 @@ export interface StandardizedMetadata {
65
65
  providerType?: string;
66
66
  processMode?: 'chat' | 'passthrough';
67
67
  routeHint?: string;
68
+ webSearchEnabled?: boolean;
68
69
  [key: string]: unknown;
69
70
  }
70
71
  export interface StandardizedRequest {
@@ -0,0 +1,6 @@
1
+ import type { ResponsesRequestContext } from './responses-openai-bridge.js';
2
+ export interface ResponsesHostPolicyResult {
3
+ shouldStripHostManagedFields: boolean;
4
+ targetProtocol: string;
5
+ }
6
+ export declare function evaluateResponsesHostPolicy(context?: ResponsesRequestContext, targetProtocol?: string): ResponsesHostPolicyResult;
@@ -0,0 +1,14 @@
1
+ export function evaluateResponsesHostPolicy(context, targetProtocol) {
2
+ const protocol = typeof targetProtocol === 'string' && targetProtocol.trim()
3
+ ? targetProtocol
4
+ : (typeof context?.targetProtocol === 'string' && context.targetProtocol.trim()
5
+ ? context.targetProtocol
6
+ : 'responses');
7
+ const normalized = protocol.toLowerCase();
8
+ const shouldStrip = normalized !== 'openai-responses' &&
9
+ normalized !== 'responses';
10
+ return {
11
+ shouldStripHostManagedFields: shouldStrip,
12
+ targetProtocol: normalized
13
+ };
14
+ }
@@ -1,4 +1,5 @@
1
1
  import { ensureBridgeInstructions } from '../shared/bridge-instructions.js';
2
+ import { evaluateResponsesHostPolicy } from './responses-host-policy.js';
2
3
  import { convertMessagesToBridgeInput, convertBridgeInputToChatMessages } from '../shared/bridge-message-utils.js';
3
4
  import { createToolCallIdTransformer, enforceToolCallIdStyle, resolveToolCallIdStyle, stripInternalToolingMetadata, sanitizeResponsesFunctionName } from '../shared/responses-tool-utils.js';
4
5
  import { mapBridgeToolsToChat, mapChatToolsToBridge } from '../shared/tool-mapping.js';
@@ -8,6 +9,7 @@ import { normalizeMessageReasoningTools } from '../shared/reasoning-tool-normali
8
9
  import { createBridgeActionState, runBridgeActionPipeline } from '../shared/bridge-actions.js';
9
10
  import { resolveBridgePolicy, resolvePolicyActions } from '../shared/bridge-policies.js';
10
11
  import { buildResponsesOutputFromChat } from '../shared/responses-output-builder.js';
12
+ import { consumeResponsesPayloadSnapshot, consumeResponsesPassthrough } from '../shared/responses-reasoning-registry.js';
11
13
  function isObject(v) {
12
14
  return !!v && typeof v === 'object' && !Array.isArray(v);
13
15
  }
@@ -144,17 +146,96 @@ function normalizeBridgeHistory(seed) {
144
146
  originalSystemMessages: systemMessages
145
147
  };
146
148
  }
149
+ function mergeResponsesTools(originalTools, fromChat) {
150
+ const result = [];
151
+ const byKey = new Map();
152
+ const norm = (value) => {
153
+ if (typeof value !== 'string')
154
+ return undefined;
155
+ const trimmed = value.trim();
156
+ return trimmed.length ? trimmed.toLowerCase() : undefined;
157
+ };
158
+ const register = (tool) => {
159
+ const fn = tool.function ?? tool.function;
160
+ const baseName = norm(fn?.name ?? tool.name);
161
+ const typeName = norm(tool.type);
162
+ const key = baseName || typeName;
163
+ if (!key || byKey.has(key))
164
+ return;
165
+ byKey.set(key, tool);
166
+ result.push(tool);
167
+ };
168
+ if (Array.isArray(fromChat)) {
169
+ for (const t of fromChat) {
170
+ if (t && typeof t === 'object') {
171
+ register(t);
172
+ }
173
+ }
174
+ }
175
+ if (Array.isArray(originalTools)) {
176
+ for (const t of originalTools) {
177
+ if (!t || typeof t !== 'object')
178
+ continue;
179
+ const typeName = norm(t.type);
180
+ const isWebSearch = typeName === 'web_search' || (typeof typeName === 'string' && typeName.startsWith('web_search'));
181
+ if (!isWebSearch) {
182
+ // 目前仅恢复原始载荷中的 builtin web_search 工具,其它非函数工具保持忽略,避免意外改变行为。
183
+ continue;
184
+ }
185
+ register(t);
186
+ }
187
+ }
188
+ return result.length ? result : undefined;
189
+ }
147
190
  export function buildResponsesRequestFromChat(payload, ctx, extras) {
148
191
  const chat = unwrapData(payload);
149
192
  const out = {};
193
+ const forceWebSearch = !!ctx &&
194
+ isObject(ctx.metadata) &&
195
+ isObject(ctx.metadata.webSearch) &&
196
+ ctx.metadata.webSearch.force === true;
150
197
  // 基本字段
151
198
  out.model = chat.model;
152
199
  // tools: 反向映射为 ResponsesToolDefinition 形状
153
- const responsesTools = mapChatToolsToBridge(chat.tools, {
200
+ const chatTools = Array.isArray(chat.tools) ? chat.tools : [];
201
+ // 对于 openai-responses upstream,内建 web_search 由官方服务器处理。
202
+ // Chat 侧注入的 server-side web_search 函数(带 engine/query/recency/count)
203
+ // 仅用于非 Responses provider 的 server-tool 回环;在这里构造真正的
204
+ // `/v1/responses` 请求时,需要:
205
+ // 1) 不再把函数版 web_search 透传上游;
206
+ // 2) 若检测到 Chat 侧启用了 web_search 且原始请求中没有 builtin web_search,
207
+ // 则补一个 `{ type: "web_search" }` 内建工具给 OpenAI Responses。
208
+ const hasServerSideWebSearch = !forceWebSearch && chatTools.some((tool) => {
209
+ const fn = tool && typeof tool === 'object' ? tool.function : undefined;
210
+ const name = typeof fn?.name === 'string' ? fn.name.trim().toLowerCase() : '';
211
+ return name === 'web_search';
212
+ });
213
+ const toolsForBridge = hasServerSideWebSearch
214
+ ? chatTools.filter((tool) => {
215
+ const fn = tool && typeof tool === 'object' ? tool.function : undefined;
216
+ const name = typeof fn?.name === 'string' ? fn.name.trim().toLowerCase() : '';
217
+ return name !== 'web_search';
218
+ })
219
+ : chatTools;
220
+ const responsesToolsFromChat = mapChatToolsToBridge(toolsForBridge, {
154
221
  sanitizeName: sanitizeResponsesFunctionName
155
222
  });
156
- if (responsesTools?.length) {
157
- out.tools = responsesTools;
223
+ // Prefer Chat‑normalized tools, but if the original Responses payload carried
224
+ // non‑function tools (such as builtin `web_search`), merge them back so that
225
+ // upstream `/v1/responses` providers see their original tool definitions.
226
+ const originalTools = Array.isArray(ctx?.toolsRaw) ? ctx.toolsRaw : undefined;
227
+ let mergedTools = mergeResponsesTools(originalTools, responsesToolsFromChat);
228
+ if (hasServerSideWebSearch) {
229
+ const normalizeType = (value) => typeof value === 'string' ? value.trim().toLowerCase() : '';
230
+ const hasBuiltinWebSearch = (mergedTools && mergedTools.some((tool) => normalizeType(tool.type) === 'web_search')) ||
231
+ (originalTools && originalTools.some((tool) => normalizeType(tool.type) === 'web_search'));
232
+ if (!hasBuiltinWebSearch) {
233
+ const injected = { type: 'web_search' };
234
+ mergedTools = mergedTools ? [...mergedTools, injected] : [injected];
235
+ }
236
+ }
237
+ if (mergedTools?.length) {
238
+ out.tools = mergedTools;
158
239
  }
159
240
  const passthroughKeys = [
160
241
  'tool_choice',
@@ -257,12 +338,20 @@ export function buildResponsesRequestFromChat(payload, ctx, extras) {
257
338
  else if (metadataExtraFields?.include !== undefined && out.include === undefined) {
258
339
  out.include = metadataExtraFields.include;
259
340
  }
260
- if (ctx?.store !== undefined && out.store === undefined) {
341
+ const stripHostFields = shouldStripHostManagedFields(ctx);
342
+ if (stripHostFields) {
343
+ delete out.store;
344
+ }
345
+ else if (ctx?.store !== undefined && out.store === undefined) {
261
346
  out.store = ctx.store;
262
347
  }
263
348
  else if (metadataExtraFields?.store !== undefined && out.store === undefined) {
264
349
  out.store = metadataExtraFields.store;
265
350
  }
351
+ else if (out.store === undefined) {
352
+ // Chat 入口无 store 概念,但 Responses provider 仍要求显式声明。
353
+ out.store = false;
354
+ }
266
355
  if (ctx?.toolChoice !== undefined && out.tool_choice === undefined) {
267
356
  out.tool_choice = ctx.toolChoice;
268
357
  }
@@ -433,6 +522,17 @@ export function buildResponsesPayloadFromChat(payload, context) {
433
522
  const response = unwrapData(payload);
434
523
  if (!response || typeof response !== 'object')
435
524
  return payload;
525
+ const snapshotKey = resolveSnapshotLookupKey(response, context);
526
+ if (snapshotKey) {
527
+ const passthrough = consumeResponsesPassthrough(snapshotKey);
528
+ if (passthrough) {
529
+ return passthrough;
530
+ }
531
+ const snapshot = consumeResponsesPayloadSnapshot(snapshotKey);
532
+ if (snapshot) {
533
+ return snapshot;
534
+ }
535
+ }
436
536
  if (response.object === 'response' && Array.isArray(response.output)) {
437
537
  return response;
438
538
  }
@@ -499,10 +599,22 @@ export function buildResponsesPayloadFromChat(payload, context) {
499
599
  out.required_action = outputBuild.requiredAction;
500
600
  // Do not inject captured tool results here; keep Chat back-half behavior standard.
501
601
  if (context) {
502
- for (const k of ['metadata', 'parallel_tool_calls', 'tool_choice', 'include', 'store']) {
602
+ for (const k of ['metadata', 'parallel_tool_calls', 'tool_choice', 'include']) {
503
603
  if (context[k] !== undefined)
504
604
  out[k] = context[k];
505
605
  }
606
+ if (!shouldStripHostManagedFields(context) && context.store !== undefined) {
607
+ out.store = context.store;
608
+ }
609
+ }
610
+ if (typeof response.request_id === 'string') {
611
+ out.request_id = response.request_id;
612
+ }
613
+ else if (typeof response.id === 'string') {
614
+ out.request_id = response.id;
615
+ }
616
+ else if (typeof context?.requestId === 'string') {
617
+ out.request_id = context.requestId;
506
618
  }
507
619
  if (out.metadata) {
508
620
  stripInternalToolingMetadata(out.metadata);
@@ -524,6 +636,22 @@ function unwrapData(value) {
524
636
  }
525
637
  return current;
526
638
  }
639
+ function resolveSnapshotLookupKey(response, context) {
640
+ if (typeof response?.request_id === 'string') {
641
+ return response.request_id;
642
+ }
643
+ if (typeof context?.requestId === 'string') {
644
+ return context.requestId;
645
+ }
646
+ if (typeof response?.id === 'string') {
647
+ return response.id;
648
+ }
649
+ return undefined;
650
+ }
651
+ function shouldStripHostManagedFields(context) {
652
+ const result = evaluateResponsesHostPolicy(context, typeof context?.targetProtocol === 'string' ? context?.targetProtocol : undefined);
653
+ return result.shouldStripHostManagedFields;
654
+ }
527
655
  export function extractRequestIdFromResponse(response) {
528
656
  if (response && typeof response === 'object' && 'metadata' in response && response.metadata && typeof response.metadata === 'object') {
529
657
  const meta = response.metadata;