@jsonstudio/rcc 0.89.3 → 0.89.164

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 (270) hide show
  1. package/README.md +240 -179
  2. package/config/modules.json +1 -11
  3. package/dist/build-info.js +2 -2
  4. package/dist/build-info.js.map +1 -1
  5. package/dist/client/gemini-cli/gemini-cli-protocol-client.d.ts +16 -0
  6. package/dist/client/gemini-cli/gemini-cli-protocol-client.js +56 -0
  7. package/dist/client/gemini-cli/gemini-cli-protocol-client.js.map +1 -0
  8. package/dist/client/openai/chat-protocol-client.js.map +1 -1
  9. package/dist/config/modules.json +1 -11
  10. package/dist/core/provider-health-manager.d.ts +17 -0
  11. package/dist/core/provider-health-manager.js +66 -0
  12. package/dist/core/provider-health-manager.js.map +1 -0
  13. package/dist/error-handling/route-error-hub.d.ts +48 -0
  14. package/dist/error-handling/route-error-hub.js +131 -0
  15. package/dist/error-handling/route-error-hub.js.map +1 -0
  16. package/dist/index.js +26 -1
  17. package/dist/index.js.map +1 -1
  18. package/dist/modules/llmswitch/bridge.d.ts +2 -0
  19. package/dist/modules/llmswitch/bridge.js +17 -0
  20. package/dist/modules/llmswitch/bridge.js.map +1 -1
  21. package/dist/modules/pipeline/utils/colored-logger.d.ts +14 -0
  22. package/dist/modules/pipeline/utils/colored-logger.js +48 -0
  23. package/dist/modules/pipeline/utils/colored-logger.js.map +1 -0
  24. package/dist/modules/pipeline/utils/debug-logger.d.ts +2 -0
  25. package/dist/modules/pipeline/utils/debug-logger.js +36 -0
  26. package/dist/modules/pipeline/utils/debug-logger.js.map +1 -1
  27. package/dist/providers/auth/gemini-cli-userinfo-helper.d.ts +53 -0
  28. package/dist/providers/auth/gemini-cli-userinfo-helper.js +152 -0
  29. package/dist/providers/auth/gemini-cli-userinfo-helper.js.map +1 -0
  30. package/dist/providers/auth/oauth-auth.js +3 -2
  31. package/dist/providers/auth/oauth-auth.js.map +1 -1
  32. package/dist/providers/auth/oauth-lifecycle.js +21 -20
  33. package/dist/providers/auth/oauth-lifecycle.js.map +1 -1
  34. package/dist/providers/auth/oauth-logger.d.ts +1 -0
  35. package/dist/providers/auth/oauth-logger.js +21 -0
  36. package/dist/providers/auth/oauth-logger.js.map +1 -0
  37. package/dist/providers/compat/compat-directory-loader.js +2 -55
  38. package/dist/providers/compat/compat-directory-loader.js.map +1 -1
  39. package/dist/providers/compat/compatibility-factory.d.ts +4 -4
  40. package/dist/providers/compat/compatibility-factory.js +108 -0
  41. package/dist/providers/compat/compatibility-factory.js.map +1 -1
  42. package/dist/providers/compat/glm/glm-compatibility.d.ts +2 -2
  43. package/dist/providers/compat/glm/glm-compatibility.js +7 -7
  44. package/dist/providers/compat/glm/glm-compatibility.js.map +1 -1
  45. package/dist/providers/compat/glm/index.js +0 -6
  46. package/dist/providers/compat/glm/index.js.map +1 -1
  47. package/dist/providers/compat/iflow/iflow-compatibility.d.ts +1 -1
  48. package/dist/providers/compat/iflow/iflow-compatibility.js +6 -6
  49. package/dist/providers/compat/iflow/iflow-compatibility.js.map +1 -1
  50. package/dist/providers/compat/index.d.ts +0 -6
  51. package/dist/providers/compat/index.js +0 -7
  52. package/dist/providers/compat/index.js.map +1 -1
  53. package/dist/providers/compat/lmstudio-compatibility.d.ts +2 -2
  54. package/dist/providers/compat/lmstudio-compatibility.js +4 -4
  55. package/dist/providers/compat/lmstudio-compatibility.js.map +1 -1
  56. package/dist/providers/compat/passthrough-compatibility.d.ts +1 -1
  57. package/dist/providers/compat/passthrough-compatibility.js +3 -3
  58. package/dist/providers/compat/passthrough-compatibility.js.map +1 -1
  59. package/dist/providers/compat/profiles/chat/glm/index.d.ts +6 -0
  60. package/dist/providers/compat/profiles/chat/glm/index.js +6 -0
  61. package/dist/providers/compat/profiles/chat/glm/index.js.map +1 -0
  62. package/dist/providers/compat/profiles/chat/iflow/index.d.ts +6 -0
  63. package/dist/providers/compat/profiles/chat/iflow/index.js +6 -0
  64. package/dist/providers/compat/profiles/chat/iflow/index.js.map +1 -0
  65. package/dist/providers/compat/profiles/chat/lmstudio/index.d.ts +6 -0
  66. package/dist/providers/compat/profiles/chat/lmstudio/index.js +6 -0
  67. package/dist/providers/compat/profiles/chat/lmstudio/index.js.map +1 -0
  68. package/dist/providers/compat/profiles/chat/qwen/index.d.ts +6 -0
  69. package/dist/providers/compat/profiles/chat/qwen/index.js +6 -0
  70. package/dist/providers/compat/profiles/chat/qwen/index.js.map +1 -0
  71. package/dist/providers/compat/profiles/compat/passthrough/index.d.ts +6 -0
  72. package/dist/providers/compat/profiles/compat/passthrough/index.js +6 -0
  73. package/dist/providers/compat/profiles/compat/passthrough/index.js.map +1 -0
  74. package/dist/providers/compat/profiles/responses/c4m/index.d.ts +6 -0
  75. package/dist/providers/compat/profiles/responses/c4m/index.js +6 -0
  76. package/dist/providers/compat/profiles/responses/c4m/index.js.map +1 -0
  77. package/dist/providers/compat/profiles/responses/default/index.d.ts +6 -0
  78. package/dist/providers/compat/profiles/responses/default/index.js +6 -0
  79. package/dist/providers/compat/profiles/responses/default/index.js.map +1 -0
  80. package/dist/providers/compat/profiles/responses/fai/index.d.ts +6 -0
  81. package/dist/providers/compat/profiles/responses/fai/index.js +6 -0
  82. package/dist/providers/compat/profiles/responses/fai/index.js.map +1 -0
  83. package/dist/providers/compat/profiles/responses/fc/index.d.ts +6 -0
  84. package/dist/providers/compat/profiles/responses/fc/index.js +6 -0
  85. package/dist/providers/compat/profiles/responses/fc/index.js.map +1 -0
  86. package/dist/providers/compat/qwen/index.js +0 -6
  87. package/dist/providers/compat/qwen/index.js.map +1 -1
  88. package/dist/providers/compat/qwen-compatibility.d.ts +2 -2
  89. package/dist/providers/compat/qwen-compatibility.js +4 -4
  90. package/dist/providers/compat/qwen-compatibility.js.map +1 -1
  91. package/dist/providers/compat/register-compat-module.d.ts +8 -0
  92. package/dist/providers/compat/register-compat-module.js +53 -0
  93. package/dist/providers/compat/register-compat-module.js.map +1 -0
  94. package/dist/providers/compat/responses/c4m-responses-compatibility.d.ts +6 -2
  95. package/dist/providers/compat/responses/c4m-responses-compatibility.js +85 -3
  96. package/dist/providers/compat/responses/c4m-responses-compatibility.js.map +1 -1
  97. package/dist/providers/compat/standard-compatibility-utils.js +45 -15
  98. package/dist/providers/compat/standard-compatibility-utils.js.map +1 -1
  99. package/dist/providers/core/api/provider-config.d.ts +1 -1
  100. package/dist/providers/core/api/provider-types.d.ts +3 -1
  101. package/dist/providers/core/api/provider-types.js +1 -0
  102. package/dist/providers/core/api/provider-types.js.map +1 -1
  103. package/dist/providers/core/config/service-profiles.js +5 -2
  104. package/dist/providers/core/config/service-profiles.js.map +1 -1
  105. package/dist/providers/core/runtime/base-provider.d.ts +3 -0
  106. package/dist/providers/core/runtime/base-provider.js +101 -6
  107. package/dist/providers/core/runtime/base-provider.js.map +1 -1
  108. package/dist/providers/core/runtime/gemini-cli-http-provider.d.ts +34 -0
  109. package/dist/providers/core/runtime/gemini-cli-http-provider.js +152 -0
  110. package/dist/providers/core/runtime/gemini-cli-http-provider.js.map +1 -0
  111. package/dist/providers/core/runtime/http-transport-provider.d.ts +1 -0
  112. package/dist/providers/core/runtime/http-transport-provider.js +178 -123
  113. package/dist/providers/core/runtime/http-transport-provider.js.map +1 -1
  114. package/dist/providers/core/runtime/provider-factory.d.ts +1 -1
  115. package/dist/providers/core/runtime/provider-factory.js +8 -0
  116. package/dist/providers/core/runtime/provider-factory.js.map +1 -1
  117. package/dist/providers/core/runtime/provider-runtime-metadata.d.ts +1 -0
  118. package/dist/providers/core/runtime/provider-runtime-metadata.js.map +1 -1
  119. package/dist/providers/core/runtime/responses-provider.d.ts +7 -0
  120. package/dist/providers/core/runtime/responses-provider.js +228 -12
  121. package/dist/providers/core/runtime/responses-provider.js.map +1 -1
  122. package/dist/providers/core/strategies/oauth-auth-code-flow.js +10 -9
  123. package/dist/providers/core/strategies/oauth-auth-code-flow.js.map +1 -1
  124. package/dist/providers/core/strategies/oauth-device-flow.js +10 -9
  125. package/dist/providers/core/strategies/oauth-device-flow.js.map +1 -1
  126. package/dist/providers/core/utils/provider-error-reporter.js +63 -15
  127. package/dist/providers/core/utils/provider-error-reporter.js.map +1 -1
  128. package/dist/providers/core/utils/provider-type-utils.d.ts +1 -1
  129. package/dist/providers/core/utils/provider-type-utils.js +6 -1
  130. package/dist/providers/core/utils/provider-type-utils.js.map +1 -1
  131. package/dist/providers/core/utils/snapshot-writer.d.ts +10 -0
  132. package/dist/providers/core/utils/snapshot-writer.js +85 -0
  133. package/dist/providers/core/utils/snapshot-writer.js.map +1 -1
  134. package/dist/providers/mock/mock-provider-runtime.js +44 -0
  135. package/dist/providers/mock/mock-provider-runtime.js.map +1 -1
  136. package/dist/providers/profile/provider-profile-loader.js +26 -19
  137. package/dist/providers/profile/provider-profile-loader.js.map +1 -1
  138. package/dist/providers/profile/provider-profile.d.ts +2 -2
  139. package/dist/server/handlers/chat-handler.js +9 -3
  140. package/dist/server/handlers/chat-handler.js.map +1 -1
  141. package/dist/server/handlers/handler-utils.d.ts +7 -1
  142. package/dist/server/handlers/handler-utils.js +64 -52
  143. package/dist/server/handlers/handler-utils.js.map +1 -1
  144. package/dist/server/handlers/messages-handler.js +9 -3
  145. package/dist/server/handlers/messages-handler.js.map +1 -1
  146. package/dist/server/handlers/responses-handler.js +21 -13
  147. package/dist/server/handlers/responses-handler.js.map +1 -1
  148. package/dist/server/runtime/http-server/colored-logger.d.ts +1 -0
  149. package/dist/server/runtime/http-server/colored-logger.js +33 -0
  150. package/dist/server/runtime/http-server/colored-logger.js.map +1 -0
  151. package/dist/server/runtime/http-server/index.d.ts +3 -0
  152. package/dist/server/runtime/http-server/index.js +76 -19
  153. package/dist/server/runtime/http-server/index.js.map +1 -1
  154. package/dist/server/runtime/http-server/provider-utils.d.ts +3 -1
  155. package/dist/server/runtime/http-server/provider-utils.js +12 -2
  156. package/dist/server/runtime/http-server/provider-utils.js.map +1 -1
  157. package/dist/server/runtime/http-server/request-executor.js +6 -2
  158. package/dist/server/runtime/http-server/request-executor.js.map +1 -1
  159. package/dist/server/runtime/http-server/routes.js +31 -11
  160. package/dist/server/runtime/http-server/routes.js.map +1 -1
  161. package/dist/server/runtime/http-server/types.d.ts +2 -1
  162. package/dist/utils/error-center-payload.d.ts +7 -0
  163. package/dist/utils/error-center-payload.js +67 -0
  164. package/dist/utils/error-center-payload.js.map +1 -0
  165. package/dist/utils/error-handler-registry.d.ts +7 -0
  166. package/dist/utils/error-handler-registry.js +44 -12
  167. package/dist/utils/error-handler-registry.js.map +1 -1
  168. package/node_modules/@jsonstudio/llms/dist/conversion/codecs/responses-openai-codec.js +16 -1
  169. package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/chat-glm.json +17 -0
  170. package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/chat-iflow.json +36 -0
  171. package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/chat-lmstudio.json +37 -0
  172. package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/chat-qwen.json +18 -0
  173. package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/responses-c4m.json +45 -0
  174. package/node_modules/@jsonstudio/llms/dist/conversion/config/compat-profiles.json +38 -0
  175. package/node_modules/@jsonstudio/llms/dist/conversion/config/sample-config.json +314 -0
  176. package/node_modules/@jsonstudio/llms/dist/conversion/config/version-switch.json +150 -0
  177. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/compat/compat-engine.d.ts +4 -0
  178. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/compat/compat-engine.js +667 -0
  179. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/compat/compat-profile-store.d.ts +2 -0
  180. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/compat/compat-profile-store.js +76 -0
  181. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/compat/compat-types.d.ts +62 -0
  182. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/compat/compat-types.js +1 -0
  183. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/hub-pipeline.d.ts +2 -0
  184. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/hub-pipeline.js +110 -29
  185. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage3_compat/index.d.ts +14 -0
  186. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage3_compat/index.js +23 -0
  187. package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage1_client_remap/index.js +34 -0
  188. package/node_modules/@jsonstudio/llms/dist/conversion/hub/process/chat-process.js +4 -1
  189. package/node_modules/@jsonstudio/llms/dist/conversion/hub/response/provider-response.js +26 -0
  190. package/node_modules/@jsonstudio/llms/dist/conversion/responses/responses-openai-bridge.d.ts +1 -0
  191. package/node_modules/@jsonstudio/llms/dist/conversion/responses/responses-openai-bridge.js +71 -0
  192. package/node_modules/@jsonstudio/llms/dist/conversion/shared/responses-conversation-store.d.ts +35 -0
  193. package/node_modules/@jsonstudio/llms/dist/conversion/shared/responses-conversation-store.js +64 -19
  194. package/node_modules/@jsonstudio/llms/dist/conversion/shared/tool-filter-pipeline.d.ts +21 -0
  195. package/node_modules/@jsonstudio/llms/dist/conversion/shared/tool-filter-pipeline.js +138 -22
  196. package/node_modules/@jsonstudio/llms/dist/conversion/shared/tool-governor.d.ts +21 -0
  197. package/node_modules/@jsonstudio/llms/dist/conversion/shared/tool-governor.js +116 -1
  198. package/node_modules/@jsonstudio/llms/dist/conversion/shared/tool-mapping.js +52 -2
  199. package/node_modules/@jsonstudio/llms/dist/filters/config/openai-openai.fieldmap.json +18 -0
  200. package/node_modules/@jsonstudio/llms/dist/filters/special/request-tools-normalize.js +20 -1
  201. package/node_modules/@jsonstudio/llms/dist/guidance/index.js +6 -2
  202. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/bootstrap.js +16 -7
  203. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/classifier.js +40 -37
  204. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/default-thinking-keywords.d.ts +1 -0
  205. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/default-thinking-keywords.js +13 -0
  206. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/engine.d.ts +39 -0
  207. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/engine.js +52 -11
  208. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/features.js +340 -11
  209. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/token-counter.d.ts +2 -0
  210. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/token-counter.js +105 -0
  211. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/types.d.ts +8 -0
  212. package/node_modules/@jsonstudio/llms/dist/router/virtual-router/types.js +2 -2
  213. package/node_modules/@jsonstudio/llms/dist/sse/sse-to-json/builders/response-builder.d.ts +2 -0
  214. package/node_modules/@jsonstudio/llms/dist/sse/sse-to-json/builders/response-builder.js +53 -11
  215. package/node_modules/@jsonstudio/llms/dist/test-output/virtual-router/results.json +1 -0
  216. package/node_modules/@jsonstudio/llms/dist/test-output/virtual-router/summary.json +12 -0
  217. package/node_modules/@jsonstudio/llms/dist/tools/tool-registry.js +4 -3
  218. package/node_modules/@jsonstudio/llms/package.json +3 -3
  219. package/package.json +11 -9
  220. package/scripts/analyze-routing-classifier.mjs +166 -0
  221. package/scripts/analyze-routing-samples.mjs +216 -0
  222. package/scripts/analyze-thinking-keywords.mjs +17 -2
  223. package/scripts/build-core.mjs +8 -0
  224. package/scripts/classify-sample-tools.mjs +252 -0
  225. package/scripts/ensure-llmswitch-mode.mjs +95 -0
  226. package/scripts/gen-build-info.mjs +58 -4
  227. package/scripts/install-global.sh +1 -1
  228. package/scripts/install-release.sh +7 -0
  229. package/scripts/mock-provider/run-regressions.mjs +60 -14
  230. package/scripts/tests/apply-patch-loop.mjs +100 -9
  231. package/scripts/tests/golden-provider-cycle.mjs +12 -1
  232. package/scripts/tests/responses-provider-dry-run.mjs +15 -1
  233. package/scripts/tests/virtual-router-health.mjs +12 -5
  234. package/scripts/tools/capture-provider-goldens.mjs +75 -25
  235. package/scripts/tools/responses-golden-dry-run.mjs +17 -1
  236. package/scripts/tools/responses-provider-replay.mjs +17 -1
  237. package/scripts/tools/sync-ci-goldens.mjs +131 -0
  238. package/scripts/verification/samples/openai-chat-list-local-files.json +19 -796
  239. package/scripts/verify-e2e-toolcall.mjs +52 -0
  240. package/dist/providers/compat/config/index.d.ts +0 -1
  241. package/dist/providers/compat/config/index.js +0 -5
  242. package/dist/providers/compat/config/index.js.map +0 -1
  243. package/dist/providers/compat/iflow/index.d.ts +0 -27
  244. package/dist/providers/compat/iflow/index.js +0 -32
  245. package/dist/providers/compat/iflow/index.js.map +0 -1
  246. package/dist/providers/compat/lmstudio/index.d.ts +0 -4
  247. package/dist/providers/compat/lmstudio/index.js +0 -10
  248. package/dist/providers/compat/lmstudio/index.js.map +0 -1
  249. package/dist/providers/compat/passthrough/index.d.ts +0 -4
  250. package/dist/providers/compat/passthrough/index.js +0 -9
  251. package/dist/providers/compat/passthrough/index.js.map +0 -1
  252. package/dist/providers/compat/responses/index.d.ts +0 -1
  253. package/dist/providers/compat/responses/index.js +0 -8
  254. package/dist/providers/compat/responses/index.js.map +0 -1
  255. package/dist/providers/core/composite/compat/anthropic.d.ts +0 -3
  256. package/dist/providers/core/composite/compat/anthropic.js +0 -7
  257. package/dist/providers/core/composite/compat/anthropic.js.map +0 -1
  258. package/dist/providers/core/composite/compat/gemini.d.ts +0 -3
  259. package/dist/providers/core/composite/compat/gemini.js +0 -7
  260. package/dist/providers/core/composite/compat/gemini.js.map +0 -1
  261. package/dist/providers/core/composite/compat/openai-compat-aggregator.d.ts +0 -9
  262. package/dist/providers/core/composite/compat/openai-compat-aggregator.js +0 -135
  263. package/dist/providers/core/composite/compat/openai-compat-aggregator.js.map +0 -1
  264. package/dist/providers/core/composite/compat/responses.d.ts +0 -3
  265. package/dist/providers/core/composite/compat/responses.js +0 -91
  266. package/dist/providers/core/composite/compat/responses.js.map +0 -1
  267. package/dist/providers/core/composite/provider-composite.d.ts +0 -50
  268. package/dist/providers/core/composite/provider-composite.js +0 -235
  269. package/dist/providers/core/composite/provider-composite.js.map +0 -1
  270. package/scripts/tests/apply-patch-loop.mjs.bak +0 -363
@@ -0,0 +1,667 @@
1
+ import { getCompatProfile } from './compat-profile-store.js';
2
+ const RATE_LIMIT_ERROR = 'ERR_COMPAT_RATE_LIMIT_DETECTED';
3
+ export function applyRequestCompat(profileId, payload) {
4
+ const profile = getCompatProfile(profileId);
5
+ if (!profile) {
6
+ return { payload };
7
+ }
8
+ const stage = pickStageConfig(profile, 'request');
9
+ if (!stage) {
10
+ return { payload };
11
+ }
12
+ const mutated = structuredClone(payload);
13
+ if (Array.isArray(stage.mappings)) {
14
+ for (const mapping of stage.mappings) {
15
+ applyMapping(mutated, mapping);
16
+ }
17
+ }
18
+ return {
19
+ payload: mutated,
20
+ appliedProfile: profile.id
21
+ };
22
+ }
23
+ export function applyResponseCompat(profileId, payload) {
24
+ const profile = getCompatProfile(profileId);
25
+ if (!profile) {
26
+ return { payload };
27
+ }
28
+ const stage = pickStageConfig(profile, 'response');
29
+ if (!stage) {
30
+ return { payload };
31
+ }
32
+ const mutated = structuredClone(payload);
33
+ if (Array.isArray(stage.mappings)) {
34
+ for (const mapping of stage.mappings) {
35
+ applyMapping(mutated, mapping);
36
+ }
37
+ }
38
+ if (Array.isArray(stage.filters)) {
39
+ for (const filter of stage.filters) {
40
+ applyFilter(mutated, filter);
41
+ }
42
+ }
43
+ return {
44
+ payload: mutated,
45
+ appliedProfile: profile.id
46
+ };
47
+ }
48
+ function pickStageConfig(profile, stage) {
49
+ if (!profile) {
50
+ return null;
51
+ }
52
+ if (stage === 'request' && profile.request) {
53
+ return profile.request;
54
+ }
55
+ if (stage === 'response' && profile.response) {
56
+ return profile.response;
57
+ }
58
+ if (profile.direction && profile.direction !== stage) {
59
+ return null;
60
+ }
61
+ if (profile.mappings || profile.filters) {
62
+ return {
63
+ mappings: profile.mappings,
64
+ filters: profile.filters
65
+ };
66
+ }
67
+ return null;
68
+ }
69
+ function applyMapping(root, mapping) {
70
+ switch (mapping.action) {
71
+ case 'remove':
72
+ removePath(root, mapping.path);
73
+ break;
74
+ case 'rename':
75
+ renamePath(root, mapping.from, mapping.to);
76
+ break;
77
+ case 'set':
78
+ setPath(root, mapping.path, mapping.value);
79
+ break;
80
+ case 'stringify':
81
+ stringifyPath(root, mapping.path, mapping.fallback);
82
+ break;
83
+ case 'parse_json':
84
+ parseJsonPath(root, mapping.path, mapping.fallback);
85
+ break;
86
+ case 'set_default':
87
+ setDefaultPath(root, mapping.path, mapping.value, mapping.valueSource);
88
+ break;
89
+ case 'normalize_tool_choice':
90
+ normalizeToolChoice(root, mapping);
91
+ break;
92
+ case 'inject_instruction':
93
+ injectInstruction(root, mapping);
94
+ break;
95
+ case 'convert_responses_output_to_choices':
96
+ convertResponsesOutputToChoices(root);
97
+ break;
98
+ default:
99
+ break;
100
+ }
101
+ }
102
+ function applyFilter(payload, filter) {
103
+ if (filter.action === 'rate_limit_text') {
104
+ if (detectRateLimitText(payload, filter.needle)) {
105
+ const err = new Error('Provider returned rate limit notice');
106
+ err.code = RATE_LIMIT_ERROR;
107
+ err.statusCode = 429;
108
+ throw err;
109
+ }
110
+ }
111
+ }
112
+ function detectRateLimitText(payload, needle) {
113
+ if (!needle || !payload) {
114
+ return false;
115
+ }
116
+ const normalizedNeedle = needle.toLowerCase();
117
+ const stack = [payload];
118
+ while (stack.length) {
119
+ const current = stack.pop();
120
+ if (typeof current === 'string') {
121
+ if (current.toLowerCase().includes(normalizedNeedle)) {
122
+ return true;
123
+ }
124
+ continue;
125
+ }
126
+ if (Array.isArray(current)) {
127
+ for (const entry of current) {
128
+ stack.push(entry);
129
+ }
130
+ continue;
131
+ }
132
+ if (isRecord(current)) {
133
+ for (const value of Object.values(current)) {
134
+ stack.push(value);
135
+ }
136
+ }
137
+ }
138
+ return false;
139
+ }
140
+ function parsePath(path) {
141
+ if (!path || typeof path !== 'string') {
142
+ return [];
143
+ }
144
+ return path
145
+ .split('.')
146
+ .map((segment) => segment.trim())
147
+ .filter(Boolean)
148
+ .map((segment) => {
149
+ if (segment.endsWith('[*]')) {
150
+ return {
151
+ key: segment.slice(0, -3),
152
+ wildcard: true
153
+ };
154
+ }
155
+ return {
156
+ key: segment,
157
+ wildcard: false
158
+ };
159
+ });
160
+ }
161
+ function removePath(root, path) {
162
+ const steps = parsePath(path);
163
+ if (!steps.length) {
164
+ return;
165
+ }
166
+ const parentSteps = steps.slice(0, -1);
167
+ const finalStep = steps[steps.length - 1];
168
+ const targets = resolveTargets(root, parentSteps);
169
+ for (const target of targets) {
170
+ if (isRecord(target) && finalStep && finalStep.key in target) {
171
+ delete target[finalStep.key];
172
+ }
173
+ }
174
+ }
175
+ function renamePath(root, fromPath, toPath) {
176
+ const value = getPathValue(root, fromPath);
177
+ if (value === undefined) {
178
+ return;
179
+ }
180
+ setPath(root, toPath, value);
181
+ removePath(root, fromPath);
182
+ }
183
+ function setPath(root, path, value) {
184
+ const steps = parsePath(path);
185
+ if (!steps.length) {
186
+ return;
187
+ }
188
+ let cursor = root;
189
+ for (let i = 0; i < steps.length; i++) {
190
+ const step = steps[i];
191
+ if (step.wildcard) {
192
+ throw new Error(`Cannot set wildcard path: ${path}`);
193
+ }
194
+ if (i === steps.length - 1) {
195
+ if (isRecord(cursor)) {
196
+ cursor[step.key] = structuredClone(value);
197
+ }
198
+ }
199
+ else {
200
+ if (!isRecord(cursor[step.key])) {
201
+ cursor[step.key] = {};
202
+ }
203
+ cursor = cursor[step.key];
204
+ }
205
+ }
206
+ }
207
+ function getPathValue(root, path) {
208
+ const steps = parsePath(path);
209
+ if (!steps.length) {
210
+ return undefined;
211
+ }
212
+ let cursor = root;
213
+ for (const step of steps) {
214
+ if (step.wildcard) {
215
+ if (!isRecord(cursor)) {
216
+ return undefined;
217
+ }
218
+ const arr = cursor[step.key];
219
+ if (!Array.isArray(arr) || !arr.length) {
220
+ return undefined;
221
+ }
222
+ cursor = arr[0];
223
+ continue;
224
+ }
225
+ if (!isRecord(cursor)) {
226
+ return undefined;
227
+ }
228
+ cursor = cursor[step.key];
229
+ if (cursor === undefined) {
230
+ return undefined;
231
+ }
232
+ }
233
+ return cursor;
234
+ }
235
+ function stringifyPath(root, path, fallback) {
236
+ const steps = parsePath(path);
237
+ if (!steps.length) {
238
+ return;
239
+ }
240
+ const parentSteps = steps.slice(0, -1);
241
+ const finalStep = steps[steps.length - 1];
242
+ const targets = resolveTargets(root, parentSteps);
243
+ for (const target of targets) {
244
+ if (!isRecord(target) || !finalStep) {
245
+ continue;
246
+ }
247
+ const current = target[finalStep.key];
248
+ if (typeof current === 'string') {
249
+ continue;
250
+ }
251
+ try {
252
+ if (current === undefined) {
253
+ target[finalStep.key] = JSON.stringify(fallback ?? {});
254
+ }
255
+ else {
256
+ target[finalStep.key] = JSON.stringify(current);
257
+ }
258
+ }
259
+ catch {
260
+ try {
261
+ target[finalStep.key] = JSON.stringify(fallback ?? {});
262
+ }
263
+ catch {
264
+ target[finalStep.key] = '{}';
265
+ }
266
+ }
267
+ }
268
+ }
269
+ function parseJsonPath(root, path, fallback) {
270
+ const steps = parsePath(path);
271
+ if (!steps.length) {
272
+ return;
273
+ }
274
+ const parentSteps = steps.slice(0, -1);
275
+ const finalStep = steps[steps.length - 1];
276
+ const targets = resolveTargets(root, parentSteps);
277
+ for (const target of targets) {
278
+ if (!isRecord(target) || !finalStep) {
279
+ continue;
280
+ }
281
+ const current = target[finalStep.key];
282
+ if (current === undefined || current === null) {
283
+ if (fallback !== undefined) {
284
+ target[finalStep.key] = structuredClone(fallback);
285
+ }
286
+ continue;
287
+ }
288
+ if (typeof current !== 'string') {
289
+ continue;
290
+ }
291
+ const trimmed = current.trim();
292
+ if (!trimmed) {
293
+ if (fallback !== undefined) {
294
+ target[finalStep.key] = structuredClone(fallback);
295
+ }
296
+ continue;
297
+ }
298
+ try {
299
+ target[finalStep.key] = JSON.parse(trimmed);
300
+ }
301
+ catch {
302
+ if (fallback !== undefined) {
303
+ target[finalStep.key] = structuredClone(fallback);
304
+ }
305
+ }
306
+ }
307
+ }
308
+ function setDefaultPath(root, path, value, source) {
309
+ const current = getPathValue(root, path);
310
+ if (current !== undefined) {
311
+ return;
312
+ }
313
+ let finalValue = value;
314
+ if (source === 'timestamp_seconds') {
315
+ finalValue = Math.floor(Date.now() / 1000);
316
+ }
317
+ else if (source === 'chat_completion_id') {
318
+ finalValue = `chatcmpl_${Date.now().toString(36)}_${Math.random().toString(36).slice(2)}`;
319
+ }
320
+ if (finalValue === undefined) {
321
+ return;
322
+ }
323
+ setPath(root, path, finalValue);
324
+ }
325
+ function normalizeToolChoice(root, mapping) {
326
+ const path = mapping.path || 'tool_choice';
327
+ const current = getPathValue(root, path);
328
+ if (!current || typeof current !== 'object' || Array.isArray(current)) {
329
+ return;
330
+ }
331
+ const replacement = mapping.objectReplacement ?? 'required';
332
+ setPath(root, path, replacement);
333
+ }
334
+ function injectInstruction(root, mapping) {
335
+ const raw = getPathValue(root, mapping.sourcePath);
336
+ removePath(root, mapping.sourcePath);
337
+ const value = typeof raw === 'string' ? raw.trim() : '';
338
+ if (!value) {
339
+ return;
340
+ }
341
+ let text = value;
342
+ if (mapping.stripHtml) {
343
+ text = stripHtml(text);
344
+ }
345
+ const maxLength = resolveMaxLength(mapping.maxLengthEnv);
346
+ if (maxLength && text.length > maxLength) {
347
+ text = text.slice(0, maxLength);
348
+ }
349
+ if (!text) {
350
+ return;
351
+ }
352
+ const targetPath = mapping.targetPath || 'input';
353
+ const targetArray = ensureArray(root, targetPath);
354
+ const message = {
355
+ type: 'message',
356
+ role: mapping.role || 'system',
357
+ content: [
358
+ {
359
+ type: mapping.contentType || 'input_text',
360
+ text
361
+ }
362
+ ]
363
+ };
364
+ targetArray.unshift(message);
365
+ }
366
+ function resolveTargets(root, steps) {
367
+ if (!steps.length) {
368
+ return [root];
369
+ }
370
+ const results = [];
371
+ const traverse = (node, index) => {
372
+ const step = steps[index];
373
+ if (!step || !isRecord(node)) {
374
+ return;
375
+ }
376
+ const next = node[step.key];
377
+ if (step.wildcard && Array.isArray(next)) {
378
+ if (index === steps.length - 1) {
379
+ for (const child of next) {
380
+ if (isRecord(child)) {
381
+ results.push(child);
382
+ }
383
+ }
384
+ }
385
+ else {
386
+ for (const child of next) {
387
+ traverse(child, index + 1);
388
+ }
389
+ }
390
+ return;
391
+ }
392
+ if (!step.wildcard && isRecord(next)) {
393
+ if (index === steps.length - 1) {
394
+ results.push(next);
395
+ }
396
+ else {
397
+ traverse(next, index + 1);
398
+ }
399
+ }
400
+ };
401
+ traverse(root, 0);
402
+ return results;
403
+ }
404
+ function isRecord(value) {
405
+ return typeof value === 'object' && value !== null;
406
+ }
407
+ function ensureArray(root, path) {
408
+ const steps = parsePath(path);
409
+ if (!steps.length) {
410
+ throw new Error(`Invalid array path: ${path}`);
411
+ }
412
+ let cursor = root;
413
+ for (let i = 0; i < steps.length; i++) {
414
+ const step = steps[i];
415
+ if (step.wildcard) {
416
+ throw new Error(`Array path does not support wildcards: ${path}`);
417
+ }
418
+ if (i === steps.length - 1) {
419
+ if (!Array.isArray(cursor[step.key])) {
420
+ cursor[step.key] = [];
421
+ }
422
+ if (!Array.isArray(cursor[step.key])) {
423
+ cursor[step.key] = [];
424
+ }
425
+ return cursor[step.key];
426
+ }
427
+ if (!isRecord(cursor[step.key])) {
428
+ cursor[step.key] = {};
429
+ }
430
+ cursor = cursor[step.key];
431
+ }
432
+ throw new Error(`Failed to resolve array path: ${path}`);
433
+ }
434
+ function stripHtml(value) {
435
+ return value.replace(/<\/?[^>]+(>|$)/g, '');
436
+ }
437
+ function resolveMaxLength(envVars) {
438
+ if (!envVars || !envVars.length) {
439
+ return undefined;
440
+ }
441
+ for (const envName of envVars) {
442
+ if (!envName)
443
+ continue;
444
+ const raw = process.env[envName];
445
+ if (!raw) {
446
+ continue;
447
+ }
448
+ const parsed = Number(raw);
449
+ if (Number.isFinite(parsed) && parsed > 0) {
450
+ return Math.floor(parsed);
451
+ }
452
+ }
453
+ return undefined;
454
+ }
455
+ function convertResponsesOutputToChoices(root) {
456
+ if (!isRecord(root)) {
457
+ return;
458
+ }
459
+ const existingChoices = root.choices;
460
+ if (Array.isArray(existingChoices) && existingChoices.length > 0) {
461
+ return;
462
+ }
463
+ const choicesFromOutput = buildChoicesFromResponsesOutput(root);
464
+ if (choicesFromOutput.length > 0) {
465
+ root.choices = choicesFromOutput;
466
+ return;
467
+ }
468
+ const fallbackText = extractOutputText(root);
469
+ if (typeof fallbackText === 'string') {
470
+ root.choices = [
471
+ {
472
+ index: 0,
473
+ finish_reason: normalizeFinishReason(typeof root.status === 'string' ? root.status : 'stop'),
474
+ message: {
475
+ role: 'assistant',
476
+ content: fallbackText
477
+ }
478
+ }
479
+ ];
480
+ }
481
+ }
482
+ function buildChoicesFromResponsesOutput(root) {
483
+ const outputEntries = Array.isArray(root.output) ? root.output : [];
484
+ const choices = [];
485
+ outputEntries.forEach((entry) => {
486
+ if (!isRecord(entry)) {
487
+ return;
488
+ }
489
+ if ('type' in entry && typeof entry.type === 'string' && entry.type !== 'message') {
490
+ return;
491
+ }
492
+ const choice = convertOutputEntryToChoice(entry, choices.length, root);
493
+ if (choice) {
494
+ choices.push(choice);
495
+ }
496
+ });
497
+ return choices;
498
+ }
499
+ function convertOutputEntryToChoice(entry, index, root) {
500
+ const message = buildMessageFromOutputEntry(entry, index);
501
+ if (!message) {
502
+ return null;
503
+ }
504
+ const finishReasonCandidate = (typeof entry.stop_reason === 'string' && entry.stop_reason) ||
505
+ (typeof entry.finish_reason === 'string' && entry.finish_reason) ||
506
+ (typeof entry.status === 'string' && entry.status) ||
507
+ (typeof root.status === 'string' && root.status) ||
508
+ 'stop';
509
+ return {
510
+ index,
511
+ finish_reason: normalizeFinishReason(finishReasonCandidate),
512
+ message
513
+ };
514
+ }
515
+ function buildMessageFromOutputEntry(entry, choiceIndex) {
516
+ const role = normalizeRole(typeof entry.role === 'string' ? entry.role : 'assistant');
517
+ const contentArray = Array.isArray(entry.content) ? entry.content : [];
518
+ const textSegments = [];
519
+ const toolCalls = [];
520
+ contentArray.forEach((part, partIndex) => {
521
+ if (!isRecord(part)) {
522
+ const fallback = coerceText(part);
523
+ if (fallback) {
524
+ textSegments.push(fallback);
525
+ }
526
+ return;
527
+ }
528
+ const type = typeof part.type === 'string'
529
+ ? part.type
530
+ : typeof part.content_type === 'string'
531
+ ? part.content_type
532
+ : '';
533
+ switch (type) {
534
+ case 'output_text': {
535
+ const txt = typeof part.text === 'string'
536
+ ? part.text
537
+ : coerceText(part.text);
538
+ if (txt) {
539
+ textSegments.push(txt);
540
+ }
541
+ break;
542
+ }
543
+ case 'tool_call': {
544
+ const normalized = normalizeToolCall(part, choiceIndex, toolCalls.length);
545
+ if (normalized) {
546
+ toolCalls.push(normalized);
547
+ }
548
+ break;
549
+ }
550
+ case 'input_text':
551
+ case 'reasoning_content': {
552
+ const txt = typeof part.text === 'string'
553
+ ? part.text
554
+ : coerceText(part.text);
555
+ if (txt) {
556
+ textSegments.push(txt);
557
+ }
558
+ break;
559
+ }
560
+ default: {
561
+ const fallback = coerceText(part);
562
+ if (fallback) {
563
+ textSegments.push(fallback);
564
+ }
565
+ break;
566
+ }
567
+ }
568
+ });
569
+ const message = {
570
+ role,
571
+ content: textSegments.join('')
572
+ };
573
+ if (toolCalls.length) {
574
+ message.tool_calls = toolCalls;
575
+ if (typeof message.content !== 'string') {
576
+ message.content = '';
577
+ }
578
+ }
579
+ return message;
580
+ }
581
+ function normalizeToolCall(part, choiceIndex, callIndex) {
582
+ const payload = isRecord(part.tool_call) ? part.tool_call : part;
583
+ const fnPayload = isRecord(payload.function)
584
+ ? payload.function
585
+ : isRecord(part.function)
586
+ ? part.function
587
+ : null;
588
+ const name = typeof fnPayload?.name === 'string' ? fnPayload.name : undefined;
589
+ if (!name) {
590
+ return null;
591
+ }
592
+ const rawArgs = fnPayload?.arguments;
593
+ let argString;
594
+ if (typeof rawArgs === 'string') {
595
+ argString = rawArgs;
596
+ }
597
+ else {
598
+ try {
599
+ argString = JSON.stringify(rawArgs ?? {});
600
+ }
601
+ catch {
602
+ argString = '{}';
603
+ }
604
+ }
605
+ const idCandidate = (typeof payload.id === 'string' && payload.id) ||
606
+ (typeof payload.tool_call_id === 'string'
607
+ ? payload.tool_call_id
608
+ : undefined) ||
609
+ (typeof payload.call_id === 'string'
610
+ ? payload.call_id
611
+ : undefined);
612
+ return {
613
+ id: idCandidate || `call_${choiceIndex}_${callIndex}`,
614
+ type: 'function',
615
+ function: {
616
+ name,
617
+ arguments: argString
618
+ }
619
+ };
620
+ }
621
+ function extractOutputText(root) {
622
+ const textCandidate = root.output_text;
623
+ if (typeof textCandidate === 'string' && textCandidate.length > 0) {
624
+ return textCandidate;
625
+ }
626
+ return undefined;
627
+ }
628
+ function normalizeRole(role) {
629
+ const normalized = role.toLowerCase();
630
+ if (normalized === 'assistant' || normalized === 'system' || normalized === 'user' || normalized === 'tool') {
631
+ return normalized;
632
+ }
633
+ return 'assistant';
634
+ }
635
+ function coerceText(value) {
636
+ if (typeof value === 'string') {
637
+ return value;
638
+ }
639
+ if (typeof value === 'number' || typeof value === 'boolean') {
640
+ return String(value);
641
+ }
642
+ if (Array.isArray(value)) {
643
+ return value.map((entry) => coerceText(entry)).join('');
644
+ }
645
+ if (isRecord(value)) {
646
+ try {
647
+ return JSON.stringify(value);
648
+ }
649
+ catch {
650
+ return '';
651
+ }
652
+ }
653
+ return '';
654
+ }
655
+ function normalizeFinishReason(reason) {
656
+ const normalized = reason.toLowerCase();
657
+ if (normalized.includes('tool')) {
658
+ return 'tool_calls';
659
+ }
660
+ if (normalized.includes('length') || normalized.includes('max_token') || normalized.includes('in_progress')) {
661
+ return 'length';
662
+ }
663
+ if (normalized.includes('filter')) {
664
+ return 'content_filter';
665
+ }
666
+ return 'stop';
667
+ }
@@ -0,0 +1,2 @@
1
+ import type { CompatProfileConfig } from './compat-types.js';
2
+ export declare function getCompatProfile(profileId?: string): CompatProfileConfig | null;