@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
@@ -0,0 +1,22 @@
1
+ export interface NativeToolGovernanceRules {
2
+ maxNameLength?: number;
3
+ allowedCharacters?: unknown;
4
+ forceCase?: 'lower' | 'upper';
5
+ defaultName?: string;
6
+ trimWhitespace?: boolean;
7
+ onViolation?: 'truncate' | 'reject';
8
+ }
9
+ export interface NativeToolGovernanceRuleNode {
10
+ request?: NativeToolGovernanceRules;
11
+ response?: NativeToolGovernanceRules;
12
+ }
13
+ export type NativeToolGovernanceRegistry = Record<string, NativeToolGovernanceRuleNode>;
14
+ export declare function resolveDefaultToolGovernanceRulesWithNative(): NativeToolGovernanceRegistry;
15
+ export declare function governRequestWithNative(input: {
16
+ request: Record<string, unknown>;
17
+ protocol?: string;
18
+ registry?: NativeToolGovernanceRegistry;
19
+ }): {
20
+ request: Record<string, unknown>;
21
+ summary: Record<string, unknown>;
22
+ };
@@ -0,0 +1,154 @@
1
+ import { failNativeRequired, isNativeDisabledByEnv } from './native-router-hotpath-policy.js';
2
+ import { loadNativeRouterHotpathBindingForInternalUse } from './native-router-hotpath.js';
3
+ function readNativeFunction(name) {
4
+ const binding = loadNativeRouterHotpathBindingForInternalUse();
5
+ const fn = binding?.[name];
6
+ return typeof fn === 'function' ? fn : null;
7
+ }
8
+ function safeStringify(value) {
9
+ try {
10
+ return JSON.stringify(value);
11
+ }
12
+ catch {
13
+ return undefined;
14
+ }
15
+ }
16
+ function normalizeAllowedCharactersToken(value) {
17
+ if (typeof value === 'string') {
18
+ const token = value.trim();
19
+ return token || undefined;
20
+ }
21
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
22
+ return undefined;
23
+ }
24
+ const row = value;
25
+ if (typeof row.source === 'string' && row.source.trim()) {
26
+ return row.source.trim();
27
+ }
28
+ return undefined;
29
+ }
30
+ function normalizeRulesForNative(rules) {
31
+ if (!rules || typeof rules !== 'object') {
32
+ return undefined;
33
+ }
34
+ const normalizedAllowed = normalizeAllowedCharactersToken(rules.allowedCharacters);
35
+ return {
36
+ ...rules,
37
+ ...(normalizedAllowed ? { allowedCharacters: normalizedAllowed } : {})
38
+ };
39
+ }
40
+ function normalizeRegistryForNative(registry) {
41
+ if (!registry || typeof registry !== 'object') {
42
+ return undefined;
43
+ }
44
+ const out = {};
45
+ for (const [protocol, node] of Object.entries(registry)) {
46
+ out[protocol] = {
47
+ request: normalizeRulesForNative(node?.request),
48
+ response: normalizeRulesForNative(node?.response)
49
+ };
50
+ }
51
+ return out;
52
+ }
53
+ function parseRegistry(raw) {
54
+ try {
55
+ const parsed = JSON.parse(raw);
56
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
57
+ return null;
58
+ }
59
+ return parsed;
60
+ }
61
+ catch {
62
+ return null;
63
+ }
64
+ }
65
+ function readNativeErrorReason(value) {
66
+ if (value instanceof Error) {
67
+ const text = value.message.trim();
68
+ return text || String(value);
69
+ }
70
+ if (!value || typeof value !== 'object') {
71
+ return undefined;
72
+ }
73
+ const row = value;
74
+ const message = typeof row.message === 'string' ? row.message.trim() : '';
75
+ if (message) {
76
+ return message;
77
+ }
78
+ return undefined;
79
+ }
80
+ export function resolveDefaultToolGovernanceRulesWithNative() {
81
+ const capability = 'resolveDefaultToolGovernanceRulesJson';
82
+ const fail = (reason) => failNativeRequired(capability, reason);
83
+ if (isNativeDisabledByEnv()) {
84
+ return fail('native disabled');
85
+ }
86
+ const fn = readNativeFunction(capability);
87
+ if (!fn) {
88
+ return fail();
89
+ }
90
+ try {
91
+ const raw = fn();
92
+ const errorReason = readNativeErrorReason(raw);
93
+ if (errorReason) {
94
+ return fail(errorReason);
95
+ }
96
+ if (typeof raw !== 'string' || !raw) {
97
+ return fail('empty result');
98
+ }
99
+ const parsed = parseRegistry(raw);
100
+ return parsed ?? fail('invalid payload');
101
+ }
102
+ catch (error) {
103
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
104
+ return fail(reason);
105
+ }
106
+ }
107
+ export function governRequestWithNative(input) {
108
+ const capability = 'governRequestJson';
109
+ const fail = (reason) => failNativeRequired(capability, reason);
110
+ if (isNativeDisabledByEnv()) {
111
+ return fail('native disabled');
112
+ }
113
+ const fn = readNativeFunction(capability);
114
+ if (!fn) {
115
+ return fail();
116
+ }
117
+ const normalizedInput = {
118
+ ...input,
119
+ registry: normalizeRegistryForNative(input.registry)
120
+ };
121
+ const inputJson = safeStringify(normalizedInput);
122
+ if (!inputJson) {
123
+ return fail('json stringify failed');
124
+ }
125
+ try {
126
+ const raw = fn(inputJson);
127
+ const errorReason = readNativeErrorReason(raw);
128
+ if (errorReason) {
129
+ return fail(errorReason);
130
+ }
131
+ if (typeof raw !== 'string' || !raw) {
132
+ return fail('empty result');
133
+ }
134
+ const parsed = JSON.parse(raw);
135
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
136
+ return fail('invalid payload');
137
+ }
138
+ const row = parsed;
139
+ if (!row.request || typeof row.request !== 'object' || Array.isArray(row.request)) {
140
+ return fail('invalid request payload');
141
+ }
142
+ if (!row.summary || typeof row.summary !== 'object' || Array.isArray(row.summary)) {
143
+ return fail('invalid summary payload');
144
+ }
145
+ return {
146
+ request: row.request,
147
+ summary: row.summary
148
+ };
149
+ }
150
+ catch (error) {
151
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
152
+ return fail(reason);
153
+ }
154
+ }
@@ -1,9 +1,10 @@
1
+ import fs from 'node:fs';
1
2
  import path from 'node:path';
2
3
  import { fileURLToPath, pathToFileURL } from 'node:url';
3
4
  import { createRequire } from 'node:module';
4
5
  import { hasCompleteNativeBinding } from './native-router-hotpath-policy.js';
5
6
  const require = createRequire(import.meta.url);
6
- const workspaceRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../../');
7
+ const workspaceRoot = resolvePackageRoot(path.dirname(fileURLToPath(import.meta.url)));
7
8
  let cachedBinding;
8
9
  let cachedBindingCacheKey;
9
10
  const REQUIRED_NATIVE_EXPORTS = [
@@ -39,6 +40,7 @@ const REQUIRED_NATIVE_EXPORTS = [
39
40
  'buildClockMarkerScheduleMessagesJson',
40
41
  'buildClockReminderMessagesJson',
41
42
  'buildClockReminderMetadataJson',
43
+ 'buildProviderProtocolErrorJson',
42
44
  'buildFormatRequestJson',
43
45
  'buildClockStandardToolAppendOperationsJson',
44
46
  'buildClockToolAppendOperationsJson',
@@ -85,9 +87,21 @@ const REQUIRED_NATIVE_EXPORTS = [
85
87
  'extractClockScheduleDirectiveTextPartsJson',
86
88
  'extractSseWrapperErrorJson',
87
89
  'extractMetadataPassthroughJson',
90
+ 'extractJsonToolCallsFromTextJson',
91
+ 'extractXmlToolCallsFromTextJson',
92
+ 'extractSimpleXmlToolsFromTextJson',
93
+ 'extractParameterXmlToolsFromTextJson',
94
+ 'extractInvokeToolsFromTextJson',
95
+ 'extractToolNamespaceXmlBlocksFromTextJson',
96
+ 'extractApplyPatchCallsFromTextJson',
97
+ 'extractBareExecCommandFromTextJson',
98
+ 'extractExecuteBlocksFromTextJson',
99
+ 'extractExploredListDirectoryCallsFromTextJson',
100
+ 'extractQwenToolCallTokensFromTextJson',
88
101
  'extractAdapterContextMetadataFieldsJson',
89
102
  'evaluateResponsesHostPolicyJson',
90
103
  'enforceChatBudgetJson',
104
+ 'resolveBudgetForModelJson',
91
105
  'finalizeGovernedRequestJson',
92
106
  'findLastUserMessageIndexJson',
93
107
  'injectContinueExecutionDirectiveJson',
@@ -114,6 +128,7 @@ const REQUIRED_NATIVE_EXPORTS = [
114
128
  'normalizeBridgeToolCallIdsJson',
115
129
  'normalizeChatMessageContentJson',
116
130
  'normalizeArgsBySchemaJson',
131
+ 'normalizeToolsJson',
117
132
  'normalizeFunctionCallIdJson',
118
133
  'normalizeFunctionCallOutputIdJson',
119
134
  'normalizeHeaderKeyJson',
@@ -133,6 +148,7 @@ const REQUIRED_NATIVE_EXPORTS = [
133
148
  'parseLenientJsonishJson',
134
149
  'parseJsonObjectCandidateJson',
135
150
  'parseProviderKeyJson',
151
+ 'parseRoutingInstructionKindsJson',
136
152
  'parseStopMessageInstructionJson',
137
153
  'pinAliasQueueJson',
138
154
  'planChatClockOperationsJson',
@@ -155,6 +171,7 @@ const REQUIRED_NATIVE_EXPORTS = [
155
171
  'resolveHasInstructionRequestedPassthroughJson',
156
172
  'resolveHubClientProtocolJson',
157
173
  'resolveHubProtocolSpecJson',
174
+ 'resolveHubProtocolAllowlistsJson',
158
175
  'resolveOutboundStreamIntentJson',
159
176
  'resolveProviderProtocolJson',
160
177
  'resolveHubPolicyOverrideJson',
@@ -164,9 +181,11 @@ const REQUIRED_NATIVE_EXPORTS = [
164
181
  'resolveStopMessageRouterMetadataJson',
165
182
  'resolveGovernanceContextJson',
166
183
  'resolveStopMessageSessionScopeJson',
184
+ 'VirtualRouterEngineProxy',
167
185
  'ensureProtocolStateJson',
168
186
  'getProtocolStateJson',
169
187
  'readRuntimeMetadataJson',
188
+ 'resolveDefaultToolGovernanceRulesJson',
170
189
  'ensureRuntimeMetadataJson',
171
190
  'cloneRuntimeMetadataJson',
172
191
  'applyReqInboundSemanticLiftJson',
@@ -187,6 +206,8 @@ const REQUIRED_NATIVE_EXPORTS = [
187
206
  'sanitizeFormatEnvelopeJson',
188
207
  'sanitizeReasoningTaggedTextJson',
189
208
  'sanitizeResponsesFunctionNameJson',
209
+ 'shouldRecordSnapshotsJson',
210
+ 'writeSnapshotViaHooksJson',
190
211
  'selectToolCallIdStyleJson',
191
212
  'serializeStopMessageStateJson',
192
213
  'shouldAttachReqOutboundContextSnapshotJson',
@@ -196,8 +217,23 @@ const REQUIRED_NATIVE_EXPORTS = [
196
217
  'stripOrphanFunctionCallsTagJson',
197
218
  'stripClockClearDirectiveTextJson',
198
219
  'stripChatProcessHistoricalImagesJson',
199
- 'stripPrivateFieldsJson'
220
+ 'stripPrivateFieldsJson',
221
+ 'cleanRoutingInstructionMarkersJson'
200
222
  ];
223
+ function resolvePackageRoot(startDir) {
224
+ let current = startDir;
225
+ for (let i = 0; i < 10; i += 1) {
226
+ if (fs.existsSync(path.join(current, 'package.json'))) {
227
+ return current;
228
+ }
229
+ const parent = path.dirname(current);
230
+ if (parent === current) {
231
+ break;
232
+ }
233
+ current = parent;
234
+ }
235
+ return path.resolve(startDir, '../../../../');
236
+ }
201
237
  function readNativePathFromEnv() {
202
238
  const raw = String(process.env.ROUTECODEX_LLMS_ROUTER_NATIVE_PATH || process.env.RCC_LLMS_ROUTER_NATIVE_PATH || '').trim();
203
239
  return raw || undefined;
@@ -6,6 +6,69 @@ export declare function extractToolCallsFromReasoningTextWithNative(text: string
6
6
  };
7
7
  export declare function sanitizeReasoningTaggedTextWithNative(text: string): string;
8
8
  export declare function deriveToolCallKeyWithNative(call: Record<string, unknown> | null | undefined): string | null;
9
+ export declare function buildProviderProtocolErrorWithNative(input: {
10
+ message: string;
11
+ code: string;
12
+ protocol?: string;
13
+ providerType?: string;
14
+ category?: string;
15
+ details?: Record<string, unknown>;
16
+ }): Record<string, unknown>;
17
+ export declare function extractJsonToolCallsFromTextWithNative(text: string, options?: Record<string, unknown>): Array<{
18
+ id?: string;
19
+ name: string;
20
+ args: string;
21
+ }> | null;
22
+ export declare function extractXMLToolCallsFromTextWithNative(text: string): Array<{
23
+ id?: string;
24
+ name: string;
25
+ args: string;
26
+ }> | null;
27
+ export declare function extractSimpleXmlToolsFromTextWithNative(text: string): Array<{
28
+ id?: string;
29
+ name: string;
30
+ args: string;
31
+ }> | null;
32
+ export declare function extractParameterXmlToolsFromTextWithNative(text: string): Array<{
33
+ id?: string;
34
+ name: string;
35
+ args: string;
36
+ }> | null;
37
+ export declare function extractInvokeToolsFromTextWithNative(text: string): Array<{
38
+ id?: string;
39
+ name: string;
40
+ args: string;
41
+ }> | null;
42
+ export declare function extractToolNamespaceXmlBlocksFromTextWithNative(text: string): Array<{
43
+ id?: string;
44
+ name: string;
45
+ args: string;
46
+ }> | null;
47
+ export declare function extractApplyPatchCallsFromTextWithNative(text: string): Array<{
48
+ id?: string;
49
+ name: string;
50
+ args: string;
51
+ }> | null;
52
+ export declare function extractBareExecCommandFromTextWithNative(text: string): Array<{
53
+ id?: string;
54
+ name: string;
55
+ args: string;
56
+ }> | null;
57
+ export declare function extractExecuteBlocksFromTextWithNative(text: string): Array<{
58
+ id?: string;
59
+ name: string;
60
+ args: string;
61
+ }> | null;
62
+ export declare function extractExploredListDirectoryCallsFromTextWithNative(text: string): Array<{
63
+ id?: string;
64
+ name: string;
65
+ args: string;
66
+ }> | null;
67
+ export declare function extractQwenToolCallTokensFromTextWithNative(text: string): Array<{
68
+ id?: string;
69
+ name: string;
70
+ args: string;
71
+ }> | null;
9
72
  export declare function mergeToolCallsWithNative(existing: Array<Record<string, unknown>> | undefined, additions: Array<Record<string, unknown>> | undefined): Array<Record<string, unknown>>;
10
73
  export declare function mapReasoningContentToResponsesOutputWithNative(reasoningContent: unknown): Array<{
11
74
  type: 'reasoning';
@@ -32,6 +95,7 @@ export declare function normalizeArgsBySchemaWithNative(input: unknown, schema:
32
95
  value?: Record<string, unknown>;
33
96
  errors?: string[];
34
97
  };
98
+ export declare function normalizeToolsWithNative(tools: unknown): Array<Record<string, unknown>>;
35
99
  export declare function extractOutputSegmentsWithNative(source: Record<string, unknown> | undefined, itemsKey?: string): {
36
100
  textParts: string[];
37
101
  reasoningParts: string[];
@@ -60,6 +124,17 @@ export declare function buildGeminiToolsFromBridgeWithNative(defs: unknown, mode
60
124
  export declare function pickResponsesPersistedFieldsWithNative(payload: unknown): Record<string, unknown>;
61
125
  export declare function convertResponsesOutputToInputItemsWithNative(response: unknown): Array<Record<string, unknown>>;
62
126
  export declare function enforceChatBudgetWithNative(chat: unknown, allowedBytes: number, systemTextLimit: number): unknown;
127
+ export declare function resolveBudgetForModelWithNative(modelId: string, fallback: {
128
+ maxBytes: number;
129
+ safetyRatio: number;
130
+ allowedBytes: number;
131
+ source: string;
132
+ } | null | undefined): {
133
+ maxBytes: number;
134
+ safetyRatio: number;
135
+ allowedBytes: number;
136
+ source: string;
137
+ };
63
138
  export declare function injectMcpToolsForResponsesWithNative(tools: unknown[] | undefined, discoveredServers: string[]): unknown[];
64
139
  export declare function normalizeFunctionCallIdWithNative(input: {
65
140
  callId?: string;
@@ -61,6 +61,25 @@ function parseReasoningItems(raw) {
61
61
  }
62
62
  return out;
63
63
  }
64
+ function parseToolCallLiteArray(raw) {
65
+ const parsed = parseJson(raw);
66
+ if (!Array.isArray(parsed)) {
67
+ return null;
68
+ }
69
+ const out = [];
70
+ for (const entry of parsed) {
71
+ if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
72
+ return null;
73
+ }
74
+ const row = entry;
75
+ if (typeof row.name !== 'string' || typeof row.args !== 'string') {
76
+ return null;
77
+ }
78
+ const id = typeof row.id === 'string' && row.id.trim().length ? row.id : undefined;
79
+ out.push({ id, name: row.name, args: row.args });
80
+ }
81
+ return out;
82
+ }
64
83
  export function parseLenientJsonishWithNative(value) {
65
84
  const capability = 'parseLenientJsonishJson';
66
85
  const fail = (reason) => failNativeRequired(capability, reason);
@@ -189,6 +208,128 @@ export function deriveToolCallKeyWithNative(call) {
189
208
  return fail(reason);
190
209
  }
191
210
  }
211
+ export function buildProviderProtocolErrorWithNative(input) {
212
+ const capability = 'buildProviderProtocolErrorJson';
213
+ const fail = (reason) => failNativeRequired(capability, reason);
214
+ if (isNativeDisabledByEnv()) {
215
+ return fail('native disabled');
216
+ }
217
+ const fn = readNativeFunction(capability);
218
+ if (!fn) {
219
+ return fail();
220
+ }
221
+ const payloadJson = safeStringify({
222
+ message: input.message,
223
+ code: input.code,
224
+ protocol: input.protocol,
225
+ providerType: input.providerType,
226
+ category: input.category,
227
+ details: input.details
228
+ });
229
+ if (!payloadJson) {
230
+ return fail('json stringify failed');
231
+ }
232
+ try {
233
+ const raw = fn(payloadJson);
234
+ if (typeof raw !== 'string' || !raw) {
235
+ return fail('empty result');
236
+ }
237
+ const parsed = parseRecord(raw);
238
+ return parsed ?? fail('invalid payload');
239
+ }
240
+ catch (error) {
241
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
242
+ return fail(reason);
243
+ }
244
+ }
245
+ function parseToolCallResult(raw) {
246
+ if (!raw || raw === 'null') {
247
+ return null;
248
+ }
249
+ return parseToolCallLiteArray(raw);
250
+ }
251
+ function callTextMarkupExtractor(capability, payload) {
252
+ const fail = (reason) => failNativeRequired(capability, reason);
253
+ if (isNativeDisabledByEnv()) {
254
+ return fail('native disabled');
255
+ }
256
+ const fn = readNativeFunction(capability);
257
+ if (!fn) {
258
+ return fail();
259
+ }
260
+ const payloadJson = safeStringify(payload ?? null);
261
+ if (!payloadJson) {
262
+ return fail('json stringify failed');
263
+ }
264
+ try {
265
+ const raw = fn(payloadJson);
266
+ if (typeof raw !== 'string') {
267
+ return fail('invalid payload');
268
+ }
269
+ const parsed = parseToolCallResult(raw);
270
+ return parsed ?? null;
271
+ }
272
+ catch (error) {
273
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
274
+ return fail(reason);
275
+ }
276
+ }
277
+ export function extractJsonToolCallsFromTextWithNative(text, options) {
278
+ return callTextMarkupExtractor('extractJsonToolCallsFromTextJson', {
279
+ text: String(text ?? ''),
280
+ options: options ?? null
281
+ });
282
+ }
283
+ export function extractXMLToolCallsFromTextWithNative(text) {
284
+ return callTextMarkupExtractor('extractXmlToolCallsFromTextJson', {
285
+ text: String(text ?? '')
286
+ });
287
+ }
288
+ export function extractSimpleXmlToolsFromTextWithNative(text) {
289
+ return callTextMarkupExtractor('extractSimpleXmlToolsFromTextJson', {
290
+ text: String(text ?? '')
291
+ });
292
+ }
293
+ export function extractParameterXmlToolsFromTextWithNative(text) {
294
+ return callTextMarkupExtractor('extractParameterXmlToolsFromTextJson', {
295
+ text: String(text ?? '')
296
+ });
297
+ }
298
+ export function extractInvokeToolsFromTextWithNative(text) {
299
+ return callTextMarkupExtractor('extractInvokeToolsFromTextJson', {
300
+ text: String(text ?? '')
301
+ });
302
+ }
303
+ export function extractToolNamespaceXmlBlocksFromTextWithNative(text) {
304
+ return callTextMarkupExtractor('extractToolNamespaceXmlBlocksFromTextJson', {
305
+ text: String(text ?? '')
306
+ });
307
+ }
308
+ export function extractApplyPatchCallsFromTextWithNative(text) {
309
+ return callTextMarkupExtractor('extractApplyPatchCallsFromTextJson', {
310
+ text: String(text ?? '')
311
+ });
312
+ }
313
+ export function extractBareExecCommandFromTextWithNative(text) {
314
+ return callTextMarkupExtractor('extractBareExecCommandFromTextJson', {
315
+ text: String(text ?? '')
316
+ });
317
+ }
318
+ export function extractExecuteBlocksFromTextWithNative(text) {
319
+ return callTextMarkupExtractor('extractExecuteBlocksFromTextJson', {
320
+ text: String(text ?? '')
321
+ });
322
+ }
323
+ export function extractExploredListDirectoryCallsFromTextWithNative(text) {
324
+ return callTextMarkupExtractor('extractExploredListDirectoryCallsFromTextJson', {
325
+ text: String(text ?? '')
326
+ });
327
+ }
328
+ export function extractQwenToolCallTokensFromTextWithNative(text) {
329
+ return callTextMarkupExtractor('extractQwenToolCallTokensFromTextJson', {
330
+ text: String(text ?? '')
331
+ });
332
+ }
192
333
  export function mergeToolCallsWithNative(existing, additions) {
193
334
  const capability = 'mergeToolCallsJson';
194
335
  const fail = (reason) => failNativeRequired(capability, reason);
@@ -613,6 +754,33 @@ export function normalizeArgsBySchemaWithNative(input, schema) {
613
754
  return fail(reason);
614
755
  }
615
756
  }
757
+ export function normalizeToolsWithNative(tools) {
758
+ const capability = 'normalizeToolsJson';
759
+ const fail = (reason) => failNativeRequired(capability, reason);
760
+ if (isNativeDisabledByEnv()) {
761
+ return fail('native disabled');
762
+ }
763
+ const fn = readNativeFunction(capability);
764
+ if (!fn) {
765
+ return fail();
766
+ }
767
+ const toolsJson = safeStringify(tools ?? null);
768
+ if (!toolsJson) {
769
+ return fail('json stringify failed');
770
+ }
771
+ try {
772
+ const raw = fn(toolsJson);
773
+ if (typeof raw !== 'string' || !raw) {
774
+ return fail('empty result');
775
+ }
776
+ const parsed = parseJson(raw);
777
+ return Array.isArray(parsed) ? parsed : fail('invalid payload');
778
+ }
779
+ catch (error) {
780
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
781
+ return fail(reason);
782
+ }
783
+ }
616
784
  export function extractOutputSegmentsWithNative(source, itemsKey = 'output') {
617
785
  const capability = 'extractOutputSegmentsJson';
618
786
  const fail = (reason) => failNativeRequired(capability, reason);
@@ -1037,6 +1205,43 @@ export function enforceChatBudgetWithNative(chat, allowedBytes, systemTextLimit)
1037
1205
  return fail(reason);
1038
1206
  }
1039
1207
  }
1208
+ export function resolveBudgetForModelWithNative(modelId, fallback) {
1209
+ const capability = 'resolveBudgetForModelJson';
1210
+ const fail = (reason) => failNativeRequired(capability, reason);
1211
+ if (isNativeDisabledByEnv()) {
1212
+ return fail('native disabled');
1213
+ }
1214
+ const fn = readNativeFunction(capability);
1215
+ if (!fn) {
1216
+ return fail();
1217
+ }
1218
+ const fallbackJson = safeStringify(fallback ?? null);
1219
+ if (!fallbackJson) {
1220
+ return fail('json stringify failed');
1221
+ }
1222
+ try {
1223
+ const raw = fn(String(modelId ?? ''), fallbackJson);
1224
+ if (typeof raw !== 'string' || !raw) {
1225
+ return fail('empty result');
1226
+ }
1227
+ const parsed = parseRecord(raw);
1228
+ if (!parsed) {
1229
+ return fail('invalid payload');
1230
+ }
1231
+ const maxBytes = Number(parsed.maxBytes);
1232
+ const safetyRatio = Number(parsed.safetyRatio);
1233
+ const allowedBytes = Number(parsed.allowedBytes);
1234
+ const source = typeof parsed.source === 'string' ? parsed.source : 'unknown';
1235
+ if (!Number.isFinite(maxBytes) || !Number.isFinite(safetyRatio) || !Number.isFinite(allowedBytes)) {
1236
+ return fail('invalid payload');
1237
+ }
1238
+ return { maxBytes, safetyRatio, allowedBytes, source };
1239
+ }
1240
+ catch (error) {
1241
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
1242
+ return fail(reason);
1243
+ }
1244
+ }
1040
1245
  export function injectMcpToolsForResponsesWithNative(tools, discoveredServers) {
1041
1246
  const capability = 'injectMcpToolsForResponsesJson';
1042
1247
  const fail = (reason) => failNativeRequired(capability, reason);
@@ -0,0 +1,2 @@
1
+ export declare function shouldRecordSnapshotsWithNative(): boolean;
2
+ export declare function writeSnapshotViaHooksWithNative(options: Record<string, unknown>): void;
@@ -0,0 +1,69 @@
1
+ import { failNativeRequired, isNativeDisabledByEnv } from './native-router-hotpath-policy.js';
2
+ import { loadNativeRouterHotpathBindingForInternalUse } from './native-router-hotpath.js';
3
+ function readNativeFunction(name) {
4
+ const binding = loadNativeRouterHotpathBindingForInternalUse();
5
+ const fn = binding?.[name];
6
+ return typeof fn === 'function' ? fn : null;
7
+ }
8
+ function safeStringify(value) {
9
+ try {
10
+ return JSON.stringify(value);
11
+ }
12
+ catch {
13
+ return undefined;
14
+ }
15
+ }
16
+ function parseBoolean(raw) {
17
+ try {
18
+ const parsed = JSON.parse(raw);
19
+ return typeof parsed === 'boolean' ? parsed : null;
20
+ }
21
+ catch {
22
+ return null;
23
+ }
24
+ }
25
+ export function shouldRecordSnapshotsWithNative() {
26
+ const capability = 'shouldRecordSnapshotsJson';
27
+ const fail = (reason) => failNativeRequired(capability, reason);
28
+ if (isNativeDisabledByEnv()) {
29
+ return fail('native disabled');
30
+ }
31
+ const fn = readNativeFunction(capability);
32
+ if (!fn) {
33
+ return fail();
34
+ }
35
+ try {
36
+ const raw = fn();
37
+ if (typeof raw !== 'string' || !raw) {
38
+ return fail('empty result');
39
+ }
40
+ const parsed = parseBoolean(raw);
41
+ return parsed === null ? fail('invalid payload') : parsed;
42
+ }
43
+ catch (error) {
44
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
45
+ return fail(reason);
46
+ }
47
+ }
48
+ export function writeSnapshotViaHooksWithNative(options) {
49
+ const capability = 'writeSnapshotViaHooksJson';
50
+ const fail = (reason) => failNativeRequired(capability, reason);
51
+ if (isNativeDisabledByEnv()) {
52
+ return fail('native disabled');
53
+ }
54
+ const fn = readNativeFunction(capability);
55
+ if (!fn) {
56
+ return fail();
57
+ }
58
+ const payloadJson = safeStringify(options ?? null);
59
+ if (!payloadJson) {
60
+ return fail('json stringify failed');
61
+ }
62
+ try {
63
+ fn(payloadJson);
64
+ }
65
+ catch (error) {
66
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
67
+ return fail(reason);
68
+ }
69
+ }