@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,5 +1,13 @@
1
1
  import { DEFAULT_TOOL_GOVERNANCE_RULES } from './rules.js';
2
- import { sanitizeResponsesFunctionNameWithNative } from '../../../router/virtual-router/engine-selection/native-hub-pipeline-resp-semantics.js';
2
+ import { governRequestWithNative, governResponseWithNative } from '../../../router/virtual-router/engine-selection/native-hub-pipeline-governance-semantics.js';
3
+ /**
4
+ * Hybrid governance engine:
5
+ * - request path: native-primary
6
+ * - response path: native-primary
7
+ *
8
+ * Legacy-only snapshot retained at:
9
+ * - src/conversion/hub/tool-governance/archive/engine.legacy.ts
10
+ */
3
11
  export class ToolGovernanceError extends Error {
4
12
  protocol;
5
13
  direction;
@@ -43,24 +51,24 @@ export class ToolGovernanceEngine {
43
51
  summary: buildSummary(protocol, 'request', false)
44
52
  };
45
53
  }
46
- const stats = createStats(protocol, 'request');
47
- const sanitizedMessages = request.messages.map((msg) => sanitizeStandardizedMessage(msg, rules, stats));
48
- const sanitizedTools = request.tools?.map((tool) => sanitizeStandardizedTool(tool, rules, stats));
49
- const governed = {
50
- ...request,
51
- messages: sanitizedMessages,
52
- tools: sanitizedTools,
53
- metadata: {
54
- ...request.metadata,
55
- toolGovernance: {
56
- ...request.metadata?.toolGovernance,
57
- request: finalizeSummary(stats)
58
- }
54
+ let governed;
55
+ try {
56
+ governed = governRequestWithNative({
57
+ request: request,
58
+ protocol,
59
+ registry: this.registry
60
+ });
61
+ }
62
+ catch (error) {
63
+ const message = error instanceof Error ? error.message : String(error ?? 'unknown error');
64
+ if (message.includes('Tool name exceeds max length')) {
65
+ throw new ToolGovernanceError(message, protocol, 'request', 'tool.function.name');
59
66
  }
60
- };
67
+ throw error;
68
+ }
61
69
  return {
62
- request: governed,
63
- summary: finalizeSummary(stats)
70
+ request: governed.request,
71
+ summary: governed.summary
64
72
  };
65
73
  }
66
74
  governResponse(payload, protocol) {
@@ -71,18 +79,24 @@ export class ToolGovernanceEngine {
71
79
  summary: buildSummary(protocol, 'response', false)
72
80
  };
73
81
  }
74
- const stats = createStats(protocol, 'response');
75
- const cloned = JSON.parse(JSON.stringify(payload));
76
- const choices = Array.isArray(cloned?.choices) ? cloned.choices : [];
77
- for (const choice of choices) {
78
- sanitizeChatCompletionChoice(choice, rules, stats);
82
+ let governed;
83
+ try {
84
+ governed = governResponseWithNative({
85
+ payload: payload,
86
+ protocol,
87
+ registry: this.registry
88
+ });
79
89
  }
80
- if (Array.isArray(cloned?.tool_calls)) {
81
- cloned.tool_calls = cloned.tool_calls.map((tc) => sanitizeChatCompletionToolCall(tc, rules, stats));
90
+ catch (error) {
91
+ const message = error instanceof Error ? error.message : String(error ?? 'unknown error');
92
+ if (message.includes('Tool name exceeds max length')) {
93
+ throw new ToolGovernanceError(message, protocol, 'response', 'tool.function.name');
94
+ }
95
+ throw error;
82
96
  }
83
97
  return {
84
- payload: cloned,
85
- summary: finalizeSummary(stats)
98
+ payload: governed.payload,
99
+ summary: governed.summary
86
100
  };
87
101
  }
88
102
  resolveRules(protocol, direction) {
@@ -91,173 +105,6 @@ export class ToolGovernanceEngine {
91
105
  return entry?.[direction];
92
106
  }
93
107
  }
94
- function sanitizeStandardizedMessage(message, rules, stats) {
95
- let changed = false;
96
- const next = { ...message };
97
- if (Array.isArray(message.tool_calls) && message.tool_calls.length) {
98
- next.tool_calls = message.tool_calls.map((call) => sanitizeToolCall(call, rules, stats));
99
- if (next.tool_calls !== message.tool_calls) {
100
- changed = true;
101
- }
102
- }
103
- if (typeof message.name === 'string' || message.role === 'tool') {
104
- const sanitizedName = sanitizeName(message.name, rules, stats, 'message.name');
105
- if (sanitizedName !== message.name) {
106
- next.name = sanitizedName;
107
- changed = true;
108
- }
109
- }
110
- return changed ? next : message;
111
- }
112
- function sanitizeStandardizedTool(tool, rules, stats) {
113
- const sanitizedName = sanitizeName(tool.function?.name, rules, stats, 'tool.function.name');
114
- if (sanitizedName === tool.function?.name) {
115
- return tool;
116
- }
117
- return {
118
- ...tool,
119
- function: {
120
- ...tool.function,
121
- name: sanitizedName
122
- }
123
- };
124
- }
125
- function sanitizeToolCall(call, rules, stats) {
126
- if (!call?.function) {
127
- return call;
128
- }
129
- const sanitizedName = sanitizeName(call.function.name, rules, stats, 'tool_call.function.name');
130
- if (sanitizedName === call.function.name) {
131
- return call;
132
- }
133
- return {
134
- ...call,
135
- function: {
136
- ...call.function,
137
- name: sanitizedName
138
- }
139
- };
140
- }
141
- function sanitizeChatCompletionChoice(choice, rules, stats) {
142
- const message = choice?.message;
143
- if (!message || typeof message !== 'object') {
144
- return;
145
- }
146
- const msg = message;
147
- if (Array.isArray(msg.tool_calls)) {
148
- msg.tool_calls = msg.tool_calls.map((tc, index) => sanitizeChatCompletionToolCall(tc, rules, stats, `choices[].message.tool_calls[${index}].function.name`));
149
- }
150
- if (msg.function_call && typeof msg.function_call === 'object') {
151
- const orig = msg.function_call.name;
152
- const sanitizedName = sanitizeName(orig, rules, stats, 'choices[].message.function_call.name');
153
- msg.function_call.name = sanitizedName;
154
- }
155
- if (typeof msg.name === 'string' || msg.role === 'tool') {
156
- msg.name = sanitizeName(msg.name, rules, stats, 'choices[].message.name');
157
- }
158
- }
159
- function sanitizeChatCompletionToolCall(tc, rules, stats, context = 'choices[].message.tool_calls[].function.name') {
160
- if (!tc || typeof tc !== 'object') {
161
- return tc;
162
- }
163
- const fn = tc.function;
164
- if (!fn || typeof fn !== 'object') {
165
- return tc;
166
- }
167
- const sanitizedName = sanitizeName(fn.name, rules, stats, context);
168
- if (sanitizedName === fn.name) {
169
- return tc;
170
- }
171
- return {
172
- ...tc,
173
- function: {
174
- ...fn,
175
- name: sanitizedName
176
- }
177
- };
178
- }
179
- function createStats(protocol, direction) {
180
- return {
181
- protocol,
182
- direction,
183
- applied: false,
184
- sanitizedNames: 0,
185
- truncatedNames: 0,
186
- defaultedNames: 0
187
- };
188
- }
189
- function sanitizeName(rawName, rules, stats, field) {
190
- const defaultName = rules.defaultName ?? 'tool';
191
- let next = typeof rawName === 'string' ? rawName : '';
192
- const nativeSanitized = sanitizeResponsesFunctionNameWithNative(next);
193
- if (typeof nativeSanitized === 'string' && nativeSanitized.trim().length) {
194
- next = nativeSanitized;
195
- }
196
- let changed = false;
197
- if (rules.trimWhitespace !== false) {
198
- next = next.trim();
199
- }
200
- if (!next) {
201
- next = defaultName;
202
- stats.defaultedNames += 1;
203
- changed = true;
204
- }
205
- if (rules.forceCase === 'lower') {
206
- const forced = next.toLowerCase();
207
- if (forced !== next) {
208
- next = forced;
209
- changed = true;
210
- }
211
- }
212
- else if (rules.forceCase === 'upper') {
213
- const forced = next.toUpperCase();
214
- if (forced !== next) {
215
- next = forced;
216
- changed = true;
217
- }
218
- }
219
- if (rules.allowedCharacters) {
220
- const matcher = new RegExp(rules.allowedCharacters.source);
221
- const filtered = next
222
- .split('')
223
- .filter((ch) => matcher.test(ch))
224
- .join('');
225
- matcher.lastIndex = 0;
226
- if (filtered.length === 0) {
227
- next = defaultName;
228
- stats.defaultedNames += 1;
229
- changed = true;
230
- }
231
- else if (filtered !== next) {
232
- next = filtered;
233
- changed = true;
234
- }
235
- }
236
- if (rules.maxNameLength && next.length > rules.maxNameLength) {
237
- if (rules.onViolation === 'reject') {
238
- throw new ToolGovernanceError(`Tool name exceeds max length of ${rules.maxNameLength}`, stats.protocol, stats.direction, field);
239
- }
240
- next = next.slice(0, rules.maxNameLength);
241
- stats.truncatedNames += 1;
242
- changed = true;
243
- }
244
- if (changed || (typeof rawName === 'string' && rawName !== next)) {
245
- stats.sanitizedNames += 1;
246
- }
247
- stats.applied = true;
248
- return next || defaultName;
249
- }
250
- function finalizeSummary(stats) {
251
- return {
252
- protocol: stats.protocol,
253
- direction: stats.direction,
254
- applied: stats.applied,
255
- sanitizedNames: stats.sanitizedNames,
256
- truncatedNames: stats.truncatedNames,
257
- defaultedNames: stats.defaultedNames,
258
- timestamp: Date.now()
259
- };
260
- }
261
108
  function buildSummary(protocol, direction, applied) {
262
109
  return {
263
110
  protocol,
@@ -1,76 +1,80 @@
1
- import { sanitizeResponsesFunctionNameWithNative } from '../../../router/virtual-router/engine-selection/native-hub-pipeline-resp-semantics.js';
1
+ import { resolveDefaultToolGovernanceRulesWithNative } from '../../../router/virtual-router/engine-selection/native-hub-pipeline-governance-semantics.js';
2
2
  const ALPHA_NUMERIC = /[A-Za-z0-9_-]/;
3
3
  const LOWER_SNAKE = /[a-z0-9_-]/;
4
4
  function clonePattern(pattern) {
5
5
  const flags = pattern.flags.replace(/g/g, '');
6
6
  return new RegExp(pattern.source, flags);
7
7
  }
8
- const DEFAULT_TOOL_NAME = sanitizeResponsesFunctionNameWithNative('tool') ?? 'tool';
9
- export const DEFAULT_TOOL_GOVERNANCE_RULES = {
10
- 'openai-chat': {
11
- request: {
12
- maxNameLength: 64,
13
- allowedCharacters: clonePattern(ALPHA_NUMERIC),
14
- defaultName: DEFAULT_TOOL_NAME,
15
- trimWhitespace: true,
16
- onViolation: 'truncate'
17
- },
18
- response: {
19
- maxNameLength: 64,
20
- allowedCharacters: clonePattern(ALPHA_NUMERIC),
21
- defaultName: DEFAULT_TOOL_NAME,
22
- trimWhitespace: true,
23
- onViolation: 'truncate'
24
- }
25
- },
26
- 'openai-responses': {
27
- request: {
28
- maxNameLength: 64,
29
- allowedCharacters: clonePattern(ALPHA_NUMERIC),
30
- defaultName: DEFAULT_TOOL_NAME,
31
- trimWhitespace: true,
32
- onViolation: 'truncate'
33
- },
34
- response: {
35
- maxNameLength: 64,
36
- allowedCharacters: clonePattern(ALPHA_NUMERIC),
37
- defaultName: DEFAULT_TOOL_NAME,
38
- trimWhitespace: true,
39
- onViolation: 'truncate'
40
- }
41
- },
42
- anthropic: {
43
- request: {
44
- maxNameLength: 64,
45
- allowedCharacters: clonePattern(LOWER_SNAKE),
46
- forceCase: 'lower',
47
- defaultName: DEFAULT_TOOL_NAME,
48
- trimWhitespace: true,
49
- onViolation: 'truncate'
50
- },
51
- response: {
52
- maxNameLength: 64,
53
- allowedCharacters: clonePattern(LOWER_SNAKE),
54
- forceCase: 'lower',
55
- defaultName: DEFAULT_TOOL_NAME,
56
- trimWhitespace: true,
57
- onViolation: 'truncate'
58
- }
59
- },
60
- gemini: {
61
- request: {
62
- maxNameLength: 64,
63
- allowedCharacters: clonePattern(ALPHA_NUMERIC),
64
- defaultName: DEFAULT_TOOL_NAME,
65
- trimWhitespace: true,
66
- onViolation: 'truncate'
67
- },
68
- response: {
69
- maxNameLength: 64,
70
- allowedCharacters: clonePattern(ALPHA_NUMERIC),
71
- defaultName: DEFAULT_TOOL_NAME,
72
- trimWhitespace: true,
73
- onViolation: 'truncate'
74
- }
8
+ function mapAllowedCharacters(token, fallback) {
9
+ const normalized = String(token || '').trim().toLowerCase();
10
+ if (normalized === 'lower_snake') {
11
+ return clonePattern(LOWER_SNAKE);
75
12
  }
76
- };
13
+ return clonePattern(fallback);
14
+ }
15
+ function mapNativeRules(nativeRules, fallback) {
16
+ if (!nativeRules || typeof nativeRules !== 'object') {
17
+ return undefined;
18
+ }
19
+ return {
20
+ maxNameLength: typeof nativeRules.maxNameLength === 'number' && Number.isFinite(nativeRules.maxNameLength)
21
+ ? Math.max(1, Math.floor(nativeRules.maxNameLength))
22
+ : fallback.maxNameLength,
23
+ allowedCharacters: mapAllowedCharacters(nativeRules.allowedCharacters, fallback.allowedCharacters),
24
+ defaultName: typeof nativeRules.defaultName === 'string' && nativeRules.defaultName.trim().length
25
+ ? nativeRules.defaultName.trim()
26
+ : fallback.defaultName,
27
+ trimWhitespace: nativeRules.trimWhitespace !== false,
28
+ ...(nativeRules.forceCase === 'lower' || nativeRules.forceCase === 'upper'
29
+ ? { forceCase: nativeRules.forceCase }
30
+ : {}),
31
+ onViolation: nativeRules.onViolation === 'reject' ? 'reject' : 'truncate'
32
+ };
33
+ }
34
+ function mapProtocolNode(nativeNode, options) {
35
+ const defaultName = 'tool';
36
+ const maxNameLength = 64;
37
+ const fallbackBase = {
38
+ allowedCharacters: options.allowedCharacters,
39
+ defaultName,
40
+ maxNameLength
41
+ };
42
+ const request = mapNativeRules(nativeNode?.request, fallbackBase) ?? {
43
+ ...fallbackBase,
44
+ trimWhitespace: true,
45
+ onViolation: 'truncate',
46
+ ...(options.forceCase ? { forceCase: options.forceCase } : {})
47
+ };
48
+ const response = mapNativeRules(nativeNode?.response, fallbackBase) ?? {
49
+ ...fallbackBase,
50
+ trimWhitespace: true,
51
+ onViolation: 'truncate',
52
+ ...(options.forceCase ? { forceCase: options.forceCase } : {})
53
+ };
54
+ if (options.forceCase) {
55
+ request.forceCase = options.forceCase;
56
+ response.forceCase = options.forceCase;
57
+ }
58
+ return {
59
+ request,
60
+ response
61
+ };
62
+ }
63
+ function mapNativeRegistry(nativeRegistry) {
64
+ return {
65
+ 'openai-chat': mapProtocolNode(nativeRegistry['openai-chat'], {
66
+ allowedCharacters: ALPHA_NUMERIC
67
+ }),
68
+ 'openai-responses': mapProtocolNode(nativeRegistry['openai-responses'], {
69
+ allowedCharacters: ALPHA_NUMERIC
70
+ }),
71
+ anthropic: mapProtocolNode(nativeRegistry.anthropic, {
72
+ allowedCharacters: LOWER_SNAKE,
73
+ forceCase: 'lower'
74
+ }),
75
+ gemini: mapProtocolNode(nativeRegistry.gemini, {
76
+ allowedCharacters: ALPHA_NUMERIC
77
+ })
78
+ };
79
+ }
80
+ export const DEFAULT_TOOL_GOVERNANCE_RULES = mapNativeRegistry(resolveDefaultToolGovernanceRulesWithNative());
@@ -2,7 +2,7 @@ import { isJsonObject, jsonClone } from '../types/json.js';
2
2
  import { mapBridgeToolsToChat, mapChatToolsToBridge } from '../../shared/tool-mapping.js';
3
3
  import { buildGeminiToolsFromBridge, prepareGeminiToolsForBridge } from '../../shared/gemini-tool-utils.js';
4
4
  import { mapAnthropicToolsToChat, mapChatToolsToAnthropicTools } from '../../shared/anthropic-message-utils.js';
5
- import { convertBridgeInputToChatMessages, convertMessagesToBridgeInput } from '../../shared/bridge-message-utils.js';
5
+ import { convertBridgeInputToChatMessages, convertMessagesToBridgeInput } from '../../bridge-message-utils.js';
6
6
  import { resolveHubProtocolSpec } from '../policy/protocol-spec.js';
7
7
  import { normalizeProviderProtocolTokenWithNative } from '../../../router/virtual-router/engine-selection/native-hub-pipeline-req-inbound-semantics.js';
8
8
  function clampSampleRate(value) {
@@ -19,9 +19,8 @@ export * from './shared/tooling.js';
19
19
  export * from '../guidance/index.js';
20
20
  export * from './shared/tool-mapping.js';
21
21
  export * from './shared/reasoning-mapping.js';
22
- export * from './shared/args-mapping.js';
22
+ export * from './args-mapping.js';
23
23
  export * from './shared/text-markup-normalizer.js';
24
- export * from './shared/tool-canonicalizer.js';
25
24
  export * from './shared/tool-governor.js';
26
25
  export { governTools } from './shared/tool-governor.js';
27
26
  export * from './shared/streaming-text-extractor.js';
@@ -19,9 +19,8 @@ export * from './shared/tooling.js';
19
19
  export * from '../guidance/index.js';
20
20
  export * from './shared/tool-mapping.js';
21
21
  export * from './shared/reasoning-mapping.js';
22
- export * from './shared/args-mapping.js';
22
+ export * from './args-mapping.js';
23
23
  export * from './shared/text-markup-normalizer.js';
24
- export * from './shared/tool-canonicalizer.js';
25
24
  export * from './shared/tool-governor.js';
26
25
  export { governTools } from './shared/tool-governor.js';
27
26
  export * from './shared/streaming-text-extractor.js';
@@ -1,5 +1,5 @@
1
1
  // Shared JSON-ish parsing helpers
2
- import { parseLenientJsonishWithNative, repairArgumentsToStringWithNative } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
2
+ import { parseLenientJsonishWithNative, repairArgumentsToStringWithNative } from '../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
3
3
  export function tryParseJson(s) {
4
4
  if (typeof s !== 'string')
5
5
  return s;
@@ -1,4 +1,4 @@
1
- import { injectMcpToolsForChatWithNative, injectMcpToolsForResponsesWithNative } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
1
+ import { injectMcpToolsForChatWithNative, injectMcpToolsForResponsesWithNative } from '../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
2
2
  export function injectMcpToolsForChat(tools, discoveredServers) {
3
3
  return injectMcpToolsForChatWithNative(tools, discoveredServers);
4
4
  }
@@ -0,0 +1,4 @@
1
+ import { isImagePathWithNative } from '../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
2
+ export function isImagePath(p) {
3
+ return isImagePathWithNative(p);
4
+ }
@@ -1,4 +1,4 @@
1
- import { type JsonObject, type JsonValue } from '../hub/types/json.js';
1
+ import { type JsonObject, type JsonValue } from './hub/types/json.js';
2
2
  interface PassthroughOptions {
3
3
  prefix: string;
4
4
  keys: readonly string[];
@@ -1,5 +1,5 @@
1
- import { isJsonObject, jsonClone } from '../hub/types/json.js';
2
- import { encodeMetadataPassthroughWithNative, extractMetadataPassthroughWithNative } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
1
+ import { isJsonObject, jsonClone } from './hub/types/json.js';
2
+ import { encodeMetadataPassthroughWithNative, extractMetadataPassthroughWithNative } from '../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
3
3
  export function encodeMetadataPassthrough(parameters, options) {
4
4
  return encodeMetadataPassthroughWithNative(parameters, options.prefix, options.keys);
5
5
  }
@@ -0,0 +1,47 @@
1
+ // Resolve payload budget (bytes) for a given model from host app config, with safety headroom.
2
+ import { UnifiedConfig } from '../config-unified/unified-config.js';
3
+ import { enforceChatBudgetWithNative, resolveBudgetForModelWithNative } from '../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
4
+ export function resolveBudgetForModelSync(modelId) {
5
+ let viaFacade = null;
6
+ try {
7
+ const resolved = UnifiedConfig.getContextBudgetForModel(modelId);
8
+ if (resolved && typeof resolved.allowedBytes === 'number') {
9
+ viaFacade = resolved;
10
+ }
11
+ }
12
+ catch {
13
+ // ignore facade errors and fallback
14
+ }
15
+ if (viaFacade) {
16
+ return viaFacade;
17
+ }
18
+ return resolveBudgetForModelWithNative(modelId, null);
19
+ }
20
+ export const resolveBudgetForModel = async (modelId) => resolveBudgetForModelSync(modelId);
21
+ // Apply payload budget enforcement to an OpenAI Chat-shaped request object in-place.
22
+ // Strategy (deterministic, minimal):
23
+ // 1) Truncate the first system message to RCC_SYSTEM_TEXT_LIMIT (default 8192 chars).
24
+ // 2) Remove assistant messages that have no tool_calls and empty/whitespace content.
25
+ // 3) Iteratively clamp tool role message content down to fit allowedBytes.
26
+ // 4) If仍超限,轻度收紧 assistant 文本(不移除,仅截断)。
27
+ export function enforceChatBudget(chat, modelId) {
28
+ try {
29
+ if (!chat || typeof chat !== 'object')
30
+ return chat;
31
+ const messages = Array.isArray(chat.messages) ? chat.messages : [];
32
+ if (!messages.length)
33
+ return chat;
34
+ const budget = resolveBudgetForModelSync(modelId || 'unknown');
35
+ const allowed = Math.max(1024, Number(budget.allowedBytes || 200000));
36
+ const sysLimit = (() => {
37
+ const raw = process?.env?.RCC_SYSTEM_TEXT_LIMIT;
38
+ const n = Number(raw);
39
+ return Number.isFinite(n) && n >= 0 ? n : 8192;
40
+ })();
41
+ return enforceChatBudgetWithNative(chat, allowed, sysLimit);
42
+ }
43
+ catch {
44
+ // ignore budget errors
45
+ }
46
+ return chat;
47
+ }
@@ -0,0 +1,7 @@
1
+ export declare const OPENAI_CHAT_ALLOWED_FIELDS: readonly string[];
2
+ export declare const ANTHROPIC_ALLOWED_FIELDS: readonly string[];
3
+ export declare const OPENAI_RESPONSES_ALLOWED_FIELDS: readonly string[];
4
+ export declare const GEMINI_ALLOWED_FIELDS: readonly string[];
5
+ export declare const OPENAI_RESPONSES_PARAMETERS_WRAPPER_ALLOW_KEYS: readonly string[];
6
+ export declare const OPENAI_CHAT_PARAMETERS_WRAPPER_ALLOW_KEYS: readonly string[];
7
+ export declare const ANTHROPIC_PARAMETERS_WRAPPER_ALLOW_KEYS: readonly string[];
@@ -0,0 +1,9 @@
1
+ import { resolveHubProtocolAllowlistsWithNative } from '../router/virtual-router/engine-selection/native-hub-bridge-policy-semantics.js';
2
+ const allowlists = resolveHubProtocolAllowlistsWithNative();
3
+ export const OPENAI_CHAT_ALLOWED_FIELDS = Object.freeze([...allowlists.openaiChatAllowedFields]);
4
+ export const ANTHROPIC_ALLOWED_FIELDS = Object.freeze([...allowlists.anthropicAllowedFields]);
5
+ export const OPENAI_RESPONSES_ALLOWED_FIELDS = Object.freeze([...allowlists.openaiResponsesAllowedFields]);
6
+ export const GEMINI_ALLOWED_FIELDS = Object.freeze([...allowlists.geminiAllowedFields]);
7
+ export const OPENAI_RESPONSES_PARAMETERS_WRAPPER_ALLOW_KEYS = Object.freeze([...allowlists.openaiResponsesParametersWrapperAllowKeys]);
8
+ export const OPENAI_CHAT_PARAMETERS_WRAPPER_ALLOW_KEYS = Object.freeze([...allowlists.openaiChatParametersWrapperAllowKeys]);
9
+ export const ANTHROPIC_PARAMETERS_WRAPPER_ALLOW_KEYS = Object.freeze([...allowlists.anthropicParametersWrapperAllowKeys]);
@@ -1,4 +1,4 @@
1
- import type { ChatEnvelope } from '../hub/types/chat-envelope.js';
2
- import { type JsonObject } from '../hub/types/json.js';
1
+ import type { ChatEnvelope } from './hub/types/chat-envelope.js';
2
+ import { type JsonObject } from './hub/types/json.js';
3
3
  export declare function ensureProtocolState(metadata: ChatEnvelope['metadata'], protocol: string): JsonObject;
4
4
  export declare function getProtocolState(metadata: ChatEnvelope['metadata'] | undefined, protocol: string): JsonObject | undefined;
@@ -1,5 +1,5 @@
1
- import { isJsonObject } from '../hub/types/json.js';
2
- import { ensureProtocolStateWithNative, getProtocolStateWithNative } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
1
+ import { isJsonObject } from './hub/types/json.js';
2
+ import { ensureProtocolStateWithNative, getProtocolStateWithNative } from '../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
3
3
  const PROTOCOL_STATE_KEY = 'protocolState';
4
4
  export function ensureProtocolState(metadata, protocol) {
5
5
  const native = ensureProtocolStateWithNative(metadata, protocol);
@@ -4,9 +4,6 @@ export interface ProviderProtocolErrorOptions {
4
4
  code: ProviderProtocolErrorCode;
5
5
  protocol?: string;
6
6
  providerType?: string;
7
- /**
8
- * 粗粒度错误类别;若未显式指定,将基于 code 自动推导。
9
- */
10
7
  category?: ProviderErrorCategory;
11
8
  details?: Record<string, unknown>;
12
9
  }
@@ -0,0 +1,25 @@
1
+ import { buildProviderProtocolErrorWithNative } from '../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
2
+ export class ProviderProtocolError extends Error {
3
+ code;
4
+ protocol;
5
+ providerType;
6
+ category;
7
+ details;
8
+ constructor(message, options) {
9
+ super(message);
10
+ this.name = 'ProviderProtocolError';
11
+ const native = buildProviderProtocolErrorWithNative({
12
+ message,
13
+ code: options.code,
14
+ protocol: options.protocol,
15
+ providerType: options.providerType,
16
+ category: options.category,
17
+ details: options.details
18
+ });
19
+ this.code = options.code;
20
+ this.protocol = typeof native.protocol === 'string' ? native.protocol : options.protocol;
21
+ this.providerType = typeof native.providerType === 'string' ? native.providerType : options.providerType;
22
+ this.category = native.category || options.category || 'EXTERNAL_ERROR';
23
+ this.details = native.details ?? options.details;
24
+ }
25
+ }
@@ -1,13 +1,13 @@
1
1
  import { evaluateResponsesHostPolicy } from '../responses-host-policy.js';
2
- import { canonicalizeChatResponseTools } from '../../shared/tool-canonicalizer.js';
3
2
  import { normalizeMessageReasoningTools } from '../../shared/reasoning-tool-normalizer.js';
4
- import { createBridgeActionState, runBridgeActionPipeline } from '../../shared/bridge-actions.js';
5
- import { resolveBridgePolicy, resolvePolicyActions } from '../../shared/bridge-policies.js';
3
+ import { createBridgeActionState, runBridgeActionPipeline } from '../../bridge-actions.js';
4
+ import { resolveBridgePolicy, resolvePolicyActions } from '../../bridge-policies.js';
6
5
  import { buildResponsesOutputFromChat } from '../../shared/responses-output-builder.js';
7
6
  import { consumeResponsesPayloadSnapshot, consumeResponsesPassthrough } from '../../shared/responses-reasoning-registry.js';
8
7
  import { sanitizeResponsesFunctionName, stripInternalToolingMetadata } from '../../shared/responses-tool-utils.js';
9
- import { ProviderProtocolError } from '../../shared/errors.js';
8
+ import { ProviderProtocolError } from '../../provider-protocol-error.js';
10
9
  import { normalizeResponsesToolCallArgumentsForClientWithNative } from '../../../router/virtual-router/engine-selection/native-hub-pipeline-resp-semantics.js';
10
+ import { normalizeChatResponseReasoningToolsWithNative } from '../../../router/virtual-router/engine-selection/native-hub-bridge-action-semantics.js';
11
11
  function isPlainObject(value) {
12
12
  return Boolean(value && typeof value === 'object' && !Array.isArray(value));
13
13
  }
@@ -77,6 +77,9 @@ function mergeResponseOutputItems(baseOutput, sourceOutput) {
77
77
  if (isMissingResponseField(baseItem.summary) && sourceItem.summary !== undefined) {
78
78
  baseItem.summary = deepCloneRecord({ value: sourceItem.summary }).value;
79
79
  }
80
+ if (isMissingResponseField(baseItem.encrypted_content) && sourceItem.encrypted_content !== undefined) {
81
+ baseItem.encrypted_content = deepCloneRecord({ value: sourceItem.encrypted_content }).value;
82
+ }
80
83
  return baseItem;
81
84
  });
82
85
  }
@@ -381,7 +384,7 @@ export function buildResponsesPayloadFromChat(payload, context) {
381
384
  }
382
385
  return mergedFallback;
383
386
  }
384
- const canonical = canonicalizeChatResponseTools(response);
387
+ const canonical = normalizeChatResponseReasoningToolsWithNative(response);
385
388
  const choices = Array.isArray(canonical?.choices) ? canonical.choices : [];
386
389
  const primaryChoice = choices[0] && typeof choices[0] === 'object' ? choices[0] : undefined;
387
390
  const message = primaryChoice && typeof primaryChoice.message === 'object' ? primaryChoice.message : undefined;
@@ -1,4 +1,4 @@
1
- import type { BridgeInputItem, BridgeToolDefinition } from '../../shared/bridge-message-types.js';
1
+ import type { BridgeInputItem, BridgeToolDefinition } from '../../types/bridge-message-types.js';
2
2
  import type { ChatToolDefinition } from '../../hub/types/chat-envelope.js';
3
3
  import type { JsonObject, JsonValue } from '../../hub/types/json.js';
4
4
  import type { ToolCallIdStyle } from '../../shared/responses-tool-utils.js';
@@ -1,4 +1,4 @@
1
- import type { BridgeInputBuildResult } from '../shared/bridge-message-utils.js';
1
+ import type { BridgeInputBuildResult } from '../bridge-message-utils.js';
2
2
  import type { BuildChatRequestResult, BuildResponsesRequestResult, ResponsesRequestContext } from './responses-openai-bridge/types.js';
3
3
  export type { BuildChatRequestResult, BuildResponsesRequestResult, ResponsesRequestContext } from './responses-openai-bridge/types.js';
4
4
  export declare function captureResponsesContext(payload: Record<string, unknown>, dto?: {