@jsonstudio/llms 0.6.3271 → 0.6.3379

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 (49) hide show
  1. package/dist/conversion/bridge-message-utils.d.ts +4 -4
  2. package/dist/conversion/bridge-message-utils.js +28 -538
  3. package/dist/conversion/compat/actions/anthropic-claude-code-system-prompt.js +38 -0
  4. package/dist/conversion/compat/profiles/responses-crs.json +15 -0
  5. package/dist/conversion/hub/operation-table/semantic-mappers/chat-mapper.js +16 -5
  6. package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage1_tool_governance/index.js +1 -6
  7. package/dist/conversion/hub/response/response-runtime.js +14 -6
  8. package/dist/conversion/responses/responses-openai-bridge/response-payload.js +11 -11
  9. package/dist/conversion/shared/anthropic-message-utils.js +2 -12
  10. package/dist/conversion/shared/chat-request-filters.js +2 -61
  11. package/dist/conversion/shared/reasoning-mapping.js +3 -0
  12. package/dist/conversion/shared/reasoning-normalizer.d.ts +1 -0
  13. package/dist/conversion/shared/reasoning-normalizer.js +35 -388
  14. package/dist/conversion/shared/reasoning-tool-normalizer.js +8 -15
  15. package/dist/conversion/shared/reasoning-utils.js +13 -35
  16. package/dist/conversion/shared/responses-tool-utils.d.ts +1 -1
  17. package/dist/conversion/shared/responses-tool-utils.js +63 -65
  18. package/dist/conversion/shared/streaming-text-extractor.d.ts +0 -5
  19. package/dist/conversion/shared/streaming-text-extractor.js +18 -111
  20. package/dist/conversion/shared/text-markup-normalizer/normalize.d.ts +1 -1
  21. package/dist/conversion/shared/text-markup-normalizer/normalize.js +3 -91
  22. package/dist/conversion/shared/thought-signature-validator.js +19 -133
  23. package/dist/conversion/shared/tool-argument-repairer.js +16 -19
  24. package/dist/conversion/shared/tool-call-id-manager.d.ts +1 -5
  25. package/dist/conversion/shared/tool-call-id-manager.js +74 -98
  26. package/dist/conversion/shared/tool-harvester.js +19 -382
  27. package/dist/conversion/shared/tool-mapping.d.ts +2 -3
  28. package/dist/conversion/shared/tool-mapping.js +28 -184
  29. package/dist/conversion/shared/tooling.js +20 -151
  30. package/dist/filters/special/response-tool-arguments-stringify.js +9 -1
  31. package/dist/guidance/index.js +2 -2
  32. package/dist/native/router_hotpath_napi.node +0 -0
  33. package/dist/router/virtual-router/engine-legacy/helpers.js +1 -1
  34. package/dist/router/virtual-router/engine-selection/native-hub-bridge-action-semantics.d.ts +39 -0
  35. package/dist/router/virtual-router/engine-selection/native-hub-bridge-action-semantics.js +196 -0
  36. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-req-inbound-semantics.d.ts +1 -0
  37. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-req-inbound-semantics.js +27 -0
  38. package/dist/router/virtual-router/engine-selection/native-router-hotpath-loader.js +34 -0
  39. package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.d.ts +65 -1
  40. package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.js +836 -35
  41. package/dist/router/virtual-router/engine.js +3 -2
  42. package/dist/router/virtual-router/routing-instructions/parse.js +30 -3
  43. package/dist/sse/sse-to-json/builders/anthropic-response-builder.js +28 -3
  44. package/dist/sse/types/anthropic-types.d.ts +3 -1
  45. package/dist/tools/apply-patch/args-normalizer/extract-patch.js +2 -2
  46. package/dist/tools/apply-patch/patch-text/looks-like-patch.js +3 -6
  47. package/dist/tools/apply-patch/patch-text/normalize.js +14 -3
  48. package/dist/tools/tool-registry.js +12 -0
  49. package/package.json +6 -1
@@ -1,409 +1,56 @@
1
- import { normalizeChatMessageContent } from './chat-output-normalizer.js';
2
- import { extractReasoningSegments } from './reasoning-utils.js';
3
- import { expandResponsesMessageItem } from '../../sse/shared/responses-output-normalizer.js';
4
- import { sanitizeReasoningTaggedTextWithNative } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
1
+ import { normalizeReasoningInAnthropicPayloadWithNative, normalizeReasoningInChatPayloadWithNative, normalizeReasoningInGeminiPayloadWithNative, normalizeReasoningInOpenAIPayloadWithNative, normalizeReasoningInResponsesPayloadWithNative } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
5
2
  export const RESPONSES_INSTRUCTIONS_REASONING_FIELD = '__rcc_reasoning_instructions';
6
- function isRecord(value) {
7
- return Boolean(value && typeof value === 'object' && !Array.isArray(value));
8
- }
9
- export function normalizeReasoningInChatPayload(payload) {
10
- if (!payload) {
11
- return;
12
- }
13
- if (Array.isArray(payload.messages)) {
14
- payload.messages = payload.messages.map(entry => normalizeChatMessageEntry(entry));
15
- }
16
- if (Array.isArray(payload.choices)) {
17
- payload.choices.forEach(choice => {
18
- normalizeChatChoice(choice);
19
- });
3
+ function assertReasoningNormalizerNativeAvailable() {
4
+ if (typeof normalizeReasoningInChatPayloadWithNative !== 'function' ||
5
+ typeof normalizeReasoningInResponsesPayloadWithNative !== 'function' ||
6
+ typeof normalizeReasoningInGeminiPayloadWithNative !== 'function' ||
7
+ typeof normalizeReasoningInAnthropicPayloadWithNative !== 'function' ||
8
+ typeof normalizeReasoningInOpenAIPayloadWithNative !== 'function') {
9
+ throw new Error('[reasoning-normalizer] native bindings unavailable');
20
10
  }
21
11
  }
22
- function normalizeChatMessageEntry(entry) {
23
- if (!entry || typeof entry !== 'object') {
24
- return entry;
25
- }
26
- const msg = entry;
27
- applyNormalizedChatContent(msg);
28
- return msg;
29
- }
30
- function normalizeChatChoice(choice) {
31
- if (!choice || typeof choice !== 'object') {
12
+ export function normalizeReasoningInChatPayload(payload) {
13
+ assertReasoningNormalizerNativeAvailable();
14
+ if (!payload)
32
15
  return;
33
- }
34
- const record = choice;
35
- const containers = [];
36
- if (record.message && typeof record.message === 'object') {
37
- containers.push(record.message);
38
- }
39
- if (record.delta && typeof record.delta === 'object') {
40
- containers.push(record.delta);
41
- }
42
- containers.forEach(container => applyNormalizedChatContent(container));
43
- }
44
- function applyNormalizedChatContent(container) {
45
- const existingReasoning = typeof container.reasoning_content === 'string' && container.reasoning_content.trim().length
46
- ? container.reasoning_content.trim()
47
- : undefined;
48
- const normalized = normalizeChatMessageContent(container.content);
49
- const role = typeof container.role === 'string' ? container.role : undefined;
50
- if (normalized.contentText !== undefined && normalized.contentText.trim().length) {
51
- container.content = normalized.contentText;
52
- }
53
- else if (typeof container.reasoning_content === 'string' && container.reasoning_content.trim().length) {
54
- container.content = container.reasoning_content.trim();
55
- }
56
- else if (role && role !== 'system' && role !== 'tool') {
57
- container.content = '';
58
- }
59
- if (normalized.reasoningText && normalized.reasoningText.trim().length) {
60
- container.reasoning_content = normalized.reasoningText.trim();
61
- }
62
- else if (existingReasoning) {
63
- container.reasoning_content = existingReasoning;
64
- }
65
- else if ('reasoning_content' in container) {
66
- delete container.reasoning_content;
16
+ const normalized = normalizeReasoningInChatPayloadWithNative(payload);
17
+ if (normalized && typeof normalized === 'object') {
18
+ Object.assign(payload, normalized);
67
19
  }
68
20
  }
69
21
  export function normalizeReasoningInResponsesPayload(payload, options = { includeOutput: true }) {
70
- if (!payload) {
71
- return;
72
- }
73
- const includeOutput = options.includeOutput !== false;
74
- if (includeOutput) {
75
- normalizeResponsesOutput(payload);
76
- }
77
- if (options.includeInput) {
78
- normalizeResponsesInput(payload);
79
- }
80
- if (options.includeInstructions) {
81
- normalizeResponsesInstructions(payload);
82
- }
83
- if (options.includeRequiredAction) {
84
- normalizeResponsesRequiredAction(payload);
85
- }
86
- }
87
- function normalizeResponsesOutput(payload) {
88
- if (!Array.isArray(payload.output)) {
89
- return;
90
- }
91
- const normalized = [];
92
- payload.output.forEach((entry, index) => {
93
- if (isResponsesMessageItem(entry)) {
94
- const expanded = expandResponsesMessageItem(entry, {
95
- requestId: typeof payload.id === 'string' ? payload.id : 'responses',
96
- outputIndex: index
97
- });
98
- expanded.forEach((item) => {
99
- normalized.push(item);
100
- });
101
- }
102
- else {
103
- normalized.push(entry);
104
- }
105
- });
106
- payload.output = normalized;
107
- }
108
- function isResponsesMessageItem(entry) {
109
- if (!isRecord(entry)) {
110
- return false;
111
- }
112
- const type = typeof entry.type === 'string' ? entry.type : undefined;
113
- if (type !== 'message') {
114
- return false;
115
- }
116
- if (!Array.isArray(entry.content)) {
117
- return false;
118
- }
119
- const status = typeof entry.status === 'string' ? entry.status : undefined;
120
- const role = typeof entry.role === 'string' ? entry.role : undefined;
121
- return Boolean(status && role);
122
- }
123
- function normalizeResponsesInput(payload) {
124
- if (!Array.isArray(payload.input)) {
22
+ assertReasoningNormalizerNativeAvailable();
23
+ if (!payload)
125
24
  return;
126
- }
127
- payload.input.forEach((entry) => {
128
- if (!isRecord(entry))
129
- return;
130
- const reasoningSegments = [];
131
- if (typeof entry.content === 'string') {
132
- const { cleaned, segments } = stripReasoningFromString(entry.content);
133
- entry.content = cleaned;
134
- reasoningSegments.push(...segments);
135
- }
136
- else if (Array.isArray(entry.content)) {
137
- entry.content = entry.content.map((block) => normalizeResponsesContentBlock(block, reasoningSegments));
138
- }
139
- if (isRecord(entry.message)) {
140
- normalizeResponsesMessageBlock(entry.message, reasoningSegments);
141
- }
142
- if (typeof entry.text === 'string') {
143
- const { cleaned, segments } = stripReasoningFromString(entry.text);
144
- entry.text = cleaned;
145
- reasoningSegments.push(...segments);
146
- }
147
- if (reasoningSegments.length) {
148
- entry.reasoning_content = mergeReasoningText(entry.reasoning_content, reasoningSegments);
149
- }
150
- else if ('reasoning_content' in entry) {
151
- delete entry.reasoning_content;
152
- }
153
- });
154
- }
155
- function normalizeResponsesMessageBlock(message, collector) {
156
- const localSegments = [];
157
- if (Array.isArray(message.content)) {
158
- message.content = message.content.map((block) => normalizeResponsesContentBlock(block, localSegments));
159
- }
160
- else if (typeof message.content === 'string') {
161
- const { cleaned, segments } = stripReasoningFromString(message.content);
162
- message.content = cleaned;
163
- localSegments.push(...segments);
164
- }
165
- if (typeof message.text === 'string') {
166
- const { cleaned, segments } = stripReasoningFromString(message.text);
167
- message.text = cleaned;
168
- localSegments.push(...segments);
169
- }
170
- if (localSegments.length) {
171
- collector.push(...localSegments);
172
- message.reasoning_content = mergeReasoningText(message.reasoning_content, localSegments);
173
- }
174
- else if ('reasoning_content' in message) {
175
- delete message.reasoning_content;
25
+ const normalized = normalizeReasoningInResponsesPayloadWithNative(payload, options);
26
+ if (normalized && typeof normalized === 'object') {
27
+ Object.assign(payload, normalized);
176
28
  }
177
29
  }
178
- function normalizeResponsesContentBlock(block, collector) {
179
- if (typeof block === 'string') {
180
- const { cleaned, segments } = stripReasoningFromString(block);
181
- collector.push(...segments);
182
- return cleaned;
183
- }
184
- if (!isRecord(block)) {
185
- return block;
186
- }
187
- const type = typeof block.type === 'string' ? block.type.toLowerCase() : '';
188
- if ((type === 'input_text' || type === 'output_text' || type === 'text' || type === 'commentary') && typeof block.text === 'string') {
189
- const { cleaned, segments } = stripReasoningFromString(block.text);
190
- block.text = cleaned;
191
- if (segments.length) {
192
- collector.push(...segments);
193
- block.reasoning_content = mergeReasoningText(block.reasoning_content, segments);
194
- }
195
- else if ('reasoning_content' in block) {
196
- delete block.reasoning_content;
197
- }
198
- }
199
- if (Array.isArray(block.content)) {
200
- block.content = block.content.map((nested) => normalizeResponsesContentBlock(nested, collector));
201
- }
202
- else if (typeof block.content === 'string') {
203
- const { cleaned, segments } = stripReasoningFromString(block.content);
204
- block.content = cleaned;
205
- if (segments.length) {
206
- collector.push(...segments);
207
- block.reasoning_content = mergeReasoningText(block.reasoning_content, segments);
208
- }
209
- else if ('reasoning_content' in block) {
210
- delete block.reasoning_content;
211
- }
212
- }
213
- return block;
214
- }
215
- function normalizeResponsesInstructions(payload) {
216
- if (typeof payload.instructions !== 'string') {
217
- if (RESPONSES_INSTRUCTIONS_REASONING_FIELD in payload) {
218
- delete payload[RESPONSES_INSTRUCTIONS_REASONING_FIELD];
219
- }
220
- return;
221
- }
222
- const { cleaned, segments } = stripReasoningFromString(payload.instructions);
223
- payload.instructions = cleaned;
224
- if (segments.length) {
225
- payload[RESPONSES_INSTRUCTIONS_REASONING_FIELD] = segments.join('\n');
226
- }
227
- else if (RESPONSES_INSTRUCTIONS_REASONING_FIELD in payload) {
228
- delete payload[RESPONSES_INSTRUCTIONS_REASONING_FIELD];
229
- }
230
- }
231
- function normalizeResponsesRequiredAction(payload) {
232
- if (!isRecord(payload.required_action)) {
233
- return;
234
- }
235
- const submit = payload.required_action.submit_tool_outputs;
236
- if (!submit || typeof submit !== 'object') {
237
- return;
238
- }
239
- const toolCalls = Array.isArray(submit.tool_calls)
240
- ? submit.tool_calls
241
- : [];
242
- toolCalls.forEach((call) => {
243
- if (!isRecord(call))
244
- return;
245
- if (typeof call.instructions === 'string') {
246
- const { cleaned, segments } = stripReasoningFromString(call.instructions);
247
- call.instructions = cleaned;
248
- if (segments.length) {
249
- call.reasoning_content = mergeReasoningText(call.reasoning_content, segments);
250
- }
251
- else if ('reasoning_content' in call) {
252
- delete call.reasoning_content;
253
- }
254
- }
255
- });
256
- }
257
- function stripReasoningFromString(value) {
258
- if (typeof value !== 'string') {
259
- return { cleaned: typeof value === 'string' ? value : '', segments: [] };
260
- }
261
- const segments = [];
262
- const cleaned = extractReasoningSegments(value, segments);
263
- const cleanedNative = sanitizeReasoningTaggedTextWithNative(value);
264
- const stableCleaned = typeof cleanedNative === 'string' ? cleanedNative : cleaned;
265
- return { cleaned: stableCleaned, segments };
266
- }
267
- function mergeReasoningText(existing, segments) {
268
- const combined = [];
269
- if (typeof existing === 'string' && existing.trim().length) {
270
- combined.push(existing.trim());
271
- }
272
- for (const segment of segments) {
273
- if (typeof segment === 'string' && segment.trim().length) {
274
- combined.push(segment.trim());
275
- }
276
- }
277
- return combined.join('\n');
278
- }
279
30
  export function normalizeReasoningInGeminiPayload(payload) {
280
- if (!payload) {
31
+ assertReasoningNormalizerNativeAvailable();
32
+ if (!payload)
281
33
  return;
34
+ const normalized = normalizeReasoningInGeminiPayloadWithNative(payload);
35
+ if (normalized && typeof normalized === 'object') {
36
+ Object.assign(payload, normalized);
282
37
  }
283
- const contents = Array.isArray(payload.contents) ? payload.contents : [];
284
- contents.forEach((content) => {
285
- if (!isRecord(content))
286
- return;
287
- const parts = Array.isArray(content.parts) ? content.parts : [];
288
- parts.forEach((part) => {
289
- if (!isRecord(part) || typeof part.text !== 'string') {
290
- return;
291
- }
292
- const reasoningSegments = [];
293
- const cleaned = extractReasoningSegments(part.text, reasoningSegments);
294
- part.text = cleaned;
295
- if (reasoningSegments.length) {
296
- part.reasoning = reasoningSegments.join('\n');
297
- }
298
- else if ('reasoning' in part) {
299
- delete part.reasoning;
300
- }
301
- });
302
- });
303
38
  }
304
39
  export function normalizeReasoningInAnthropicPayload(payload) {
305
- if (!payload) {
40
+ assertReasoningNormalizerNativeAvailable();
41
+ if (!payload)
306
42
  return;
307
- }
308
- const responseContent = Array.isArray(payload.content) ? payload.content : undefined;
309
- if (responseContent) {
310
- const responseReasoning = [];
311
- responseContent.forEach((block) => normalizeAnthropicBlock(block, responseReasoning));
312
- if (responseReasoning.length) {
313
- payload.reasoning_content = mergeReasoningText(payload.reasoning_content, responseReasoning);
314
- }
315
- else if ('reasoning_content' in payload) {
316
- delete payload.reasoning_content;
317
- }
318
- }
319
- const messages = Array.isArray(payload.messages) ? payload.messages : [];
320
- messages.forEach((message) => {
321
- if (!isRecord(message))
322
- return;
323
- normalizeAnthropicMessage(message);
324
- });
325
- const systemField = payload.system;
326
- if (typeof systemField === 'string') {
327
- const { cleaned } = stripReasoningFromString(systemField);
328
- payload.system = cleaned;
329
- }
330
- else if (Array.isArray(systemField)) {
331
- systemField.forEach((entry) => normalizeAnthropicBlock(entry, []));
332
- }
333
- else if (isRecord(systemField) && Array.isArray(systemField.content)) {
334
- const sysBlocks = systemField.content;
335
- systemField.content = sysBlocks.map((block) => {
336
- normalizeAnthropicBlock(block, []);
337
- return block;
338
- });
339
- }
340
- }
341
- function normalizeAnthropicMessage(message) {
342
- const reasoningSegments = [];
343
- if (Array.isArray(message.content)) {
344
- message.content.forEach((block) => normalizeAnthropicBlock(block, reasoningSegments));
345
- }
346
- else if (typeof message.content === 'string') {
347
- const { cleaned, segments } = stripReasoningFromString(message.content);
348
- message.content = cleaned;
349
- reasoningSegments.push(...segments);
350
- }
351
- if (reasoningSegments.length) {
352
- message.reasoning_content = mergeReasoningText(message.reasoning_content, reasoningSegments);
353
- }
354
- else if ('reasoning_content' in message) {
355
- delete message.reasoning_content;
43
+ const normalized = normalizeReasoningInAnthropicPayloadWithNative(payload);
44
+ if (normalized && typeof normalized === 'object') {
45
+ Object.assign(payload, normalized);
356
46
  }
357
47
  }
358
- function normalizeAnthropicBlock(block, collector) {
359
- if (typeof block === 'string') {
360
- const { cleaned, segments } = stripReasoningFromString(block);
361
- collector.push(...segments);
48
+ export function normalizeReasoningInOpenAIPayload(payload) {
49
+ assertReasoningNormalizerNativeAvailable();
50
+ if (!payload)
362
51
  return;
52
+ const normalized = normalizeReasoningInOpenAIPayloadWithNative(payload);
53
+ if (normalized && typeof normalized === 'object') {
54
+ Object.assign(payload, normalized);
363
55
  }
364
- if (!isRecord(block)) {
365
- return;
366
- }
367
- const type = typeof block.type === 'string' ? block.type.toLowerCase() : '';
368
- if (type === 'text' && typeof block.text === 'string') {
369
- const { cleaned, segments } = stripReasoningFromString(block.text);
370
- block.text = cleaned;
371
- collector.push(...segments);
372
- return;
373
- }
374
- if (type === 'thinking' || type === 'reasoning') {
375
- const flattened = flattenAnthropicText(block);
376
- if (flattened.trim().length) {
377
- collector.push(flattened.trim());
378
- }
379
- return;
380
- }
381
- if (Array.isArray(block.content)) {
382
- block.content.forEach((nested) => normalizeAnthropicBlock(nested, collector));
383
- }
384
- else if (typeof block.content === 'string') {
385
- const { cleaned, segments } = stripReasoningFromString(block.content);
386
- block.content = cleaned;
387
- collector.push(...segments);
388
- }
389
- }
390
- function flattenAnthropicText(source) {
391
- if (typeof source === 'string') {
392
- return source;
393
- }
394
- if (Array.isArray(source)) {
395
- return source.map((entry) => flattenAnthropicText(entry)).filter(Boolean).join('');
396
- }
397
- if (isRecord(source)) {
398
- if (typeof source.text === 'string') {
399
- return source.text;
400
- }
401
- if (typeof source.content === 'string') {
402
- return source.content;
403
- }
404
- if (Array.isArray(source.content)) {
405
- return source.content.map((entry) => flattenAnthropicText(entry)).filter(Boolean).join('');
406
- }
407
- }
408
- return '';
409
56
  }
@@ -1,18 +1,14 @@
1
1
  import { normalizeChatResponseReasoningToolsWithNative, normalizeMessageReasoningToolsWithNative } from '../../router/virtual-router/engine-selection/native-hub-bridge-action-semantics.js';
2
- function overwriteRecordInPlace(target, source) {
3
- for (const key of Object.keys(target)) {
4
- delete target[key];
5
- }
6
- for (const [key, value] of Object.entries(source)) {
7
- target[key] = value;
2
+ const MODULE_NAME = 'reasoning-tool-normalizer';
3
+ function assertReasoningToolNormalizerNativeAvailable() {
4
+ if (typeof normalizeMessageReasoningToolsWithNative !== 'function' ||
5
+ typeof normalizeChatResponseReasoningToolsWithNative !== 'function') {
6
+ throw new Error(`[${MODULE_NAME}] native bindings unavailable`);
8
7
  }
9
8
  }
10
9
  export function normalizeMessageReasoningTools(message, options) {
11
- if (!message || typeof message !== 'object') {
12
- return { toolCallsAdded: 0 };
13
- }
10
+ assertReasoningToolNormalizerNativeAvailable();
14
11
  const normalized = normalizeMessageReasoningToolsWithNative(message, typeof options?.idPrefix === 'string' ? options.idPrefix : undefined);
15
- overwriteRecordInPlace(message, normalized.message);
16
12
  return {
17
13
  toolCallsAdded: normalized.toolCallsAdded,
18
14
  ...(typeof normalized.cleanedReasoning === 'string'
@@ -21,9 +17,6 @@ export function normalizeMessageReasoningTools(message, options) {
21
17
  };
22
18
  }
23
19
  export function normalizeChatResponseReasoningTools(response, options) {
24
- if (!response || typeof response !== 'object') {
25
- return;
26
- }
27
- const normalized = normalizeChatResponseReasoningToolsWithNative(response, typeof options?.idPrefixBase === 'string' ? options.idPrefixBase : undefined);
28
- overwriteRecordInPlace(response, normalized);
20
+ assertReasoningToolNormalizerNativeAvailable();
21
+ normalizeChatResponseReasoningToolsWithNative(response, typeof options?.idPrefixBase === 'string' ? options.idPrefixBase : undefined);
29
22
  }
@@ -1,41 +1,19 @@
1
- import { sanitizeReasoningTaggedTextWithNative } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
2
- export function extractReasoningSegments(source, reasoningCollector) {
3
- let working = source ?? '';
4
- const hasExplicitOpen = /<think>/i.test(source) ||
5
- /<reflection>/i.test(source) ||
6
- /```\s*(?:think|reflection)/i.test(source);
7
- const hasExplicitClose = /<\/think>/i.test(source) ||
8
- /<\/reflection>/i.test(source);
9
- const push = (value) => {
10
- const trimmed = (value ?? '').trim();
11
- if (trimmed && reasoningCollector) {
12
- reasoningCollector.push(trimmed);
13
- }
14
- };
15
- const patterns = [
16
- /<think>([\s\S]*?)<\/think>/gi,
17
- /<reflection>([\s\S]*?)<\/reflection>/gi,
18
- /```\s*(?:think|reflection)[\s\S]*?```/gi
19
- ];
20
- for (const pattern of patterns) {
21
- working = working.replace(pattern, (_match, inner) => {
22
- push(inner);
23
- return '';
24
- });
1
+ import { extractReasoningSegmentsWithNative, sanitizeReasoningTaggedTextWithNative } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
2
+ function assertReasoningUtilsNativeAvailable() {
3
+ if (typeof extractReasoningSegmentsWithNative !== 'function' ||
4
+ typeof sanitizeReasoningTaggedTextWithNative !== 'function') {
5
+ throw new Error('[reasoning-utils] native bindings unavailable');
25
6
  }
26
- working = working
27
- .replace(/<\/?think>/gi, '')
28
- .replace(/<\/?reflection>/gi, '');
29
- working = working.replace(/\n{3,}/g, '\n\n');
30
- if (reasoningCollector && !hasExplicitOpen && hasExplicitClose) {
31
- const trimmed = working.trim();
32
- if (trimmed.length) {
33
- reasoningCollector.push(trimmed);
34
- }
35
- return '';
7
+ }
8
+ export function extractReasoningSegments(source, reasoningCollector) {
9
+ assertReasoningUtilsNativeAvailable();
10
+ const output = extractReasoningSegmentsWithNative(source ?? '');
11
+ if (reasoningCollector) {
12
+ reasoningCollector.push(...output.segments);
36
13
  }
37
- return working.trim();
14
+ return output.text;
38
15
  }
39
16
  export function sanitizeReasoningTaggedText(value) {
17
+ assertReasoningUtilsNativeAvailable();
40
18
  return sanitizeReasoningTaggedTextWithNative(value);
41
19
  }
@@ -6,9 +6,9 @@ export interface CallIdTransformer {
6
6
  normalizeOutputId(callId: string, raw: unknown): string;
7
7
  }
8
8
  export declare function createToolCallIdTransformer(style: ToolCallIdStyle): CallIdTransformer | null;
9
- export declare function enforceToolCallIdStyle(input: BridgeInputItem[], transformer: CallIdTransformer): void;
10
9
  export declare function normalizeResponsesToolCallIds(payload: Record<string, unknown> | null | undefined): void;
11
10
  export declare function resolveToolCallIdStyle(metadata: Record<string, unknown> | undefined): ToolCallIdStyle;
12
11
  export declare function stripInternalToolingMetadata(metadata: unknown): void;
13
12
  export declare function sanitizeResponsesFunctionName(rawName: unknown): string | undefined;
13
+ export declare function enforceToolCallIdStyle(input: BridgeInputItem[], transformer: CallIdTransformer): void;
14
14
  export {};