@jsonstudio/llms 0.6.2979 → 0.6.3238

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 (246) hide show
  1. package/dist/conversion/args-mapping.js +8 -0
  2. package/dist/conversion/{shared/bridge-actions.js → bridge-actions.js} +2 -1
  3. package/dist/conversion/{shared/bridge-id-utils.js → bridge-id-utils.js} +1 -1
  4. package/dist/conversion/{shared/bridge-instructions.js → bridge-instructions.js} +1 -1
  5. package/dist/conversion/{shared/bridge-message-utils.d.ts → bridge-message-utils.d.ts} +1 -1
  6. package/dist/conversion/{shared/bridge-message-utils.js → bridge-message-utils.js} +5 -149
  7. package/dist/conversion/{shared/bridge-metadata.js → bridge-metadata.js} +1 -1
  8. package/dist/conversion/{shared/bridge-policies.js → bridge-policies.js} +1 -1
  9. package/dist/conversion/codecs/gemini-openai-codec.js +27 -8
  10. package/dist/conversion/codecs/responses-openai-codec.js +1 -1
  11. package/dist/conversion/{shared/compaction-detect.d.ts → compaction-detect.d.ts} +1 -1
  12. package/dist/conversion/compaction-detect.js +4 -0
  13. package/dist/conversion/compat/actions/apply-patch-fixer.js +2 -2
  14. package/dist/conversion/compat/actions/deepseek-web-response.d.ts +0 -1
  15. package/dist/conversion/compat/actions/deepseek-web-response.js +15 -405
  16. package/dist/conversion/compat/actions/harvest-tool-calls-from-text.js +1 -1
  17. package/dist/conversion/compat/actions/lmstudio-responses-fc-ids.js +1 -1
  18. package/dist/conversion/compat/actions/qwen-transform.js +74 -2
  19. package/dist/conversion/compat/actions/snapshot.js +1 -1
  20. package/dist/conversion/compat/antigravity-session-signature.js +36 -0
  21. package/dist/conversion/compat/profiles/chat-deepseek-web.json +0 -22
  22. package/dist/conversion/compat/profiles/chat-glm.json +251 -72
  23. package/dist/conversion/compat/profiles/chat-iflow.json +174 -39
  24. package/dist/conversion/compat/profiles/chat-lmstudio.json +43 -14
  25. package/dist/conversion/hub/operation-table/operation-table-runner.js +2 -2
  26. package/dist/conversion/hub/operation-table/semantic-mappers/anthropic-mapper.js +1 -1
  27. package/dist/conversion/hub/operation-table/semantic-mappers/archive/chat-mapper.archive.d.ts +8 -0
  28. package/dist/conversion/hub/operation-table/semantic-mappers/archive/chat-mapper.archive.js +404 -0
  29. package/dist/conversion/hub/operation-table/semantic-mappers/chat-mapper.js +5 -381
  30. package/dist/conversion/hub/operation-table/semantic-mappers/gemini-mapper.js +2 -2
  31. package/dist/conversion/hub/operation-table/semantic-mappers/responses-mapper.js +2 -8
  32. package/dist/conversion/hub/pipeline/hub-pipeline.d.ts +1 -0
  33. package/dist/conversion/hub/pipeline/hub-pipeline.js +50 -3
  34. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.d.ts +1 -1
  35. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.js +62 -0
  36. package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage2_route_select/index.js +3 -1
  37. package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage1_sse_decode/index.js +1 -1
  38. package/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage1_client_remap/chat-process-semantics-bridge.d.ts +1 -1
  39. package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage1_tool_governance/index.js +42 -29
  40. package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage2_finalize/index.js +12 -0
  41. package/dist/conversion/hub/policy/protocol-spec.js +1 -1
  42. package/dist/conversion/hub/process/chat-process-clock-reminders.js +1 -1
  43. package/dist/conversion/hub/process/chat-process-clock-tools.js +1 -1
  44. package/dist/conversion/hub/process/chat-process-continue-execution.js +1 -1
  45. package/dist/conversion/hub/process/chat-process-servertool-orchestration.js +1 -1
  46. package/dist/conversion/hub/process/chat-process-web-search.js +1 -1
  47. package/dist/conversion/hub/response/provider-response.js +14 -5
  48. package/dist/conversion/hub/response/response-mappers.js +23 -1
  49. package/dist/conversion/hub/response/response-runtime.js +28 -5
  50. package/dist/conversion/hub/snapshot-recorder.js +3 -92
  51. package/dist/conversion/hub/tool-governance/engine.d.ts +8 -0
  52. package/dist/conversion/hub/tool-governance/engine.js +40 -193
  53. package/dist/conversion/hub/tool-governance/rules.js +73 -69
  54. package/dist/conversion/hub/tool-surface/tool-surface-engine.js +1 -1
  55. package/dist/conversion/index.d.ts +1 -2
  56. package/dist/conversion/index.js +1 -2
  57. package/dist/conversion/{shared/jsonish.js → jsonish.js} +1 -1
  58. package/dist/conversion/{shared/mcp-injection.js → mcp-injection.js} +1 -1
  59. package/dist/conversion/media.js +4 -0
  60. package/dist/conversion/{shared/metadata-passthrough.d.ts → metadata-passthrough.d.ts} +1 -1
  61. package/dist/conversion/{shared/metadata-passthrough.js → metadata-passthrough.js} +2 -2
  62. package/dist/conversion/payload-budget.js +47 -0
  63. package/dist/conversion/protocol-field-allowlists.d.ts +7 -0
  64. package/dist/conversion/protocol-field-allowlists.js +9 -0
  65. package/dist/conversion/{shared/protocol-state.d.ts → protocol-state.d.ts} +2 -2
  66. package/dist/conversion/{shared/protocol-state.js → protocol-state.js} +2 -2
  67. package/dist/conversion/{shared/errors.d.ts → provider-protocol-error.d.ts} +0 -3
  68. package/dist/conversion/provider-protocol-error.js +25 -0
  69. package/dist/conversion/responses/responses-openai-bridge/response-payload.js +8 -5
  70. package/dist/conversion/responses/responses-openai-bridge/types.d.ts +1 -1
  71. package/dist/conversion/responses/responses-openai-bridge.d.ts +1 -1
  72. package/dist/conversion/responses/responses-openai-bridge.js +43 -10
  73. package/dist/conversion/{shared/runtime-metadata.d.ts → runtime-metadata.d.ts} +1 -1
  74. package/dist/conversion/{shared/runtime-metadata.js → runtime-metadata.js} +2 -2
  75. package/dist/conversion/shared/anthropic-message-utils.js +19 -8
  76. package/dist/conversion/shared/chat-request-filters.d.ts +3 -4
  77. package/dist/conversion/shared/chat-request-filters.js +22 -78
  78. package/dist/conversion/shared/gemini-tool-utils.d.ts +1 -1
  79. package/dist/conversion/shared/openai-finalizer.js +1 -0
  80. package/dist/conversion/shared/openai-message-normalize.js +2 -2
  81. package/dist/conversion/shared/reasoning-normalizer.js +6 -0
  82. package/dist/conversion/shared/reasoning-utils.js +5 -2
  83. package/dist/conversion/shared/responses-conversation-store.js +1 -1
  84. package/dist/conversion/shared/responses-output-builder.js +55 -11
  85. package/dist/conversion/shared/responses-reasoning-registry.d.ts +14 -2
  86. package/dist/conversion/shared/responses-reasoning-registry.js +34 -6
  87. package/dist/conversion/shared/responses-response-utils.js +99 -9
  88. package/dist/conversion/shared/responses-tool-utils.js +1 -1
  89. package/dist/conversion/shared/text-markup-normalizer/normalize.d.ts +1 -1
  90. package/dist/conversion/shared/text-markup-normalizer.d.ts +2 -2
  91. package/dist/conversion/shared/text-markup-normalizer.js +1 -1
  92. package/dist/conversion/shared/tool-filter-pipeline.js +1 -1
  93. package/dist/conversion/shared/tool-governor.js +3 -3
  94. package/dist/conversion/shared/tool-mapping.d.ts +1 -1
  95. package/dist/conversion/{shared/snapshot-utils.d.ts → snapshot-utils.d.ts} +11 -0
  96. package/dist/conversion/{shared/snapshot-utils.js → snapshot-utils.js} +14 -23
  97. package/dist/conversion/types/text-markup-normalizer.d.ts +13 -0
  98. package/dist/conversion/types/text-markup-normalizer.js +1 -0
  99. package/dist/filters/special/request-tools-normalize.js +1 -1
  100. package/dist/filters/special/response-tool-text-canonicalize.js +2 -2
  101. package/dist/native/router_hotpath_napi.node +0 -0
  102. package/dist/quota/quota-manager.js +31 -59
  103. package/dist/quota/quota-state.js +14 -7
  104. package/dist/router/virtual-router/bootstrap/profile-builder.d.ts +1 -0
  105. package/dist/router/virtual-router/bootstrap/profile-builder.js +13 -0
  106. package/dist/router/virtual-router/bootstrap/provider-normalization.d.ts +2 -0
  107. package/dist/router/virtual-router/bootstrap/provider-normalization.js +4 -1
  108. package/dist/router/virtual-router/bootstrap/streaming-helpers.d.ts +7 -0
  109. package/dist/router/virtual-router/bootstrap/streaming-helpers.js +44 -0
  110. package/dist/router/virtual-router/bootstrap.js +2 -0
  111. package/dist/router/virtual-router/engine/routing-state/store.d.ts +1 -2
  112. package/dist/router/virtual-router/engine/routing-state/store.js +2 -2
  113. package/dist/router/virtual-router/engine-legacy/config.d.ts +11 -0
  114. package/dist/router/virtual-router/engine-legacy/config.js +108 -0
  115. package/dist/router/virtual-router/engine-legacy/direct-model.d.ts +10 -0
  116. package/dist/router/virtual-router/engine-legacy/direct-model.js +38 -0
  117. package/dist/router/virtual-router/engine-legacy/health.d.ts +13 -0
  118. package/dist/router/virtual-router/engine-legacy/health.js +104 -0
  119. package/dist/router/virtual-router/engine-legacy/helpers.d.ts +16 -0
  120. package/dist/router/virtual-router/engine-legacy/helpers.js +226 -0
  121. package/dist/router/virtual-router/engine-legacy/route-finalize.d.ts +9 -0
  122. package/dist/router/virtual-router/engine-legacy/route-finalize.js +84 -0
  123. package/dist/router/virtual-router/engine-legacy/route-selection.d.ts +17 -0
  124. package/dist/router/virtual-router/engine-legacy/route-selection.js +205 -0
  125. package/dist/router/virtual-router/engine-legacy/route-state-allowlist.d.ts +3 -0
  126. package/dist/router/virtual-router/engine-legacy/route-state-allowlist.js +36 -0
  127. package/dist/router/virtual-router/engine-legacy/route-state.d.ts +12 -0
  128. package/dist/router/virtual-router/engine-legacy/route-state.js +386 -0
  129. package/dist/router/virtual-router/engine-legacy/route-utils.d.ts +19 -0
  130. package/dist/router/virtual-router/engine-legacy/route-utils.js +212 -0
  131. package/dist/router/virtual-router/engine-legacy/routing.d.ts +8 -0
  132. package/dist/router/virtual-router/engine-legacy/routing.js +8 -0
  133. package/dist/router/virtual-router/engine-legacy/selection-core.d.ts +28 -0
  134. package/dist/router/virtual-router/engine-legacy/selection-core.js +112 -0
  135. package/dist/router/virtual-router/engine-legacy/selection-state.d.ts +16 -0
  136. package/dist/router/virtual-router/engine-legacy/selection-state.js +187 -0
  137. package/dist/router/virtual-router/engine-legacy/state-accessors.d.ts +21 -0
  138. package/dist/router/virtual-router/engine-legacy/state-accessors.js +118 -0
  139. package/dist/router/virtual-router/engine-legacy.d.ts +123 -0
  140. package/dist/router/virtual-router/engine-legacy.js +194 -0
  141. package/dist/router/virtual-router/engine-logging.d.ts +2 -0
  142. package/dist/router/virtual-router/engine-logging.js +7 -2
  143. package/dist/router/virtual-router/engine-selection/key-parsing.js +0 -3
  144. package/dist/router/virtual-router/engine-selection/native-chat-request-filter-semantics.d.ts +1 -0
  145. package/dist/router/virtual-router/engine-selection/native-chat-request-filter-semantics.js +54 -0
  146. package/dist/router/virtual-router/engine-selection/native-hub-bridge-policy-semantics.d.ts +10 -0
  147. package/dist/router/virtual-router/engine-selection/native-hub-bridge-policy-semantics.js +67 -0
  148. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-governance-semantics.d.ts +30 -0
  149. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-governance-semantics.js +202 -0
  150. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-semantic-mappers.d.ts +2 -0
  151. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-semantic-mappers.js +83 -0
  152. package/dist/router/virtual-router/engine-selection/native-router-hotpath-loader.js +43 -2
  153. package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.d.ts +75 -0
  154. package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.js +205 -0
  155. package/dist/router/virtual-router/engine-selection/native-snapshot-hooks.d.ts +3 -0
  156. package/dist/router/virtual-router/engine-selection/native-snapshot-hooks.js +109 -0
  157. package/dist/router/virtual-router/engine-selection/native-virtual-router-engine-proxy.d.ts +16 -0
  158. package/dist/router/virtual-router/engine-selection/native-virtual-router-engine-proxy.js +14 -0
  159. package/dist/router/virtual-router/engine-selection/native-virtual-router-routing-instructions-semantics.d.ts +2 -0
  160. package/dist/router/virtual-router/engine-selection/native-virtual-router-routing-instructions-semantics.js +86 -0
  161. package/dist/router/virtual-router/engine-selection/tier-selection-quota-integration.js +100 -0
  162. package/dist/router/virtual-router/engine-selection/tier-selection-select.js +99 -0
  163. package/dist/router/virtual-router/engine.d.ts +22 -105
  164. package/dist/router/virtual-router/engine.js +274 -1641
  165. package/dist/router/virtual-router/load-balancer.d.ts +8 -0
  166. package/dist/router/virtual-router/load-balancer.js +65 -2
  167. package/dist/router/virtual-router/provider-registry.js +2 -0
  168. package/dist/router/virtual-router/routing-instructions/clean.d.ts +3 -0
  169. package/dist/router/virtual-router/routing-instructions/clean.js +34 -0
  170. package/dist/router/virtual-router/routing-instructions/parse.d.ts +18 -0
  171. package/dist/router/virtual-router/routing-instructions/parse.js +377 -0
  172. package/dist/router/virtual-router/routing-instructions/state.d.ts +4 -0
  173. package/dist/router/virtual-router/routing-instructions/state.js +245 -0
  174. package/dist/router/virtual-router/routing-instructions/types.d.ts +70 -0
  175. package/dist/router/virtual-router/routing-instructions/types.js +2 -0
  176. package/dist/router/virtual-router/routing-instructions.d.ts +5 -89
  177. package/dist/router/virtual-router/routing-instructions.js +4 -655
  178. package/dist/router/virtual-router/sticky-session-store.d.ts +4 -0
  179. package/dist/router/virtual-router/sticky-session-store.js +19 -81
  180. package/dist/router/virtual-router/tool-signals.js +21 -3
  181. package/dist/router/virtual-router/types.d.ts +4 -0
  182. package/dist/servertool/clock/session-scope.js +32 -1
  183. package/dist/servertool/engine.js +79 -8
  184. package/dist/servertool/handlers/antigravity-thought-signature-bootstrap.js +1 -1
  185. package/dist/servertool/handlers/clock-auto.js +1 -1
  186. package/dist/servertool/handlers/clock.js +1 -1
  187. package/dist/servertool/handlers/compaction-detect.d.ts +1 -1
  188. package/dist/servertool/handlers/compaction-detect.js +1 -1
  189. package/dist/servertool/handlers/gemini-empty-reply-continue.js +1 -1
  190. package/dist/servertool/handlers/iflow-model-error-retry.js +1 -1
  191. package/dist/servertool/handlers/recursive-detection-guard.js +1 -1
  192. package/dist/servertool/handlers/review.js +1 -1
  193. package/dist/servertool/handlers/stop-message-auto/iflow-followup.js +1 -1
  194. package/dist/servertool/handlers/stop-message-auto/runtime-utils.js +1 -1
  195. package/dist/servertool/handlers/stop-message-auto.js +1 -1
  196. package/dist/servertool/handlers/vision.js +1 -1
  197. package/dist/servertool/handlers/web-search.js +1 -1
  198. package/dist/servertool/reenter-backend.js +1 -1
  199. package/dist/servertool/server-side-tools.js +2 -2
  200. package/dist/servertool/stop-gateway-context.js +1 -1
  201. package/dist/servertool/stop-message-compare-context.js +1 -1
  202. package/dist/sse/json-to-sse/event-generators/responses.d.ts +4 -0
  203. package/dist/sse/json-to-sse/event-generators/responses.js +95 -1
  204. package/dist/sse/json-to-sse/sequencers/responses-sequencer.js +6 -4
  205. package/dist/sse/sse-to-json/builders/response-builder.d.ts +8 -0
  206. package/dist/sse/sse-to-json/builders/response-builder.js +162 -4
  207. package/dist/sse/sse-to-json/responses-sse-to-json-converter.js +2 -0
  208. package/dist/sse/types/responses-types.d.ts +6 -2
  209. package/dist/tools/apply-patch/structured/coercion.js +5 -0
  210. package/dist/tools/args-json.js +29 -0
  211. package/package.json +8 -5
  212. package/dist/conversion/shared/args-mapping.js +0 -77
  213. package/dist/conversion/shared/compaction-detect.js +0 -4
  214. package/dist/conversion/shared/errors.js +0 -31
  215. package/dist/conversion/shared/media.js +0 -4
  216. package/dist/conversion/shared/payload-budget.js +0 -165
  217. package/dist/conversion/shared/protocol-field-allowlists.d.ts +0 -7
  218. package/dist/conversion/shared/protocol-field-allowlists.js +0 -149
  219. package/dist/conversion/shared/snapshot-hooks.d.ts +0 -11
  220. package/dist/conversion/shared/snapshot-hooks.js +0 -503
  221. package/dist/conversion/shared/text-markup-normalizer/extractors-apply-patch.d.ts +0 -2
  222. package/dist/conversion/shared/text-markup-normalizer/extractors-apply-patch.js +0 -129
  223. package/dist/conversion/shared/text-markup-normalizer/extractors-json.d.ts +0 -4
  224. package/dist/conversion/shared/text-markup-normalizer/extractors-json.js +0 -637
  225. package/dist/conversion/shared/text-markup-normalizer/extractors-shared.d.ts +0 -21
  226. package/dist/conversion/shared/text-markup-normalizer/extractors-shared.js +0 -177
  227. package/dist/conversion/shared/text-markup-normalizer/extractors-transcript.d.ts +0 -5
  228. package/dist/conversion/shared/text-markup-normalizer/extractors-transcript.js +0 -385
  229. package/dist/conversion/shared/text-markup-normalizer/extractors-xml.d.ts +0 -10
  230. package/dist/conversion/shared/text-markup-normalizer/extractors-xml.js +0 -602
  231. package/dist/conversion/shared/text-markup-normalizer/extractors.d.ts +0 -5
  232. package/dist/conversion/shared/text-markup-normalizer/extractors.js +0 -4
  233. package/dist/conversion/shared/tool-canonicalizer.d.ts +0 -2
  234. package/dist/conversion/shared/tool-canonicalizer.js +0 -38
  235. /package/dist/conversion/{shared/args-mapping.d.ts → args-mapping.d.ts} +0 -0
  236. /package/dist/conversion/{shared/bridge-actions.d.ts → bridge-actions.d.ts} +0 -0
  237. /package/dist/conversion/{shared/bridge-id-utils.d.ts → bridge-id-utils.d.ts} +0 -0
  238. /package/dist/conversion/{shared/bridge-instructions.d.ts → bridge-instructions.d.ts} +0 -0
  239. /package/dist/conversion/{shared/bridge-metadata.d.ts → bridge-metadata.d.ts} +0 -0
  240. /package/dist/conversion/{shared/bridge-policies.d.ts → bridge-policies.d.ts} +0 -0
  241. /package/dist/conversion/{shared/jsonish.d.ts → jsonish.d.ts} +0 -0
  242. /package/dist/conversion/{shared/mcp-injection.d.ts → mcp-injection.d.ts} +0 -0
  243. /package/dist/conversion/{shared/media.d.ts → media.d.ts} +0 -0
  244. /package/dist/conversion/{shared/payload-budget.d.ts → payload-budget.d.ts} +0 -0
  245. /package/dist/conversion/{shared → types}/bridge-message-types.d.ts +0 -0
  246. /package/dist/conversion/{shared → types}/bridge-message-types.js +0 -0
@@ -1,9 +1,7 @@
1
- import { normalizeAssistantTextToToolCalls } from '../../shared/text-markup-normalizer.js';
2
1
  import { validateToolCall } from '../../../tools/tool-registry.js';
3
2
  import { encoding_for_model, get_encoding } from 'tiktoken';
4
3
  const DEFAULT_OPTIONS = {
5
4
  strictToolRequired: true,
6
- textToolFallback: true,
7
5
  textNormalizer: undefined
8
6
  };
9
7
  const SHELL_LIKE_TOOL_NAMES = new Set(['exec_command', 'shell_command', 'shell', 'bash', 'terminal']);
@@ -121,17 +119,13 @@ function resolveOptions(adapterContext, config) {
121
119
  return {
122
120
  ...DEFAULT_OPTIONS,
123
121
  strictToolRequired: readOptionalBoolean(config?.strictToolRequired) ?? DEFAULT_OPTIONS.strictToolRequired,
124
- textToolFallback: readOptionalBoolean(config?.textToolFallback) ?? DEFAULT_OPTIONS.textToolFallback,
125
122
  textNormalizer: config?.textNormalizer
126
123
  };
127
124
  }
128
125
  const strictOverride = readOptionalBoolean(config?.strictToolRequired);
129
- const fallbackOverride = readOptionalBoolean(config?.textToolFallback);
130
126
  return {
131
127
  strictToolRequired: strictOverride ??
132
128
  readBoolean(deepseekNode.strictToolRequired, DEFAULT_OPTIONS.strictToolRequired),
133
- textToolFallback: fallbackOverride ??
134
- readBoolean(deepseekNode.textToolFallback, DEFAULT_OPTIONS.textToolFallback),
135
129
  textNormalizer: config?.textNormalizer && typeof config.textNormalizer === 'object'
136
130
  ? config.textNormalizer
137
131
  : undefined
@@ -610,369 +604,6 @@ function normalizeMessageToolCalls(message, allowedToolNames, callIdPrefix) {
610
604
  message.content = null;
611
605
  return true;
612
606
  }
613
- function collectMessageTextCandidates(message) {
614
- const candidates = [];
615
- const content = message.content;
616
- if (typeof content === 'string' && content.trim().length) {
617
- candidates.push(content);
618
- }
619
- else if (Array.isArray(content)) {
620
- for (const part of content) {
621
- if (!isRecord(part)) {
622
- continue;
623
- }
624
- const text = readString(part.text) ?? readString(part.content);
625
- if (text) {
626
- candidates.push(text);
627
- }
628
- }
629
- }
630
- const reasoning = readString(message.reasoning) ?? readString(message.reasoning_content);
631
- if (reasoning) {
632
- candidates.push(reasoning);
633
- }
634
- return candidates;
635
- }
636
- function normalizeFunctionResultsMarkupText(value) {
637
- let changed = false;
638
- const replaced = value.replace(/<function_results>\s*([\s\S]*?)\s*<\/function_results>/gi, (_match, inner) => {
639
- changed = true;
640
- const payload = typeof inner === 'string' ? inner.trim() : '';
641
- if (!payload.length) {
642
- return '';
643
- }
644
- return `\n\`\`\`json\n${payload}\n\`\`\`\n`;
645
- });
646
- if (!changed) {
647
- return { text: value, changed: false };
648
- }
649
- return {
650
- text: replaced.replace(/\n{3,}/g, '\n\n').trim(),
651
- changed: true
652
- };
653
- }
654
- function normalizeCommentaryMarkupText(value) {
655
- const capturedCommentary = [];
656
- let changed = false;
657
- const stripped = value.replace(/<\s*commentary\s*>([\s\S]*?)<\s*\/\s*commentary\s*>/gi, (_match, inner) => {
658
- changed = true;
659
- const text = typeof inner === 'string' ? inner.trim() : '';
660
- if (text.length) {
661
- capturedCommentary.push(text);
662
- }
663
- return '';
664
- });
665
- if (!changed) {
666
- return { text: value, changed: false };
667
- }
668
- const collapsed = stripped.replace(/\n{3,}/g, '\n\n').trim();
669
- if (collapsed.length) {
670
- return { text: collapsed, changed: true };
671
- }
672
- return {
673
- text: capturedCommentary.join('\n\n').trim(),
674
- changed: true
675
- };
676
- }
677
- function harvestFunctionResultsMarkup(message) {
678
- let harvested = false;
679
- const apply = (input) => {
680
- if (typeof input !== 'string') {
681
- return undefined;
682
- }
683
- const functionResultsNormalized = normalizeFunctionResultsMarkupText(input);
684
- if (functionResultsNormalized.changed) {
685
- harvested = true;
686
- }
687
- const commentaryNormalized = normalizeCommentaryMarkupText(functionResultsNormalized.text);
688
- return commentaryNormalized.text;
689
- };
690
- if (typeof message.content === 'string') {
691
- const next = apply(message.content);
692
- if (typeof next === 'string') {
693
- message.content = next;
694
- }
695
- }
696
- else if (Array.isArray(message.content)) {
697
- for (const part of message.content) {
698
- if (!isRecord(part)) {
699
- continue;
700
- }
701
- if (typeof part.text === 'string') {
702
- const next = apply(part.text);
703
- if (typeof next === 'string') {
704
- part.text = next;
705
- }
706
- }
707
- if (typeof part.content === 'string') {
708
- const next = apply(part.content);
709
- if (typeof next === 'string') {
710
- part.content = next;
711
- }
712
- }
713
- }
714
- }
715
- if (typeof message.reasoning === 'string') {
716
- const next = apply(message.reasoning);
717
- if (typeof next === 'string') {
718
- message.reasoning = next;
719
- }
720
- }
721
- if (typeof message.reasoning_content === 'string') {
722
- const next = apply(message.reasoning_content);
723
- if (typeof next === 'string') {
724
- message.reasoning_content = next;
725
- }
726
- }
727
- return harvested;
728
- }
729
- function extractToolCallsFromDeepSeekJsonText(text, allowedToolNames, callIdPrefix) {
730
- const normalized = [];
731
- const trimmed = text.trim();
732
- if (!trimmed.length) {
733
- return normalized;
734
- }
735
- const parseCandidate = (candidate) => {
736
- if (!isRecord(candidate)) {
737
- return;
738
- }
739
- const calls = coerceToolCallsValue(candidate.tool_calls);
740
- for (const entry of calls) {
741
- if (!isRecord(entry)) {
742
- continue;
743
- }
744
- const call = normalizeToolCallEntry(entry, allowedToolNames, callIdPrefix, normalized.length);
745
- if (call) {
746
- normalized.push(call);
747
- }
748
- }
749
- };
750
- const standalonePayload = (() => {
751
- const trimDeepSeekTailArtifacts = (value) => {
752
- let out = value.trim();
753
- // Remove DeepSeek sentinel tails (e.g. <|end|>, <| User |>).
754
- out = out
755
- .replace(/(?:<[\u007C\uFF5C]\s*end[^>\n]*[\u007C\uFF5C]>\s*)+$/i, '')
756
- .replace(/(?:<[\u007C\uFF5C]\s*(?:user|assistant|system|tool|observation)[^>\n]*[\u007C\uFF5C]>\s*)+$/i, '')
757
- .trim();
758
- return out;
759
- };
760
- const extractLeadingJsonObject = (value) => {
761
- const trimmedValue = value.trimStart();
762
- if (!trimmedValue.startsWith('{')) {
763
- return undefined;
764
- }
765
- let depth = 0;
766
- let inString = false;
767
- let escaped = false;
768
- for (let i = 0; i < trimmedValue.length; i += 1) {
769
- const ch = trimmedValue[i] ?? '';
770
- if (inString) {
771
- if (escaped) {
772
- escaped = false;
773
- continue;
774
- }
775
- if (ch === '\\') {
776
- escaped = true;
777
- continue;
778
- }
779
- if (ch === '"') {
780
- inString = false;
781
- }
782
- continue;
783
- }
784
- if (ch === '"') {
785
- inString = true;
786
- continue;
787
- }
788
- if (ch === '{') {
789
- depth += 1;
790
- continue;
791
- }
792
- if (ch === '}') {
793
- depth -= 1;
794
- if (depth === 0) {
795
- return trimmedValue.slice(0, i + 1).trim();
796
- }
797
- continue;
798
- }
799
- }
800
- return undefined;
801
- };
802
- let candidate = trimDeepSeekTailArtifacts(trimmed);
803
- const fenced = candidate.match(/^```(?:json|tool_call|tool_calls)?\s*([\s\S]*?)\s*```/i);
804
- if (fenced?.[1]) {
805
- candidate = trimDeepSeekTailArtifacts(fenced[1]);
806
- }
807
- const leadingObject = extractLeadingJsonObject(candidate);
808
- if (!leadingObject) {
809
- return undefined;
810
- }
811
- if (!/["']tool_calls["']\s*:/.test(leadingObject)) {
812
- return undefined;
813
- }
814
- return leadingObject;
815
- })();
816
- if (standalonePayload) {
817
- const parsedRoot = tryParseJsonText(standalonePayload);
818
- if (parsedRoot !== null) {
819
- parseCandidate(parsedRoot);
820
- }
821
- }
822
- if (normalized.length === 0) {
823
- const sourceForRepair = standalonePayload ?? trimmed;
824
- const hasToolCallsMarker = /tool_calls/i.test(sourceForRepair);
825
- const hasApplyPatchMarker = /apply_patch/i.test(sourceForRepair);
826
- if (hasToolCallsMarker && hasApplyPatchMarker) {
827
- const patchMatch = sourceForRepair.match(/\*\*\*\s*Begin Patch[\s\S]*?\*\*\*\s*End Patch/);
828
- const patchText = readString(patchMatch?.[0]);
829
- const applyPatchAllowed = allowedToolNames.size === 0 || hasAllowedToolName(allowedToolNames, 'apply_patch');
830
- if (patchText && applyPatchAllowed) {
831
- const validation = validateToolCall('apply_patch', patchText);
832
- if (validation.ok && typeof validation.normalizedArgs === 'string' && validation.normalizedArgs.trim().length > 0) {
833
- normalized.push({
834
- id: `${callIdPrefix}_repair_1`,
835
- type: 'function',
836
- function: {
837
- name: 'apply_patch',
838
- arguments: validation.normalizedArgs
839
- }
840
- });
841
- }
842
- }
843
- }
844
- }
845
- return normalized;
846
- }
847
- function normalizeMessageTextToolCalls(message, allowedToolNames, callIdPrefix) {
848
- const candidates = collectMessageTextCandidates(message);
849
- if (!candidates.length) {
850
- return false;
851
- }
852
- for (const text of candidates) {
853
- const calls = extractToolCallsFromDeepSeekJsonText(text, allowedToolNames, callIdPrefix);
854
- if (!calls.length) {
855
- continue;
856
- }
857
- message.tool_calls = calls;
858
- message.content = null;
859
- return true;
860
- }
861
- return false;
862
- }
863
- function looksLikeShellCommand(value) {
864
- return /^(?:pnpm|npm|yarn|node|git|rg|ls|cat|find|sed|head|tail|rm|cp|mv|mkdir|bash|sh|zsh)\b/i.test(value.trim());
865
- }
866
- function parseJsonArrayCommand(value) {
867
- const trimmed = value.trim();
868
- if (!trimmed.startsWith('[') || !trimmed.endsWith(']')) {
869
- return undefined;
870
- }
871
- try {
872
- const parsed = JSON.parse(trimmed);
873
- if (!Array.isArray(parsed)) {
874
- return undefined;
875
- }
876
- const tokens = parsed
877
- .map((item) => (item == null ? '' : String(item)))
878
- .filter((item) => item.length > 0);
879
- if (!tokens.length) {
880
- return undefined;
881
- }
882
- return tokens.join(' ');
883
- }
884
- catch {
885
- return undefined;
886
- }
887
- }
888
- function normalizeCommandLine(raw) {
889
- return raw.trim().replace(/^\$\s*/, '').trim();
890
- }
891
- function extractCommandCandidates(text) {
892
- const commands = [];
893
- const seen = new Set();
894
- const push = (value) => {
895
- const normalized = value.trim();
896
- if (!normalized || seen.has(normalized)) {
897
- return;
898
- }
899
- seen.add(normalized);
900
- commands.push(normalized);
901
- };
902
- const blockPattern = /```(?:bash|sh|zsh)?\s*\n([\s\S]*?)```/gi;
903
- let blockMatch;
904
- while ((blockMatch = blockPattern.exec(text)) !== null) {
905
- const block = (blockMatch[1] ?? '').toString();
906
- const lines = block
907
- .split(/\r?\n/)
908
- .map((line) => normalizeCommandLine(line))
909
- .filter((line) => line.length > 0 && !line.startsWith('#'));
910
- if (!lines.length) {
911
- continue;
912
- }
913
- const first = lines[0];
914
- if (!looksLikeShellCommand(first)) {
915
- continue;
916
- }
917
- push(lines.join('\n'));
918
- }
919
- const linePattern = text.split(/\r?\n/);
920
- for (const raw of linePattern) {
921
- const line = raw.trim();
922
- if (!line.length || line.startsWith('```')) {
923
- continue;
924
- }
925
- const ran = line.match(/^(?:[•*+-]\s*)?Ran\s+(.+)$/i);
926
- if (ran?.[1]) {
927
- const payload = ran[1].trim();
928
- const parsedArray = parseJsonArrayCommand(payload);
929
- if (parsedArray && looksLikeShellCommand(parsedArray)) {
930
- push(parsedArray);
931
- continue;
932
- }
933
- if (looksLikeShellCommand(payload)) {
934
- push(payload);
935
- continue;
936
- }
937
- }
938
- const normalized = normalizeCommandLine(line);
939
- if (looksLikeShellCommand(normalized)) {
940
- push(normalized);
941
- }
942
- }
943
- return commands;
944
- }
945
- function normalizeMessageCommandToolCall(message, allowedToolNames, callIdPrefix) {
946
- const commandToolName = hasAllowedToolName(allowedToolNames, 'exec_command')
947
- ? 'exec_command'
948
- : hasAllowedToolName(allowedToolNames, 'shell_command')
949
- ? 'shell_command'
950
- : 'exec_command';
951
- const candidates = collectMessageTextCandidates(message);
952
- if (!candidates.length) {
953
- return false;
954
- }
955
- for (const text of candidates) {
956
- const commands = extractCommandCandidates(text);
957
- if (!commands.length) {
958
- continue;
959
- }
960
- const cmd = commands[commands.length - 1];
961
- message.tool_calls = [
962
- {
963
- id: `${callIdPrefix}_cmd_1`,
964
- type: 'function',
965
- function: {
966
- name: commandToolName,
967
- arguments: JSON.stringify({ cmd, command: cmd })
968
- }
969
- }
970
- ];
971
- message.content = null;
972
- return true;
973
- }
974
- return false;
975
- }
976
607
  function normalizeUsageSnapshot(raw) {
977
608
  if (!isRecord(raw)) {
978
609
  return {};
@@ -996,9 +627,20 @@ function estimateCompletionTokensFromChoices(choices, modelHint) {
996
627
  if (!message) {
997
628
  continue;
998
629
  }
999
- const candidates = collectMessageTextCandidates(message);
1000
- if (candidates.length) {
1001
- segments.push(...candidates);
630
+ const content = message.content;
631
+ if (typeof content === 'string' && content.trim().length) {
632
+ segments.push(content);
633
+ }
634
+ else if (Array.isArray(content)) {
635
+ for (const part of content) {
636
+ if (!isRecord(part)) {
637
+ continue;
638
+ }
639
+ const text = readString(part.text);
640
+ if (text) {
641
+ segments.push(text);
642
+ }
643
+ }
1002
644
  }
1003
645
  if (Array.isArray(message.tool_calls) && message.tool_calls.length) {
1004
646
  try {
@@ -1054,41 +696,10 @@ function normalizeChoice(choice, options, allowedToolNames, callIdPrefix) {
1054
696
  }
1055
697
  return { hasNative: true, hasFallback: false, harvestedFunctionResults: false };
1056
698
  }
1057
- if (!options.textToolFallback) {
1058
- return {
1059
- hasNative: false,
1060
- hasFallback: false,
1061
- harvestedFunctionResults: harvestFunctionResultsMarkup(message)
1062
- };
1063
- }
1064
- const transformed = normalizeAssistantTextToToolCalls(message, options.textNormalizer);
1065
- if (transformed !== message) {
1066
- choice.message = transformed;
1067
- }
1068
- const fallbackMessage = isRecord(choice.message) ? choice.message : message;
1069
- let fallback = normalizeMessageToolCalls(fallbackMessage, allowedToolNames, callIdPrefix);
1070
- if (!fallback) {
1071
- fallback = normalizeMessageTextToolCalls(fallbackMessage, allowedToolNames, callIdPrefix);
1072
- }
1073
- if (fallback) {
1074
- const finish = readString(choice.finish_reason)?.toLowerCase();
1075
- if (!finish || finish === 'stop') {
1076
- choice.finish_reason = 'tool_calls';
1077
- }
1078
- return { hasNative: false, hasFallback: true, harvestedFunctionResults: false };
1079
- }
1080
- const commandFallback = normalizeMessageCommandToolCall(fallbackMessage, allowedToolNames, callIdPrefix);
1081
- if (commandFallback) {
1082
- const finish = readString(choice.finish_reason)?.toLowerCase();
1083
- if (!finish || finish === 'stop') {
1084
- choice.finish_reason = 'tool_calls';
1085
- }
1086
- return { hasNative: false, hasFallback: true, harvestedFunctionResults: false };
1087
- }
1088
699
  return {
1089
700
  hasNative: false,
1090
701
  hasFallback: false,
1091
- harvestedFunctionResults: harvestFunctionResultsMarkup(fallbackMessage)
702
+ harvestedFunctionResults: false
1092
703
  };
1093
704
  }
1094
705
  function writeCompatState(root, state, source, harvestedFunctionResults) {
@@ -1139,7 +750,6 @@ export function applyDeepSeekWebResponseTransform(payload, adapterContext, confi
1139
750
  requestId: readString(adapterContext?.requestId),
1140
751
  phase: 'chat_process.resp.stage3.compat',
1141
752
  state,
1142
- fallbackEnabled: options.textToolFallback,
1143
753
  strictToolRequired: options.strictToolRequired
1144
754
  };
1145
755
  throw error;
@@ -1,5 +1,5 @@
1
1
  import { normalizeAssistantTextToToolCalls } from '../../shared/text-markup-normalizer.js';
2
- import { normalizeFunctionCallId } from '../../shared/bridge-id-utils.js';
2
+ import { normalizeFunctionCallId } from '../../bridge-id-utils.js';
3
3
  const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
4
4
  function pickString(...candidates) {
5
5
  for (const c of candidates) {
@@ -1,4 +1,4 @@
1
- import { normalizeFunctionCallId, normalizeFunctionCallOutputId, normalizeResponsesCallId } from '../../shared/bridge-id-utils.js';
1
+ import { normalizeFunctionCallId, normalizeFunctionCallOutputId, normalizeResponsesCallId } from '../../bridge-id-utils.js';
2
2
  function isRecord(value) {
3
3
  return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
4
4
  }
@@ -11,6 +11,15 @@ const FINISH_REASON_MAP = {
11
11
  content_filter: 'content_filter'
12
12
  };
13
13
  const isRecord = (value) => typeof value === 'object' && value !== null;
14
+ const readReasoningEffort = (value) => {
15
+ if (typeof value === 'string') {
16
+ return value;
17
+ }
18
+ if (isRecord(value) && typeof value.effort === 'string') {
19
+ return value.effort;
20
+ }
21
+ return undefined;
22
+ };
14
23
  export function applyQwenRequestTransform(payload) {
15
24
  const cloned = structuredClone(payload);
16
25
  const transformed = convertToQwenRequest(cloned);
@@ -132,6 +141,10 @@ function extractParameters(request) {
132
141
  if (typeof request.debug === 'boolean') {
133
142
  parameters.debug = request.debug;
134
143
  }
144
+ const reasoningEffort = readReasoningEffort(request.reasoning)?.toLowerCase();
145
+ if (reasoningEffort !== 'low') {
146
+ parameters.reasoning = true;
147
+ }
135
148
  return parameters;
136
149
  }
137
150
  function transformQwenResponseToOpenAI(response) {
@@ -154,6 +167,17 @@ function transformQwenResponseToOpenAI(response) {
154
167
  _originalFormat: 'qwen',
155
168
  _targetFormat: 'openai'
156
169
  };
170
+ const firstMessage = (() => {
171
+ const choices = Array.isArray(transformed.choices) ? transformed.choices : [];
172
+ const primary = choices[0] && isRecord(choices[0]) ? choices[0] : undefined;
173
+ const message = primary && isRecord(primary.message) ? primary.message : undefined;
174
+ return message;
175
+ })();
176
+ if (firstMessage && typeof firstMessage.reasoning_content === 'string' && firstMessage.reasoning_content.trim()) {
177
+ transformed.__responses_reasoning = {
178
+ content: [{ type: 'reasoning_text', text: String(firstMessage.reasoning_content).trim() }]
179
+ };
180
+ }
157
181
  return transformed;
158
182
  }
159
183
  function transformChoices(rawChoices) {
@@ -163,17 +187,65 @@ function transformChoices(rawChoices) {
163
187
  return rawChoices.map((choice, index) => {
164
188
  const choiceObj = isRecord(choice) ? choice : {};
165
189
  const messageObj = isRecord(choiceObj.message) ? choiceObj.message : {};
190
+ const contentDetails = extractContentAndReasoning(messageObj.content);
191
+ const reasoningText = mergeReasoningText(contentDetails?.reasoningText, readString(messageObj.reasoning_content) ?? readString(messageObj.reasoning));
166
192
  return {
167
193
  index: typeof choiceObj.index === 'number' ? choiceObj.index : index,
168
194
  message: {
169
195
  role: typeof messageObj.role === 'string' ? messageObj.role : 'assistant',
170
- content: typeof messageObj.content === 'string' ? messageObj.content : '',
171
- tool_calls: transformToolCalls(messageObj.tool_calls)
196
+ content: contentDetails?.contentText ?? (typeof messageObj.content === 'string' ? messageObj.content : ''),
197
+ tool_calls: transformToolCalls(messageObj.tool_calls),
198
+ ...(reasoningText ? { reasoning_content: reasoningText } : {})
172
199
  },
173
200
  finish_reason: transformFinishReason(typeof choiceObj.finish_reason === 'string' ? choiceObj.finish_reason : undefined)
174
201
  };
175
202
  });
176
203
  }
204
+ function readString(value) {
205
+ if (typeof value !== 'string') {
206
+ return undefined;
207
+ }
208
+ const trimmed = value.trim();
209
+ return trimmed.length ? trimmed : undefined;
210
+ }
211
+ function mergeReasoningText(primary, secondary) {
212
+ const parts = [primary, secondary].filter((item) => typeof item === 'string' && item.trim().length > 0);
213
+ if (parts.length === 0) {
214
+ return undefined;
215
+ }
216
+ return parts.join('\n');
217
+ }
218
+ function extractContentAndReasoning(content) {
219
+ if (!Array.isArray(content)) {
220
+ return null;
221
+ }
222
+ const contentParts = [];
223
+ const reasoningParts = [];
224
+ for (const chunk of content) {
225
+ if (typeof chunk === 'string') {
226
+ contentParts.push(chunk);
227
+ continue;
228
+ }
229
+ if (!isRecord(chunk)) {
230
+ continue;
231
+ }
232
+ const text = readString(chunk.text);
233
+ const type = typeof chunk.type === 'string' ? chunk.type.toLowerCase() : '';
234
+ const isThinking = Boolean(chunk.thought) || type === 'thinking' || type === 'reasoning';
235
+ if (text) {
236
+ if (isThinking) {
237
+ reasoningParts.push(text);
238
+ }
239
+ else {
240
+ contentParts.push(text);
241
+ }
242
+ }
243
+ }
244
+ return {
245
+ contentText: contentParts.join('\n'),
246
+ reasoningText: reasoningParts.length ? reasoningParts.join('\n') : undefined
247
+ };
248
+ }
177
249
  function transformToolCalls(toolCalls) {
178
250
  if (!Array.isArray(toolCalls)) {
179
251
  return [];
@@ -1,4 +1,4 @@
1
- import { writeSnapshotViaHooks } from '../../shared/snapshot-hooks.js';
1
+ import { writeSnapshotViaHooks } from '../../snapshot-utils.js';
2
2
  const SNAPSHOT_FLAG = String(process.env.ROUTECODEX_SNAPSHOT ?? '').toLowerCase();
3
3
  const SNAPSHOT_ENABLED = SNAPSHOT_FLAG === '1' || SNAPSHOT_FLAG === 'true';
4
4
  export async function writeCompatSnapshot(options) {
@@ -39,6 +39,13 @@ export function configureAntigravitySessionSignaturePersistence(input) {
39
39
  clearTimeout(prior.flushTimer);
40
40
  }
41
41
  setPersistenceState(null);
42
+ try {
43
+ delete process.env.ROUTECODEX_ANTIGRAVITY_SIGNATURE_STATE_DIR;
44
+ delete process.env.ROUTECODEX_ANTIGRAVITY_SIGNATURE_FILE;
45
+ }
46
+ catch {
47
+ // best-effort only
48
+ }
42
49
  return;
43
50
  }
44
51
  const stateDir = typeof input.stateDir === 'string' ? input.stateDir.trim() : '';
@@ -57,6 +64,13 @@ export function configureAntigravitySessionSignaturePersistence(input) {
57
64
  loadedOnce: false,
58
65
  flushTimer: null
59
66
  });
67
+ try {
68
+ process.env.ROUTECODEX_ANTIGRAVITY_SIGNATURE_STATE_DIR = stateDir;
69
+ process.env.ROUTECODEX_ANTIGRAVITY_SIGNATURE_FILE = fileName;
70
+ }
71
+ catch {
72
+ // best-effort only
73
+ }
60
74
  // Ensure we hydrate immediately so a short-lived process (or a server restart)
61
75
  // never flushes an empty in-memory cache over an existing persisted file.
62
76
  try {
@@ -484,6 +498,27 @@ function hydrateSignaturesFromDiskIfNeeded(force = false) {
484
498
  pinnedSessionByAlias.set(normalizedAlias, { sessionId, timestamp });
485
499
  }
486
500
  }
501
+ const syncNativeSignature = (cacheKey, entry) => {
502
+ const aliasKey = cacheKey.split('|')[0]?.trim() ?? '';
503
+ const sessionId = extractSessionIdFromCacheKey(cacheKey);
504
+ if (!aliasKey || !sessionId) {
505
+ return;
506
+ }
507
+ if (aliasKey === 'antigravity.unknown' || aliasKey === ANTIGRAVITY_GLOBAL_ALIAS_KEY) {
508
+ return;
509
+ }
510
+ try {
511
+ cacheAntigravitySessionSignatureWithNative({
512
+ aliasKey,
513
+ sessionId,
514
+ signature: entry.signature,
515
+ messageCount: entry.messageCount
516
+ });
517
+ }
518
+ catch {
519
+ // best-effort native sync; JS cache remains source of truth for persistence
520
+ }
521
+ };
487
522
  for (const [persistedKey, entry] of Object.entries(sessions)) {
488
523
  if (typeof persistedKey !== 'string' || !persistedKey.trim())
489
524
  continue;
@@ -509,6 +544,7 @@ function hydrateSignaturesFromDiskIfNeeded(force = false) {
509
544
  continue;
510
545
  }
511
546
  sessionSignatures.set(normalizedKey, entry);
547
+ syncNativeSignature(normalizedKey, entry);
512
548
  }
513
549
  }
514
550
  latestSignaturesByAlias.clear();