@jsonstudio/llms 0.6.2979 → 0.6.3214

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 (242) 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/chat-mapper.js +7 -4
  28. package/dist/conversion/hub/operation-table/semantic-mappers/gemini-mapper.js +2 -2
  29. package/dist/conversion/hub/operation-table/semantic-mappers/responses-mapper.js +2 -8
  30. package/dist/conversion/hub/pipeline/hub-pipeline.d.ts +1 -0
  31. package/dist/conversion/hub/pipeline/hub-pipeline.js +50 -3
  32. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.d.ts +1 -1
  33. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.js +62 -0
  34. package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage2_route_select/index.js +3 -1
  35. package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage1_sse_decode/index.js +1 -1
  36. package/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage1_client_remap/chat-process-semantics-bridge.d.ts +1 -1
  37. package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage1_tool_governance/index.js +42 -29
  38. package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage2_finalize/index.js +12 -0
  39. package/dist/conversion/hub/policy/protocol-spec.js +1 -1
  40. package/dist/conversion/hub/process/chat-process-clock-reminders.js +1 -1
  41. package/dist/conversion/hub/process/chat-process-clock-tools.js +1 -1
  42. package/dist/conversion/hub/process/chat-process-continue-execution.js +1 -1
  43. package/dist/conversion/hub/process/chat-process-servertool-orchestration.js +1 -1
  44. package/dist/conversion/hub/process/chat-process-web-search.js +1 -1
  45. package/dist/conversion/hub/response/provider-response.js +14 -5
  46. package/dist/conversion/hub/response/response-mappers.js +23 -1
  47. package/dist/conversion/hub/response/response-runtime.js +28 -5
  48. package/dist/conversion/hub/snapshot-recorder.js +1 -1
  49. package/dist/conversion/hub/tool-governance/engine.d.ts +8 -0
  50. package/dist/conversion/hub/tool-governance/engine.js +25 -68
  51. package/dist/conversion/hub/tool-governance/rules.js +73 -69
  52. package/dist/conversion/hub/tool-surface/tool-surface-engine.js +1 -1
  53. package/dist/conversion/index.d.ts +1 -2
  54. package/dist/conversion/index.js +1 -2
  55. package/dist/conversion/{shared/jsonish.js → jsonish.js} +1 -1
  56. package/dist/conversion/{shared/mcp-injection.js → mcp-injection.js} +1 -1
  57. package/dist/conversion/media.js +4 -0
  58. package/dist/conversion/{shared/metadata-passthrough.d.ts → metadata-passthrough.d.ts} +1 -1
  59. package/dist/conversion/{shared/metadata-passthrough.js → metadata-passthrough.js} +2 -2
  60. package/dist/conversion/payload-budget.js +47 -0
  61. package/dist/conversion/protocol-field-allowlists.d.ts +7 -0
  62. package/dist/conversion/protocol-field-allowlists.js +9 -0
  63. package/dist/conversion/{shared/protocol-state.d.ts → protocol-state.d.ts} +2 -2
  64. package/dist/conversion/{shared/protocol-state.js → protocol-state.js} +2 -2
  65. package/dist/conversion/{shared/errors.d.ts → provider-protocol-error.d.ts} +0 -3
  66. package/dist/conversion/provider-protocol-error.js +25 -0
  67. package/dist/conversion/responses/responses-openai-bridge/response-payload.js +8 -5
  68. package/dist/conversion/responses/responses-openai-bridge/types.d.ts +1 -1
  69. package/dist/conversion/responses/responses-openai-bridge.d.ts +1 -1
  70. package/dist/conversion/responses/responses-openai-bridge.js +43 -10
  71. package/dist/conversion/{shared/runtime-metadata.d.ts → runtime-metadata.d.ts} +1 -1
  72. package/dist/conversion/{shared/runtime-metadata.js → runtime-metadata.js} +2 -2
  73. package/dist/conversion/shared/anthropic-message-utils.js +19 -8
  74. package/dist/conversion/shared/chat-request-filters.d.ts +3 -4
  75. package/dist/conversion/shared/chat-request-filters.js +22 -78
  76. package/dist/conversion/shared/gemini-tool-utils.d.ts +1 -1
  77. package/dist/conversion/shared/openai-finalizer.js +1 -0
  78. package/dist/conversion/shared/openai-message-normalize.js +2 -2
  79. package/dist/conversion/shared/reasoning-normalizer.js +6 -0
  80. package/dist/conversion/shared/reasoning-utils.js +5 -2
  81. package/dist/conversion/shared/responses-conversation-store.js +1 -1
  82. package/dist/conversion/shared/responses-output-builder.js +55 -11
  83. package/dist/conversion/shared/responses-reasoning-registry.d.ts +14 -2
  84. package/dist/conversion/shared/responses-reasoning-registry.js +34 -6
  85. package/dist/conversion/shared/responses-response-utils.js +99 -9
  86. package/dist/conversion/shared/responses-tool-utils.js +1 -1
  87. package/dist/conversion/shared/text-markup-normalizer/normalize.d.ts +1 -1
  88. package/dist/conversion/shared/text-markup-normalizer.d.ts +2 -2
  89. package/dist/conversion/shared/text-markup-normalizer.js +1 -1
  90. package/dist/conversion/shared/tool-filter-pipeline.js +1 -1
  91. package/dist/conversion/shared/tool-governor.js +3 -3
  92. package/dist/conversion/shared/tool-mapping.d.ts +1 -1
  93. package/dist/conversion/{shared/snapshot-utils.d.ts → snapshot-utils.d.ts} +11 -0
  94. package/dist/conversion/{shared/snapshot-utils.js → snapshot-utils.js} +14 -23
  95. package/dist/conversion/types/text-markup-normalizer.d.ts +13 -0
  96. package/dist/conversion/types/text-markup-normalizer.js +1 -0
  97. package/dist/filters/special/request-tools-normalize.js +1 -1
  98. package/dist/filters/special/response-tool-text-canonicalize.js +2 -2
  99. package/dist/native/router_hotpath_napi.node +0 -0
  100. package/dist/quota/quota-manager.js +31 -59
  101. package/dist/quota/quota-state.js +14 -7
  102. package/dist/router/virtual-router/bootstrap/profile-builder.d.ts +1 -0
  103. package/dist/router/virtual-router/bootstrap/profile-builder.js +13 -0
  104. package/dist/router/virtual-router/bootstrap/provider-normalization.d.ts +2 -0
  105. package/dist/router/virtual-router/bootstrap/provider-normalization.js +4 -1
  106. package/dist/router/virtual-router/bootstrap/streaming-helpers.d.ts +7 -0
  107. package/dist/router/virtual-router/bootstrap/streaming-helpers.js +44 -0
  108. package/dist/router/virtual-router/bootstrap.js +2 -0
  109. package/dist/router/virtual-router/engine/routing-state/store.d.ts +1 -2
  110. package/dist/router/virtual-router/engine/routing-state/store.js +2 -2
  111. package/dist/router/virtual-router/engine-legacy/config.d.ts +11 -0
  112. package/dist/router/virtual-router/engine-legacy/config.js +108 -0
  113. package/dist/router/virtual-router/engine-legacy/direct-model.d.ts +10 -0
  114. package/dist/router/virtual-router/engine-legacy/direct-model.js +38 -0
  115. package/dist/router/virtual-router/engine-legacy/health.d.ts +13 -0
  116. package/dist/router/virtual-router/engine-legacy/health.js +104 -0
  117. package/dist/router/virtual-router/engine-legacy/helpers.d.ts +16 -0
  118. package/dist/router/virtual-router/engine-legacy/helpers.js +226 -0
  119. package/dist/router/virtual-router/engine-legacy/route-finalize.d.ts +9 -0
  120. package/dist/router/virtual-router/engine-legacy/route-finalize.js +84 -0
  121. package/dist/router/virtual-router/engine-legacy/route-selection.d.ts +17 -0
  122. package/dist/router/virtual-router/engine-legacy/route-selection.js +205 -0
  123. package/dist/router/virtual-router/engine-legacy/route-state-allowlist.d.ts +3 -0
  124. package/dist/router/virtual-router/engine-legacy/route-state-allowlist.js +36 -0
  125. package/dist/router/virtual-router/engine-legacy/route-state.d.ts +12 -0
  126. package/dist/router/virtual-router/engine-legacy/route-state.js +386 -0
  127. package/dist/router/virtual-router/engine-legacy/route-utils.d.ts +19 -0
  128. package/dist/router/virtual-router/engine-legacy/route-utils.js +212 -0
  129. package/dist/router/virtual-router/engine-legacy/routing.d.ts +8 -0
  130. package/dist/router/virtual-router/engine-legacy/routing.js +8 -0
  131. package/dist/router/virtual-router/engine-legacy/selection-core.d.ts +28 -0
  132. package/dist/router/virtual-router/engine-legacy/selection-core.js +112 -0
  133. package/dist/router/virtual-router/engine-legacy/selection-state.d.ts +16 -0
  134. package/dist/router/virtual-router/engine-legacy/selection-state.js +187 -0
  135. package/dist/router/virtual-router/engine-legacy/state-accessors.d.ts +21 -0
  136. package/dist/router/virtual-router/engine-legacy/state-accessors.js +118 -0
  137. package/dist/router/virtual-router/engine-legacy.d.ts +123 -0
  138. package/dist/router/virtual-router/engine-legacy.js +194 -0
  139. package/dist/router/virtual-router/engine-logging.d.ts +2 -0
  140. package/dist/router/virtual-router/engine-logging.js +7 -2
  141. package/dist/router/virtual-router/engine-selection/key-parsing.js +0 -3
  142. package/dist/router/virtual-router/engine-selection/native-chat-request-filter-semantics.d.ts +1 -0
  143. package/dist/router/virtual-router/engine-selection/native-chat-request-filter-semantics.js +54 -0
  144. package/dist/router/virtual-router/engine-selection/native-hub-bridge-policy-semantics.d.ts +10 -0
  145. package/dist/router/virtual-router/engine-selection/native-hub-bridge-policy-semantics.js +67 -0
  146. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-governance-semantics.d.ts +22 -0
  147. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-governance-semantics.js +154 -0
  148. package/dist/router/virtual-router/engine-selection/native-router-hotpath-loader.js +38 -2
  149. package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.d.ts +75 -0
  150. package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.js +205 -0
  151. package/dist/router/virtual-router/engine-selection/native-snapshot-hooks.d.ts +2 -0
  152. package/dist/router/virtual-router/engine-selection/native-snapshot-hooks.js +69 -0
  153. package/dist/router/virtual-router/engine-selection/native-virtual-router-engine-proxy.d.ts +16 -0
  154. package/dist/router/virtual-router/engine-selection/native-virtual-router-engine-proxy.js +14 -0
  155. package/dist/router/virtual-router/engine-selection/native-virtual-router-routing-instructions-semantics.d.ts +2 -0
  156. package/dist/router/virtual-router/engine-selection/native-virtual-router-routing-instructions-semantics.js +86 -0
  157. package/dist/router/virtual-router/engine-selection/tier-selection-quota-integration.js +100 -0
  158. package/dist/router/virtual-router/engine-selection/tier-selection-select.js +99 -0
  159. package/dist/router/virtual-router/engine.d.ts +22 -105
  160. package/dist/router/virtual-router/engine.js +274 -1641
  161. package/dist/router/virtual-router/load-balancer.d.ts +8 -0
  162. package/dist/router/virtual-router/load-balancer.js +65 -2
  163. package/dist/router/virtual-router/provider-registry.js +2 -0
  164. package/dist/router/virtual-router/routing-instructions/clean.d.ts +3 -0
  165. package/dist/router/virtual-router/routing-instructions/clean.js +34 -0
  166. package/dist/router/virtual-router/routing-instructions/parse.d.ts +18 -0
  167. package/dist/router/virtual-router/routing-instructions/parse.js +377 -0
  168. package/dist/router/virtual-router/routing-instructions/state.d.ts +4 -0
  169. package/dist/router/virtual-router/routing-instructions/state.js +245 -0
  170. package/dist/router/virtual-router/routing-instructions/types.d.ts +70 -0
  171. package/dist/router/virtual-router/routing-instructions/types.js +2 -0
  172. package/dist/router/virtual-router/routing-instructions.d.ts +5 -89
  173. package/dist/router/virtual-router/routing-instructions.js +4 -655
  174. package/dist/router/virtual-router/sticky-session-store.d.ts +4 -0
  175. package/dist/router/virtual-router/sticky-session-store.js +19 -81
  176. package/dist/router/virtual-router/tool-signals.js +21 -3
  177. package/dist/router/virtual-router/types.d.ts +4 -0
  178. package/dist/servertool/clock/session-scope.js +32 -1
  179. package/dist/servertool/engine.js +79 -8
  180. package/dist/servertool/handlers/antigravity-thought-signature-bootstrap.js +1 -1
  181. package/dist/servertool/handlers/clock-auto.js +1 -1
  182. package/dist/servertool/handlers/clock.js +1 -1
  183. package/dist/servertool/handlers/compaction-detect.d.ts +1 -1
  184. package/dist/servertool/handlers/compaction-detect.js +1 -1
  185. package/dist/servertool/handlers/gemini-empty-reply-continue.js +1 -1
  186. package/dist/servertool/handlers/iflow-model-error-retry.js +1 -1
  187. package/dist/servertool/handlers/recursive-detection-guard.js +1 -1
  188. package/dist/servertool/handlers/review.js +1 -1
  189. package/dist/servertool/handlers/stop-message-auto/iflow-followup.js +1 -1
  190. package/dist/servertool/handlers/stop-message-auto/runtime-utils.js +1 -1
  191. package/dist/servertool/handlers/stop-message-auto.js +1 -1
  192. package/dist/servertool/handlers/vision.js +1 -1
  193. package/dist/servertool/handlers/web-search.js +1 -1
  194. package/dist/servertool/reenter-backend.js +1 -1
  195. package/dist/servertool/server-side-tools.js +2 -2
  196. package/dist/servertool/stop-gateway-context.js +1 -1
  197. package/dist/servertool/stop-message-compare-context.js +1 -1
  198. package/dist/sse/json-to-sse/event-generators/responses.d.ts +4 -0
  199. package/dist/sse/json-to-sse/event-generators/responses.js +95 -1
  200. package/dist/sse/json-to-sse/sequencers/responses-sequencer.js +6 -4
  201. package/dist/sse/sse-to-json/builders/response-builder.d.ts +8 -0
  202. package/dist/sse/sse-to-json/builders/response-builder.js +162 -4
  203. package/dist/sse/sse-to-json/responses-sse-to-json-converter.js +2 -0
  204. package/dist/sse/types/responses-types.d.ts +6 -2
  205. package/dist/tools/apply-patch/structured/coercion.js +5 -0
  206. package/dist/tools/args-json.js +29 -0
  207. package/package.json +8 -5
  208. package/dist/conversion/shared/args-mapping.js +0 -77
  209. package/dist/conversion/shared/compaction-detect.js +0 -4
  210. package/dist/conversion/shared/errors.js +0 -31
  211. package/dist/conversion/shared/media.js +0 -4
  212. package/dist/conversion/shared/payload-budget.js +0 -165
  213. package/dist/conversion/shared/protocol-field-allowlists.d.ts +0 -7
  214. package/dist/conversion/shared/protocol-field-allowlists.js +0 -149
  215. package/dist/conversion/shared/snapshot-hooks.d.ts +0 -11
  216. package/dist/conversion/shared/snapshot-hooks.js +0 -503
  217. package/dist/conversion/shared/text-markup-normalizer/extractors-apply-patch.d.ts +0 -2
  218. package/dist/conversion/shared/text-markup-normalizer/extractors-apply-patch.js +0 -129
  219. package/dist/conversion/shared/text-markup-normalizer/extractors-json.d.ts +0 -4
  220. package/dist/conversion/shared/text-markup-normalizer/extractors-json.js +0 -637
  221. package/dist/conversion/shared/text-markup-normalizer/extractors-shared.d.ts +0 -21
  222. package/dist/conversion/shared/text-markup-normalizer/extractors-shared.js +0 -177
  223. package/dist/conversion/shared/text-markup-normalizer/extractors-transcript.d.ts +0 -5
  224. package/dist/conversion/shared/text-markup-normalizer/extractors-transcript.js +0 -385
  225. package/dist/conversion/shared/text-markup-normalizer/extractors-xml.d.ts +0 -10
  226. package/dist/conversion/shared/text-markup-normalizer/extractors-xml.js +0 -602
  227. package/dist/conversion/shared/text-markup-normalizer/extractors.d.ts +0 -5
  228. package/dist/conversion/shared/text-markup-normalizer/extractors.js +0 -4
  229. package/dist/conversion/shared/tool-canonicalizer.d.ts +0 -2
  230. package/dist/conversion/shared/tool-canonicalizer.js +0 -38
  231. /package/dist/conversion/{shared/args-mapping.d.ts → args-mapping.d.ts} +0 -0
  232. /package/dist/conversion/{shared/bridge-actions.d.ts → bridge-actions.d.ts} +0 -0
  233. /package/dist/conversion/{shared/bridge-id-utils.d.ts → bridge-id-utils.d.ts} +0 -0
  234. /package/dist/conversion/{shared/bridge-instructions.d.ts → bridge-instructions.d.ts} +0 -0
  235. /package/dist/conversion/{shared/bridge-metadata.d.ts → bridge-metadata.d.ts} +0 -0
  236. /package/dist/conversion/{shared/bridge-policies.d.ts → bridge-policies.d.ts} +0 -0
  237. /package/dist/conversion/{shared/jsonish.d.ts → jsonish.d.ts} +0 -0
  238. /package/dist/conversion/{shared/mcp-injection.d.ts → mcp-injection.d.ts} +0 -0
  239. /package/dist/conversion/{shared/media.d.ts → media.d.ts} +0 -0
  240. /package/dist/conversion/{shared/payload-budget.d.ts → payload-budget.d.ts} +0 -0
  241. /package/dist/conversion/{shared → types}/bridge-message-types.d.ts +0 -0
  242. /package/dist/conversion/{shared → types}/bridge-message-types.js +0 -0
@@ -1,13 +1,11 @@
1
- import { FilterEngine, RequestToolCallsStringifyFilter, RequestToolChoicePolicyFilter } from '../../filters/index.js';
2
1
  import { normalizeChatRequest } from '../index.js';
3
- import { loadFieldMapConfig } from '../../filters/utils/fieldmap-loader.js';
4
- import { createSnapshotWriter } from './snapshot-utils.js';
2
+ import { createSnapshotWriter } from '../snapshot-utils.js';
3
+ import { buildGovernedFilterPayloadWithNativeFallback } from '../../router/virtual-router/engine-selection/native-chat-request-filter-semantics.js';
5
4
  /**
6
- * 统一的 Chat 请求侧过滤链路。
5
+ * Native-primary Chat request filters.
7
6
  *
8
- * 目标:
9
- * - 所有进入 Provider 的 Chat 形状请求(无论入口为 /v1/chat、/v1/responses 还是 /v1/messages),
10
- * 都在这里走同一套工具治理与参数标准化逻辑。
7
+ * Historical TS FilterEngine implementation archived at:
8
+ * - src/conversion/shared/archive/chat-request-filters.ts
11
9
  */
12
10
  export async function runStandardChatRequestFilters(chatRequest, profile, context) {
13
11
  const existingMetadata = context.metadata ?? {};
@@ -15,18 +13,13 @@ export async function runStandardChatRequestFilters(chatRequest, profile, contex
15
13
  context.metadata = existingMetadata;
16
14
  }
17
15
  const inboundStreamFromContext = typeof existingMetadata.inboundStream === 'boolean' ? existingMetadata.inboundStream : undefined;
18
- const inboundStreamDetected = chatRequest && typeof chatRequest === 'object' && chatRequest.stream === true;
19
- const normalizedInboundStream = inboundStreamFromContext ?? inboundStreamDetected ?? undefined;
16
+ const inboundStreamDetected = chatRequest && typeof chatRequest === 'object' && chatRequest.stream === true ? true : undefined;
17
+ const normalizedInboundStream = inboundStreamFromContext ?? inboundStreamDetected;
20
18
  if (typeof normalizedInboundStream === 'boolean') {
21
19
  existingMetadata.inboundStream = normalizedInboundStream;
22
20
  }
23
21
  const requestId = context.requestId ?? `req_${Date.now()}`;
24
- const modelId = (chatRequest && typeof chatRequest === 'object' && typeof chatRequest.model === 'string')
25
- ? String(chatRequest.model)
26
- : 'unknown';
27
- const endpoint = context.entryEndpoint ||
28
- context.endpoint ||
29
- '/v1/chat/completions';
22
+ const endpoint = context.entryEndpoint || context.endpoint || '/v1/chat/completions';
30
23
  const snapshot = createSnapshotWriter({
31
24
  requestId,
32
25
  endpoint,
@@ -38,78 +31,29 @@ export async function runStandardChatRequestFilters(chatRequest, profile, contex
38
31
  snapshot(stage, payload);
39
32
  };
40
33
  snapshotStage('req_process_filters_input', chatRequest);
41
- const reqCtxBase = {
42
- requestId,
43
- model: modelId,
44
- endpoint,
45
- profile: profile.outgoingProtocol,
46
- debug: { emit: () => { } }
47
- };
48
- const engine = new FilterEngine();
49
34
  const incomingProtocol = (profile.incomingProtocol || '').toLowerCase();
50
- const entryEndpointLower = (endpoint || '').toLowerCase();
51
- const originalToolCount = (chatRequest && typeof chatRequest === 'object' && Array.isArray(chatRequest.tools))
35
+ const entryEndpointLower = endpoint.toLowerCase();
36
+ const originalToolCount = chatRequest && typeof chatRequest === 'object' && Array.isArray(chatRequest.tools)
52
37
  ? chatRequest.tools.length
53
38
  : 0;
54
39
  const isAnthropicProfile = incomingProtocol === 'anthropic-messages' ||
55
40
  entryEndpointLower.includes('/v1/messages');
56
41
  const skipAutoToolInjection = isAnthropicProfile && originalToolCount === 0;
57
- // Request-side initial filters(与 openai-openai-codec 保持一致)
58
- if (!skipAutoToolInjection) {
59
- try {
60
- const { RequestToolListFilter } = await import('../../filters/index.js');
61
- engine.registerFilter(new RequestToolListFilter());
62
- }
63
- catch {
64
- // 可选过滤器,失败时保持向后兼容
65
- }
66
- }
67
- engine.registerFilter(new RequestToolCallsStringifyFilter());
68
- engine.registerFilter(new RequestToolChoicePolicyFilter());
69
- // FieldMap:保持与 Chat 入口一致,使用 openai-openai.fieldmap.json
70
- try {
71
- const cfg = await loadFieldMapConfig('openai-openai.fieldmap.json');
72
- if (cfg)
73
- engine.setFieldMap(cfg);
74
- engine.registerTransform('stringifyJson', (v) => (typeof v === 'string'
75
- ? v
76
- : (() => {
77
- try {
78
- return JSON.stringify(v ?? {});
79
- }
80
- catch {
81
- return '{}';
82
- }
83
- })()));
84
- }
85
- catch {
86
- // best-effort:缺少 fieldmap 时保持原样
87
- }
88
- let staged = await engine.run('request_pre', chatRequest, reqCtxBase);
89
- snapshotStage('req_process_filters_request_pre', staged);
90
- staged = await engine.run('request_map', staged, reqCtxBase);
91
- snapshotStage('req_process_filters_request_map', staged);
92
- staged = await engine.run('request_post', staged, reqCtxBase);
93
- snapshotStage('req_process_filters_request_post', staged);
94
- if (skipAutoToolInjection && staged && typeof staged === 'object') {
95
- if (!Array.isArray(staged.tools)) {
96
- staged.tools = [];
42
+ const nativeGovernedPayload = buildGovernedFilterPayloadWithNativeFallback(chatRequest);
43
+ if (skipAutoToolInjection && nativeGovernedPayload && typeof nativeGovernedPayload === 'object') {
44
+ if (!Array.isArray(nativeGovernedPayload.tools)) {
45
+ nativeGovernedPayload.tools = [];
97
46
  }
98
- staged.__rcc_disable_mcp_tools = true;
47
+ nativeGovernedPayload.__rcc_disable_mcp_tools = true;
99
48
  }
100
- // 归一化 Chat 请求后再做最终工具治理
101
- let normalized = normalizeChatRequest(staged);
49
+ snapshotStage('req_process_filters_native_payload', nativeGovernedPayload);
50
+ let normalized = normalizeChatRequest(nativeGovernedPayload);
102
51
  snapshotStage('req_process_filters_normalized', normalized);
103
- try {
104
- const { RequestOpenAIToolsNormalizeFilter, ToolPostConstraintsFilter } = await import('../../filters/index.js');
105
- engine.registerFilter(new RequestOpenAIToolsNormalizeFilter());
106
- // 工具治理后的最后约束层:默认配置为空,由宿主/配置系统按 profile/provider/modelId 决定是否启用具体规则。
107
- engine.registerFilter(new ToolPostConstraintsFilter('request_finalize'));
108
- normalized = await engine.run('request_finalize', normalized, reqCtxBase);
109
- snapshotStage('req_process_filters_request_finalize', normalized);
110
- }
111
- catch {
112
- // 可选工具归一过滤器,失败时保持已归一化结果
52
+ if (skipAutoToolInjection && normalized && typeof normalized === 'object') {
53
+ if (!Array.isArray(normalized.tools)) {
54
+ normalized.tools = [];
55
+ }
56
+ normalized.__rcc_disable_mcp_tools = true;
113
57
  }
114
58
  const preserveStreamField = profile.incomingProtocol === 'openai-chat' && profile.outgoingProtocol === 'openai-chat';
115
59
  const pruned = pruneChatRequestPayload(normalized, { preserveStreamField });
@@ -1,4 +1,4 @@
1
- import type { BridgeToolDefinition } from './bridge-message-types.js';
1
+ import type { BridgeToolDefinition } from '../types/bridge-message-types.js';
2
2
  import type { MissingField } from '../hub/types/chat-envelope.js';
3
3
  import type { JsonValue, JsonObject } from '../hub/types/json.js';
4
4
  export declare function prepareGeminiToolsForBridge(rawTools: JsonValue | undefined, missing?: MissingField[]): BridgeToolDefinition[] | undefined;
@@ -151,6 +151,7 @@ function normalizeReasoningField(container, mode) {
151
151
  if (mode === 'append_to_content') {
152
152
  appendReasoningToContent(bag, trimmed);
153
153
  delete bag.reasoning_content;
154
+ return;
154
155
  }
155
156
  }
156
157
  function appendReasoningToContent(container, reasoning) {
@@ -1,4 +1,4 @@
1
- import { injectMcpToolsForChat } from './mcp-injection.js';
1
+ import { injectMcpToolsForChat } from '../mcp-injection.js';
2
2
  import { normalizeOpenaiChatMessagesWithNative, normalizeOpenaiMessageWithNative, normalizeOpenaiToolCallWithNative, normalizeOpenaiToolWithNative } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
3
3
  // Message normalization utilities for OpenAI chat payloads (renamed to avoid confusion
4
4
  // with the deprecated "openai-normalizer" module entry). This file contains the
@@ -209,4 +209,4 @@ function normalizeToolCall(tc) {
209
209
  const isDisabled = disableShellCoerce === '1' || disableShellCoerce === 'true';
210
210
  return normalizeOpenaiToolCallWithNative(tc, isDisabled);
211
211
  }
212
- import { resolveBudgetForModelSync } from './payload-budget.js';
212
+ import { resolveBudgetForModelSync } from '../payload-budget.js';
@@ -42,6 +42,9 @@ function normalizeChatChoice(choice) {
42
42
  containers.forEach(container => applyNormalizedChatContent(container));
43
43
  }
44
44
  function applyNormalizedChatContent(container) {
45
+ const existingReasoning = typeof container.reasoning_content === 'string' && container.reasoning_content.trim().length
46
+ ? container.reasoning_content.trim()
47
+ : undefined;
45
48
  const normalized = normalizeChatMessageContent(container.content);
46
49
  const role = typeof container.role === 'string' ? container.role : undefined;
47
50
  if (normalized.contentText !== undefined && normalized.contentText.trim().length) {
@@ -56,6 +59,9 @@ function applyNormalizedChatContent(container) {
56
59
  if (normalized.reasoningText && normalized.reasoningText.trim().length) {
57
60
  container.reasoning_content = normalized.reasoningText.trim();
58
61
  }
62
+ else if (existingReasoning) {
63
+ container.reasoning_content = existingReasoning;
64
+ }
59
65
  else if ('reasoning_content' in container) {
60
66
  delete container.reasoning_content;
61
67
  }
@@ -4,7 +4,8 @@ export function extractReasoningSegments(source, reasoningCollector) {
4
4
  const hasExplicitOpen = /<think>/i.test(source) ||
5
5
  /<reflection>/i.test(source) ||
6
6
  /```\s*(?:think|reflection)/i.test(source);
7
- const hasExplicitClose = /<\/think>/i.test(source) || /<\/reflection>/i.test(source);
7
+ const hasExplicitClose = /<\/think>/i.test(source) ||
8
+ /<\/reflection>/i.test(source);
8
9
  const push = (value) => {
9
10
  const trimmed = (value ?? '').trim();
10
11
  if (trimmed && reasoningCollector) {
@@ -22,7 +23,9 @@ export function extractReasoningSegments(source, reasoningCollector) {
22
23
  return '';
23
24
  });
24
25
  }
25
- working = working.replace(/<\/?think>/gi, '').replace(/<\/?reflection>/gi, '');
26
+ working = working
27
+ .replace(/<\/?think>/gi, '')
28
+ .replace(/<\/?reflection>/gi, '');
26
29
  working = working.replace(/\n{3,}/g, '\n\n');
27
30
  if (reasoningCollector && !hasExplicitOpen && hasExplicitClose) {
28
31
  const trimmed = working.trim();
@@ -1,4 +1,4 @@
1
- import { ProviderProtocolError } from './errors.js';
1
+ import { ProviderProtocolError } from '../provider-protocol-error.js';
2
2
  import { normalizeFunctionCallOutputIdWithNative as normalizeFunctionCallOutputId } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
3
3
  import { convertResponsesOutputToInputItemsWithNative, pickResponsesPersistedFieldsWithNative } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
4
4
  const TTL_MS = 1000 * 60 * 30; // 30min
@@ -1,4 +1,4 @@
1
- import { normalizeFunctionCallId, normalizeFunctionCallOutputId } from './bridge-id-utils.js';
1
+ import { normalizeFunctionCallId, normalizeFunctionCallOutputId } from '../bridge-id-utils.js';
2
2
  import { normalizeContentPart } from './output-content-normalizer.js';
3
3
  import { expandResponsesMessageItem } from '../../sse/shared/responses-output-normalizer.js';
4
4
  import { normalizeResponsesUsageWithNative } from '../../router/virtual-router/engine-selection/native-hub-pipeline-resp-semantics.js';
@@ -86,17 +86,28 @@ export function buildResponsesOutputFromChat(options) {
86
86
  }
87
87
  const hasToolCalls = toolCalls.length > 0;
88
88
  const reasoningChunks = [];
89
- const preservedReasoning = Array.isArray(response?.__responses_reasoning)
90
- ? response.__responses_reasoning
91
- : undefined;
92
- if (preservedReasoning && preservedReasoning.length) {
93
- reasoningChunks.push(...preservedReasoning);
89
+ const preservedReasoning = response?.__responses_reasoning;
90
+ const preservedSummary = preservedReasoning?.summary ?? [];
91
+ const preservedContent = preservedReasoning?.content ?? [];
92
+ const preservedEncrypted = preservedReasoning?.encrypted_content;
93
+ if (preservedContent.length) {
94
+ for (const entry of preservedContent) {
95
+ if (!entry || typeof entry !== 'object')
96
+ continue;
97
+ const text = String(entry.text ?? '').trim();
98
+ if (text.length) {
99
+ reasoningChunks.push(text);
100
+ }
101
+ }
94
102
  }
95
103
  else {
96
104
  appendReasoningSegments(reasoningChunks, message?.reasoning_content);
97
105
  }
98
106
  const convertedContent = convertChatContentToResponses(content);
99
- const shouldEmitMessage = Boolean(message) && (convertedContent.length > 0 || reasoningChunks.length > 0 || !hasToolCalls);
107
+ const shouldEmitMessage = Boolean(message) && (convertedContent.length > 0 ||
108
+ reasoningChunks.length > 0 ||
109
+ preservedSummary.length > 0 ||
110
+ !hasToolCalls);
100
111
  if (shouldEmitMessage) {
101
112
  const responsesMessage = {
102
113
  id: allocateOutputId('message'),
@@ -110,6 +121,28 @@ export function buildResponsesOutputFromChat(options) {
110
121
  outputIndex: outputItems.length,
111
122
  extraReasoning: reasoningChunks
112
123
  });
124
+ const summaryItems = preservedSummary
125
+ .map((entry) => ({ type: 'summary_text', text: String(entry.text ?? '') }))
126
+ .filter((entry) => entry.text.trim().length > 0);
127
+ let reasoningItem = expandedItems.find((item) => item.type === 'reasoning');
128
+ if (!reasoningItem && summaryItems.length > 0) {
129
+ reasoningItem = {
130
+ id: `${responsesMessage.id}_reasoning`,
131
+ type: 'reasoning',
132
+ summary: summaryItems,
133
+ content: undefined,
134
+ ...(typeof preservedEncrypted === 'string' ? { encrypted_content: preservedEncrypted } : {})
135
+ };
136
+ expandedItems.unshift(reasoningItem);
137
+ }
138
+ else if (reasoningItem) {
139
+ if (summaryItems.length > 0) {
140
+ reasoningItem.summary = summaryItems;
141
+ }
142
+ if (typeof preservedEncrypted === 'string') {
143
+ reasoningItem.encrypted_content = preservedEncrypted;
144
+ }
145
+ }
113
146
  for (const expanded of expandedItems) {
114
147
  outputItems.push(expanded);
115
148
  }
@@ -165,7 +198,14 @@ export function buildResponsesOutputFromChat(options) {
165
198
  };
166
199
  }
167
200
  function normalizeUsage(usageRaw) {
168
- return normalizeResponsesUsageWithNative(usageRaw);
201
+ if (usageRaw === null || usageRaw === undefined) {
202
+ return undefined;
203
+ }
204
+ const normalized = normalizeResponsesUsageWithNative(usageRaw);
205
+ if (normalized === null) {
206
+ return undefined;
207
+ }
208
+ return normalized;
169
209
  }
170
210
  function buildFunctionCallOutput(call, allocateOutputId, sanitizeFunctionName, baseCount, offset) {
171
211
  try {
@@ -265,9 +305,13 @@ function resolveOutputText(parts, meta) {
265
305
  if (meta && typeof meta === 'object') {
266
306
  const hasField = Boolean(meta.hasField);
267
307
  if (hasField) {
268
- const raw = meta.value;
269
- if (typeof raw === 'string') {
270
- return raw;
308
+ const rawValue = meta.raw;
309
+ if (typeof rawValue === 'string') {
310
+ return rawValue;
311
+ }
312
+ const fallbackValue = meta.value;
313
+ if (typeof fallbackValue === 'string') {
314
+ return fallbackValue;
271
315
  }
272
316
  return '';
273
317
  }
@@ -1,9 +1,21 @@
1
1
  export interface ResponsesOutputTextMeta {
2
2
  hasField: boolean;
3
3
  value?: string;
4
+ raw?: string;
4
5
  }
5
- export declare function registerResponsesReasoning(id: unknown, segments: string[] | undefined): void;
6
- export declare function consumeResponsesReasoning(id: unknown): string[] | undefined;
6
+ export interface ResponsesReasoningPayload {
7
+ summary?: Array<{
8
+ type: 'summary_text';
9
+ text: string;
10
+ }>;
11
+ content?: Array<{
12
+ type: 'reasoning_text' | 'text';
13
+ text: string;
14
+ }>;
15
+ encrypted_content?: string | null;
16
+ }
17
+ export declare function registerResponsesReasoning(id: unknown, reasoning: ResponsesReasoningPayload | undefined): void;
18
+ export declare function consumeResponsesReasoning(id: unknown): ResponsesReasoningPayload | undefined;
7
19
  export declare function registerResponsesOutputTextMeta(id: unknown, meta: ResponsesOutputTextMeta | undefined): void;
8
20
  export declare function consumeResponsesOutputTextMeta(id: unknown): ResponsesOutputTextMeta | undefined;
9
21
  export declare function registerResponsesPayloadSnapshot(id: unknown, snapshot: Record<string, unknown> | undefined): void;
@@ -38,13 +38,35 @@ function cloneSnapshot(snapshot) {
38
38
  return undefined;
39
39
  }
40
40
  }
41
- export function registerResponsesReasoning(id, segments) {
41
+ export function registerResponsesReasoning(id, reasoning) {
42
42
  if (typeof id !== 'string')
43
43
  return;
44
- if (!Array.isArray(segments) || segments.length === 0)
44
+ if (!reasoning)
45
+ return;
46
+ const summary = Array.isArray(reasoning.summary)
47
+ ? reasoning.summary
48
+ .map((item) => ({ type: 'summary_text', text: String(item.text ?? '').trim() }))
49
+ .filter((item) => item.text.length > 0)
50
+ : undefined;
51
+ const content = Array.isArray(reasoning.content)
52
+ ? reasoning.content
53
+ .map((item) => ({
54
+ type: item.type === 'text' ? 'text' : 'reasoning_text',
55
+ text: String(item.text ?? '').trim()
56
+ }))
57
+ .filter((item) => item.text.length > 0)
58
+ : undefined;
59
+ const hasSummary = Array.isArray(summary) && summary.length > 0;
60
+ const hasContent = Array.isArray(content) && content.length > 0;
61
+ const hasEncrypted = reasoning.encrypted_content !== undefined;
62
+ if (!hasSummary && !hasContent && !hasEncrypted)
45
63
  return;
46
64
  const entry = ensureEntry(id);
47
- entry.reasoning = [...segments];
65
+ entry.reasoning = {
66
+ summary: hasSummary ? summary : undefined,
67
+ content: hasContent ? content : undefined,
68
+ encrypted_content: reasoning.encrypted_content
69
+ };
48
70
  }
49
71
  export function consumeResponsesReasoning(id) {
50
72
  if (typeof id !== 'string')
@@ -52,7 +74,11 @@ export function consumeResponsesReasoning(id) {
52
74
  const entry = registry.get(id);
53
75
  if (!entry?.reasoning)
54
76
  return undefined;
55
- const value = [...entry.reasoning];
77
+ const value = {
78
+ summary: entry.reasoning.summary ? [...entry.reasoning.summary] : undefined,
79
+ content: entry.reasoning.content ? [...entry.reasoning.content] : undefined,
80
+ encrypted_content: entry.reasoning.encrypted_content
81
+ };
56
82
  entry.reasoning = undefined;
57
83
  pruneEntry(id);
58
84
  return value;
@@ -65,7 +91,8 @@ export function registerResponsesOutputTextMeta(id, meta) {
65
91
  const entry = ensureEntry(id);
66
92
  entry.outputText = {
67
93
  hasField: Boolean(meta.hasField),
68
- value: typeof meta.value === 'string' ? meta.value : undefined
94
+ value: typeof meta.value === 'string' ? meta.value : undefined,
95
+ raw: typeof meta.raw === 'string' ? meta.raw : undefined
69
96
  };
70
97
  }
71
98
  export function consumeResponsesOutputTextMeta(id) {
@@ -76,7 +103,8 @@ export function consumeResponsesOutputTextMeta(id) {
76
103
  return undefined;
77
104
  const value = {
78
105
  hasField: Boolean(entry.outputText.hasField),
79
- value: entry.outputText.value
106
+ value: entry.outputText.value,
107
+ raw: entry.outputText.raw
80
108
  };
81
109
  entry.outputText = undefined;
82
110
  pruneEntry(id);
@@ -1,6 +1,6 @@
1
1
  import { extractOutputSegments } from './output-content-normalizer.js';
2
- import { createBridgeActionState, runBridgeActionPipeline } from './bridge-actions.js';
3
- import { resolveBridgePolicy, resolvePolicyActions } from './bridge-policies.js';
2
+ import { createBridgeActionState, runBridgeActionPipeline } from '../bridge-actions.js';
3
+ import { resolveBridgePolicy, resolvePolicyActions } from '../bridge-policies.js';
4
4
  import { registerResponsesPayloadSnapshot, registerResponsesPassthrough } from './responses-reasoning-registry.js';
5
5
  import { normalizeFunctionCallIdWithNative, sanitizeReasoningTaggedTextWithNative } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
6
6
  import { sanitizeResponsesFunctionNameWithNative } from '../../router/virtual-router/engine-selection/native-hub-pipeline-resp-semantics.js';
@@ -153,6 +153,60 @@ function collectRawReasoningSegments(response) {
153
153
  }
154
154
  return segments;
155
155
  }
156
+ function collectReasoningSummarySegments(response) {
157
+ const segments = [];
158
+ const outputItems = Array.isArray(response.output) ? response.output : [];
159
+ for (const item of outputItems) {
160
+ if (!item || typeof item !== 'object')
161
+ continue;
162
+ const type = typeof item.type === 'string' ? String(item.type).toLowerCase() : '';
163
+ if (type !== 'reasoning')
164
+ continue;
165
+ const summary = Array.isArray(item.summary) ? item.summary : [];
166
+ for (const entry of summary) {
167
+ if (typeof entry === 'string') {
168
+ segments.push(entry);
169
+ continue;
170
+ }
171
+ if (entry && typeof entry === 'object' && typeof entry.text === 'string') {
172
+ segments.push(entry.text);
173
+ }
174
+ }
175
+ }
176
+ return segments;
177
+ }
178
+ function collectReasoningEncryptedContent(response) {
179
+ const outputItems = Array.isArray(response.output) ? response.output : [];
180
+ for (const item of outputItems) {
181
+ if (!item || typeof item !== 'object')
182
+ continue;
183
+ const type = typeof item.type === 'string' ? String(item.type).toLowerCase() : '';
184
+ if (type !== 'reasoning')
185
+ continue;
186
+ const encrypted = item.encrypted_content;
187
+ if (typeof encrypted === 'string' && encrypted.trim().length) {
188
+ return encrypted;
189
+ }
190
+ }
191
+ return undefined;
192
+ }
193
+ function buildReasoningPayload(options) {
194
+ const { summarySegments, contentSegments, encryptedContent } = options;
195
+ const summary = summarySegments.length
196
+ ? summarySegments.map((text) => ({ type: 'summary_text', text }))
197
+ : undefined;
198
+ const content = contentSegments.length
199
+ ? contentSegments.map((text) => ({ type: 'reasoning_text', text }))
200
+ : undefined;
201
+ if (!summary && !content && encryptedContent === undefined) {
202
+ return undefined;
203
+ }
204
+ return {
205
+ summary,
206
+ content,
207
+ encrypted_content: encryptedContent
208
+ };
209
+ }
156
210
  function registerPassthroughSnapshot(payload) {
157
211
  const ids = new Set();
158
212
  const requestId = typeof payload?.request_id === 'string' ? payload.request_id.trim() : '';
@@ -165,6 +219,23 @@ function registerPassthroughSnapshot(payload) {
165
219
  registerResponsesPassthrough(candidate, payload);
166
220
  }
167
221
  }
222
+ function cloneSnapshot(value) {
223
+ try {
224
+ const structuredCloneImpl = globalThis.structuredClone;
225
+ if (typeof structuredCloneImpl === 'function') {
226
+ return structuredCloneImpl(value);
227
+ }
228
+ }
229
+ catch {
230
+ /* ignore structuredClone failures */
231
+ }
232
+ try {
233
+ return JSON.parse(JSON.stringify(value));
234
+ }
235
+ catch {
236
+ return { ...value };
237
+ }
238
+ }
168
239
  export function buildChatResponseFromResponses(payload) {
169
240
  if (!payload || typeof payload !== 'object')
170
241
  return payload;
@@ -185,8 +256,13 @@ export function buildChatResponseFromResponses(payload) {
185
256
  const toolCalls = collectToolCallsFromResponses(response);
186
257
  const { textParts, reasoningParts } = extractOutputSegments(response);
187
258
  const rawReasoningSegments = collectRawReasoningSegments(response);
188
- const explicitOutput = typeof response.output_text === 'string' && response.output_text.trim().length
189
- ? sanitizeReasoningTaggedTextWithNative(response.output_text)
259
+ const summaryReasoningSegments = collectReasoningSummarySegments(response);
260
+ const encryptedReasoning = collectReasoningEncryptedContent(response);
261
+ const outputTextRaw = typeof response.output_text === 'string' && response.output_text.trim().length
262
+ ? response.output_text
263
+ : undefined;
264
+ const explicitOutput = typeof outputTextRaw === 'string'
265
+ ? sanitizeReasoningTaggedTextWithNative(outputTextRaw)
190
266
  : undefined;
191
267
  const messageContentText = explicitOutput || textParts.join('\n').trim();
192
268
  const messageContent = messageContentText || '';
@@ -218,7 +294,9 @@ export function buildChatResponseFromResponses(payload) {
218
294
  if (toolCalls.length) {
219
295
  message.tool_calls = toolCalls;
220
296
  }
221
- const reasoningSegments = rawReasoningSegments.length ? rawReasoningSegments : reasoningParts;
297
+ const reasoningSegments = rawReasoningSegments.length
298
+ ? rawReasoningSegments
299
+ : (reasoningParts.length ? reasoningParts : summaryReasoningSegments);
222
300
  if (reasoningSegments.length) {
223
301
  message.reasoning_content = reasoningSegments.join('\n');
224
302
  }
@@ -237,13 +315,18 @@ export function buildChatResponseFromResponses(payload) {
237
315
  ]
238
316
  };
239
317
  const hasOutputTextField = Object.prototype.hasOwnProperty.call(response, 'output_text');
240
- if (rawReasoningSegments.length) {
241
- chat.__responses_reasoning = rawReasoningSegments;
318
+ const reasoningPayload = buildReasoningPayload({
319
+ summarySegments: summaryReasoningSegments,
320
+ contentSegments: rawReasoningSegments.length ? rawReasoningSegments : reasoningParts,
321
+ encryptedContent: encryptedReasoning
322
+ });
323
+ if (reasoningPayload) {
324
+ chat.__responses_reasoning = reasoningPayload;
242
325
  }
243
326
  chat.__responses_output_text_meta = {
244
327
  hasField: hasOutputTextField,
245
- value: hasOutputTextField && typeof response.output_text === 'string'
246
- ? sanitizeReasoningTaggedTextWithNative(response.output_text)
328
+ value: typeof outputTextRaw === 'string'
329
+ ? sanitizeReasoningTaggedTextWithNative(outputTextRaw)
247
330
  : undefined
248
331
  };
249
332
  if (usage !== undefined) {
@@ -256,5 +339,12 @@ export function buildChatResponseFromResponses(payload) {
256
339
  chat.request_id = requestId;
257
340
  }
258
341
  registerResponsesPayloadSnapshot(id, response);
342
+ if (requestId && requestId !== id) {
343
+ registerResponsesPayloadSnapshot(requestId, response);
344
+ }
345
+ const snapshot = cloneSnapshot(response);
346
+ if (snapshot) {
347
+ chat.__responses_payload_snapshot = snapshot;
348
+ }
259
349
  return chat;
260
350
  }
@@ -1,4 +1,4 @@
1
- import { normalizeFunctionCallId, normalizeFunctionCallOutputId, normalizeResponsesCallId } from './bridge-id-utils.js';
1
+ import { normalizeFunctionCallId, normalizeFunctionCallOutputId, normalizeResponsesCallId } from '../bridge-id-utils.js';
2
2
  import { sanitizeResponsesFunctionNameWithNative } from '../../router/virtual-router/engine-selection/native-hub-pipeline-resp-semantics.js';
3
3
  export function createToolCallIdTransformer(style) {
4
4
  if (style !== 'fc') {
@@ -1,2 +1,2 @@
1
- import type { TextMarkupNormalizeOptions } from './extractors.js';
1
+ import type { TextMarkupNormalizeOptions } from '../../types/text-markup-normalizer.js';
2
2
  export declare function normalizeAssistantTextToToolCalls(message: Record<string, any>, _options?: TextMarkupNormalizeOptions): Record<string, any>;
@@ -1,4 +1,4 @@
1
- export type { JsonToolRepairConfig, TextMarkupNormalizeOptions, ToolCallLite } from './text-markup-normalizer/extractors.js';
2
- export { extractApplyPatchCallsFromText, extractBareExecCommandFromText, extractExecuteBlocksFromText, extractExploredListDirectoryCallsFromText, extractInvokeToolsFromText, extractJsonToolCallsFromText, extractParameterXmlToolsFromText, extractQwenToolCallTokensFromText, extractSimpleXmlToolsFromText, extractToolNamespaceXmlBlocksFromText, extractXMLToolCallsFromText } from './text-markup-normalizer/extractors.js';
1
+ export type { JsonToolRepairConfig, TextMarkupNormalizeOptions, ToolCallLite } from '../types/text-markup-normalizer.js';
2
+ export { extractApplyPatchCallsFromTextWithNative as extractApplyPatchCallsFromText, extractBareExecCommandFromTextWithNative as extractBareExecCommandFromText, extractExecuteBlocksFromTextWithNative as extractExecuteBlocksFromText, extractExploredListDirectoryCallsFromTextWithNative as extractExploredListDirectoryCallsFromText, extractInvokeToolsFromTextWithNative as extractInvokeToolsFromText, extractJsonToolCallsFromTextWithNative as extractJsonToolCallsFromText, extractParameterXmlToolsFromTextWithNative as extractParameterXmlToolsFromText, extractQwenToolCallTokensFromTextWithNative as extractQwenToolCallTokensFromText, extractSimpleXmlToolsFromTextWithNative as extractSimpleXmlToolsFromText, extractToolNamespaceXmlBlocksFromTextWithNative as extractToolNamespaceXmlBlocksFromText, extractXMLToolCallsFromTextWithNative as extractXMLToolCallsFromText } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
3
3
  export { normalizeAssistantTextToToolCalls } from './text-markup-normalizer/normalize.js';
4
4
  export { extractToolCallsFromReasoningTextWithNative, parseLenientJsonishWithNative, repairArgumentsToStringWithNative } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
@@ -1,3 +1,3 @@
1
- export { extractApplyPatchCallsFromText, extractBareExecCommandFromText, extractExecuteBlocksFromText, extractExploredListDirectoryCallsFromText, extractInvokeToolsFromText, extractJsonToolCallsFromText, extractParameterXmlToolsFromText, extractQwenToolCallTokensFromText, extractSimpleXmlToolsFromText, extractToolNamespaceXmlBlocksFromText, extractXMLToolCallsFromText } from './text-markup-normalizer/extractors.js';
1
+ export { extractApplyPatchCallsFromTextWithNative as extractApplyPatchCallsFromText, extractBareExecCommandFromTextWithNative as extractBareExecCommandFromText, extractExecuteBlocksFromTextWithNative as extractExecuteBlocksFromText, extractExploredListDirectoryCallsFromTextWithNative as extractExploredListDirectoryCallsFromText, extractInvokeToolsFromTextWithNative as extractInvokeToolsFromText, extractJsonToolCallsFromTextWithNative as extractJsonToolCallsFromText, extractParameterXmlToolsFromTextWithNative as extractParameterXmlToolsFromText, extractQwenToolCallTokensFromTextWithNative as extractQwenToolCallTokensFromText, extractSimpleXmlToolsFromTextWithNative as extractSimpleXmlToolsFromText, extractToolNamespaceXmlBlocksFromTextWithNative as extractToolNamespaceXmlBlocksFromText, extractXMLToolCallsFromTextWithNative as extractXMLToolCallsFromText } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
2
2
  export { normalizeAssistantTextToToolCalls } from './text-markup-normalizer/normalize.js';
3
3
  export { extractToolCallsFromReasoningTextWithNative, parseLenientJsonishWithNative, repairArgumentsToStringWithNative } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
@@ -1,6 +1,6 @@
1
1
  import { FilterEngine } from '../../filters/index.js';
2
2
  import { loadFieldMapConfig } from '../../filters/utils/fieldmap-loader.js';
3
- import { createSnapshotWriter } from './snapshot-utils.js';
3
+ import { createSnapshotWriter } from '../snapshot-utils.js';
4
4
  import { normalizeChatResponseReasoningToolsWithNative as normalizeChatResponseReasoningTools } from '../../router/virtual-router/engine-selection/native-hub-bridge-action-semantics.js';
5
5
  const REQUEST_FILTER_STAGES = [
6
6
  'request_pre',
@@ -6,7 +6,8 @@ import { augmentOpenAITools } from '../../guidance/index.js';
6
6
  import { validateToolCall } from '../../tools/tool-registry.js';
7
7
  import { captureApplyPatchRegression } from '../../tools/patch-regression-capturer.js';
8
8
  import { normalizeExecCommandArgs } from '../../tools/exec-command/normalize.js';
9
- import { readRuntimeMetadata } from './runtime-metadata.js';
9
+ import { readRuntimeMetadata } from '../runtime-metadata.js';
10
+ import { normalizeChatResponseReasoningToolsWithNative } from '../../router/virtual-router/engine-selection/native-hub-bridge-action-semantics.js';
10
11
  function isObject(v) { return !!v && typeof v === 'object' && !Array.isArray(v); }
11
12
  // Note: tool schema strict augmentation removed per alignment
12
13
  function enforceChatBudget(chat, _modelId) { return chat; }
@@ -639,8 +640,7 @@ export function processChatResponseTools(resp) {
639
640
  if (!isObject(resp))
640
641
  return resp;
641
642
  try {
642
- const { canonicalizeChatResponseTools } = require('./tool-canonicalizer.js');
643
- const canon = canonicalizeChatResponseTools(resp);
643
+ const canon = normalizeChatResponseReasoningToolsWithNative(resp);
644
644
  const withPatch = normalizeApplyPatchToolCallsOnResponse(canon);
645
645
  return enhanceResponseToolArguments(withPatch);
646
646
  }
@@ -1,5 +1,5 @@
1
1
  import type { ChatToolDefinition } from '../hub/types/chat-envelope.js';
2
- import type { BridgeToolDefinition } from './bridge-message-types.js';
2
+ import type { BridgeToolDefinition } from '../types/bridge-message-types.js';
3
3
  export interface ToolCallFunction {
4
4
  name: string;
5
5
  arguments: string;