@ai-sdk-tool/parser 2.1.2 → 2.1.4

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.
package/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright 2025 Woonggi Min (https://github.com/minpeter)
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
package/README.md CHANGED
@@ -127,3 +127,7 @@ See `examples/parser-core/src/*` for runnable demos (streaming/non‑streaming,
127
127
  - `toolNames`: internal propagation of custom tool names.
128
128
  - `toolChoice`: internal fast‑path activation for required/specific tool modes.
129
129
  - Transform details: `transformParams` injects a system message built from protocol `formatTools` and clears `tools` since many providers strip/ignore them.
130
+
131
+ ## License
132
+
133
+ Licensed under Apache License 2.0. See the repository `LICENSE`. Include the `NOTICE` file in distributions.
package/dist/index.cjs CHANGED
@@ -20,11 +20,30 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ RJSON: () => robust_json_exports,
24
+ coerceBySchema: () => coerceBySchema,
25
+ coerceToolCallInput: () => coerceToolCallInput,
26
+ createDynamicIfThenElseSchema: () => createDynamicIfThenElseSchema,
23
27
  createToolMiddleware: () => createToolMiddleware,
28
+ escapeRegExp: () => escapeRegExp,
29
+ extractOnErrorOption: () => extractOnErrorOption,
30
+ fixToolCallWithSchema: () => fixToolCallWithSchema,
24
31
  gemmaToolMiddleware: () => gemmaToolMiddleware,
32
+ getDebugLevel: () => getDebugLevel,
33
+ getFunctionTools: () => getFunctionTools,
34
+ getPotentialStartIndex: () => getPotentialStartIndex,
35
+ getSchemaType: () => getSchemaType,
36
+ hasInputProperty: () => hasInputProperty,
25
37
  hermesToolMiddleware: () => hermesToolMiddleware,
38
+ isToolCallContent: () => isToolCallContent,
39
+ isToolChoiceActive: () => isToolChoiceActive,
40
+ isToolResultPart: () => isToolResultPart,
26
41
  jsonMixProtocol: () => jsonMixProtocol,
42
+ logParsedChunk: () => logParsedChunk,
43
+ logParsedSummary: () => logParsedSummary,
44
+ logRawChunk: () => logRawChunk,
27
45
  morphXmlProtocol: () => morphXmlProtocol,
46
+ unwrapJsonSchema: () => unwrapJsonSchema,
28
47
  xmlToolMiddleware: () => xmlToolMiddleware
29
48
  });
30
49
  module.exports = __toCommonJS(index_exports);
@@ -114,9 +133,9 @@ function escapeRegExp(literal) {
114
133
  return literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
115
134
  }
116
135
 
117
- // src/utils/relaxed-json.ts
118
- var relaxed_json_exports = {};
119
- __export(relaxed_json_exports, {
136
+ // src/utils/robust-json.ts
137
+ var robust_json_exports = {};
138
+ __export(robust_json_exports, {
120
139
  parse: () => parse,
121
140
  stringify: () => stringify,
122
141
  transform: () => transform
@@ -1038,11 +1057,6 @@ function extractOnErrorOption(providerOptions) {
1038
1057
  return void 0;
1039
1058
  }
1040
1059
 
1041
- // src/utils/protocol.ts
1042
- function isProtocolFactory(protocol) {
1043
- return typeof protocol === "function";
1044
- }
1045
-
1046
1060
  // src/utils/tools.ts
1047
1061
  function isToolChoiceActive(params) {
1048
1062
  var _a, _b, _c;
@@ -1139,7 +1153,7 @@ var jsonMixProtocol = ({
1139
1153
  }
1140
1154
  if (toolCallJson) {
1141
1155
  try {
1142
- const parsedToolCall = relaxed_json_exports.parse(toolCallJson);
1156
+ const parsedToolCall = robust_json_exports.parse(toolCallJson);
1143
1157
  processedElements.push({
1144
1158
  type: "tool-call",
1145
1159
  toolCallId: (0, import_provider_utils2.generateId)(),
@@ -1262,7 +1276,7 @@ var jsonMixProtocol = ({
1262
1276
  isInsideToolCall = true;
1263
1277
  } else {
1264
1278
  try {
1265
- const parsedToolCall = relaxed_json_exports.parse(currentToolCallJson);
1279
+ const parsedToolCall = robust_json_exports.parse(currentToolCallJson);
1266
1280
  if (currentTextId && hasEmittedTextStart) {
1267
1281
  controller.enqueue({ type: "text-end", id: currentTextId });
1268
1282
  currentTextId = null;
@@ -1324,7 +1338,51 @@ var jsonMixProtocol = ({
1324
1338
 
1325
1339
  // src/protocols/morph-xml-protocol.ts
1326
1340
  var import_provider_utils3 = require("@ai-sdk/provider-utils");
1327
- var import_fast_xml_parser = require("fast-xml-parser");
1341
+ var import_rxml = require("@ai-sdk-tool/rxml");
1342
+ function getToolSchema(tools, originalSchemas, toolName) {
1343
+ var _a;
1344
+ const original = originalSchemas[toolName];
1345
+ if (original) return original;
1346
+ const fallback = (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
1347
+ return fallback;
1348
+ }
1349
+ function findToolCalls(text, toolNames) {
1350
+ const toolCalls = [];
1351
+ for (const toolName of toolNames) {
1352
+ let searchIndex = 0;
1353
+ while (searchIndex < text.length) {
1354
+ const startTag = `<${toolName}>`;
1355
+ const tagStart = text.indexOf(startTag, searchIndex);
1356
+ if (tagStart === -1) break;
1357
+ const remainingText = text.substring(tagStart);
1358
+ const range = (0, import_rxml.findFirstTopLevelRange)(remainingText, toolName);
1359
+ if (range) {
1360
+ const contentStart = tagStart + startTag.length;
1361
+ const contentEnd = contentStart + (range.end - range.start);
1362
+ let fullTagEnd = contentEnd + `</${toolName}>`.length;
1363
+ const closeHead = text.indexOf(`</${toolName}`, contentEnd);
1364
+ if (closeHead === contentEnd) {
1365
+ let p = closeHead + 2 + toolName.length;
1366
+ while (p < text.length && /\s/.test(text[p])) p++;
1367
+ if (text[p] === ">") fullTagEnd = p + 1;
1368
+ }
1369
+ const toolContent = text.substring(contentStart, contentEnd);
1370
+ const fullSegment = text.substring(tagStart, fullTagEnd);
1371
+ toolCalls.push({
1372
+ toolName,
1373
+ startIndex: tagStart,
1374
+ endIndex: fullTagEnd,
1375
+ content: toolContent,
1376
+ segment: fullSegment
1377
+ });
1378
+ searchIndex = fullTagEnd;
1379
+ } else {
1380
+ searchIndex = tagStart + startTag.length;
1381
+ }
1382
+ }
1383
+ }
1384
+ return toolCalls.sort((a, b) => a.startIndex - b.startIndex);
1385
+ }
1328
1386
  var morphXmlProtocol = () => ({
1329
1387
  formatTools({ tools, toolSystemPromptTemplate }) {
1330
1388
  const toolsForPrompt = (tools || []).map((tool) => ({
@@ -1335,7 +1393,6 @@ var morphXmlProtocol = () => ({
1335
1393
  return toolSystemPromptTemplate(JSON.stringify(toolsForPrompt));
1336
1394
  },
1337
1395
  formatToolCall(toolCall) {
1338
- const builder = new import_fast_xml_parser.XMLBuilder({ format: true, suppressEmptyNode: true });
1339
1396
  let args = {};
1340
1397
  const inputValue = hasInputProperty(toolCall) ? toolCall.input : void 0;
1341
1398
  if (typeof inputValue === "string") {
@@ -1347,145 +1404,63 @@ var morphXmlProtocol = () => ({
1347
1404
  } else {
1348
1405
  args = inputValue;
1349
1406
  }
1350
- const xmlContent = builder.build({
1351
- [toolCall.toolName]: args
1407
+ return (0, import_rxml.stringify)(toolCall.toolName, args, {
1408
+ suppressEmptyNode: false,
1409
+ format: false
1352
1410
  });
1353
- return xmlContent;
1354
1411
  },
1355
1412
  formatToolResponse(toolResult) {
1356
- const builder = new import_fast_xml_parser.XMLBuilder({ format: true });
1357
- const xmlContent = builder.build({
1358
- tool_response: {
1359
- tool_name: toolResult.toolName,
1360
- result: toolResult.output
1361
- }
1413
+ return (0, import_rxml.stringify)("tool_response", {
1414
+ tool_name: toolResult.toolName,
1415
+ result: toolResult.output
1362
1416
  });
1363
- return xmlContent;
1364
1417
  },
1365
1418
  parseGeneratedText({ text, tools, options }) {
1366
- var _a, _b, _c;
1419
+ var _a;
1367
1420
  const originalSchemas = (options == null ? void 0 : options.originalToolSchemas) || {};
1368
1421
  const toolNames = tools.map((t) => t.name).filter((name) => name != null);
1369
1422
  if (toolNames.length === 0) {
1370
1423
  return [{ type: "text", text }];
1371
1424
  }
1372
- const toolNamesPattern = toolNames.map((n) => escapeRegExp(n)).join("|");
1373
- const toolCallRegex = new RegExp(
1374
- String.raw`<(${toolNamesPattern})>([\s\S]*?)<\/\1>`,
1375
- "g"
1376
- );
1377
1425
  const processedElements = [];
1378
1426
  let currentIndex = 0;
1379
- let match;
1380
- while ((match = toolCallRegex.exec(text)) !== null) {
1381
- const startIndex = match.index;
1382
- const toolName = match[1];
1383
- const toolContent = match[2].trim();
1384
- if (startIndex > currentIndex) {
1385
- const textSegment = text.substring(currentIndex, startIndex);
1427
+ const toolCalls = findToolCalls(text, toolNames);
1428
+ for (const toolCall of toolCalls) {
1429
+ if (toolCall.startIndex > currentIndex) {
1430
+ const textSegment = text.substring(currentIndex, toolCall.startIndex);
1386
1431
  if (textSegment.trim()) {
1387
1432
  processedElements.push({ type: "text", text: textSegment });
1388
1433
  }
1389
1434
  }
1390
1435
  try {
1391
- const parser = new import_fast_xml_parser.XMLParser({
1392
- ignoreAttributes: false,
1393
- parseTagValue: false,
1394
- ignoreDeclaration: true,
1395
- textNodeName: "#text"
1436
+ const toolSchema = getToolSchema(
1437
+ tools,
1438
+ originalSchemas,
1439
+ toolCall.toolName
1440
+ );
1441
+ const parsed = (0, import_rxml.parse)(toolCall.content, toolSchema, {
1442
+ onError: options == null ? void 0 : options.onError
1396
1443
  });
1397
- const parsedArgs = ((_a = parser.parse(`<root>${toolContent}</root>`)) == null ? void 0 : _a.root) || {};
1398
- const args = {};
1399
- for (const k of Object.keys(parsedArgs || {})) {
1400
- const v = parsedArgs[k];
1401
- let val = v;
1402
- if (v && typeof v === "object" && Object.prototype.hasOwnProperty.call(v, "#text")) {
1403
- val = v == null ? void 0 : v["#text"];
1404
- }
1405
- if (Array.isArray(v)) {
1406
- val = v.map((item) => {
1407
- if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
1408
- const textVal = item == null ? void 0 : item["#text"];
1409
- return typeof textVal === "string" ? textVal.trim() : textVal;
1410
- }
1411
- return typeof item === "string" ? item.trim() : item;
1412
- });
1413
- } else if (v && typeof v === "object" && !Object.prototype.hasOwnProperty.call(v, "#text")) {
1414
- const obj = v;
1415
- const keys = Object.keys(obj);
1416
- if (keys.length === 1 && keys[0] === "item") {
1417
- const itemValue = obj.item;
1418
- if (Array.isArray(itemValue)) {
1419
- val = itemValue.map((item) => {
1420
- if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
1421
- const textVal = item == null ? void 0 : item["#text"];
1422
- const trimmed2 = typeof textVal === "string" ? textVal.trim() : textVal;
1423
- if (typeof trimmed2 === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed2)) {
1424
- const num = Number(trimmed2);
1425
- if (Number.isFinite(num)) return num;
1426
- }
1427
- return trimmed2;
1428
- }
1429
- const trimmed = typeof item === "string" ? item.trim() : item;
1430
- if (typeof trimmed === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed)) {
1431
- const num = Number(trimmed);
1432
- if (Number.isFinite(num)) return num;
1433
- }
1434
- return trimmed;
1435
- });
1436
- } else {
1437
- const trimmed = typeof itemValue === "string" ? itemValue.trim() : itemValue;
1438
- if (typeof trimmed === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed)) {
1439
- const num = Number(trimmed);
1440
- if (Number.isFinite(num)) {
1441
- val = num;
1442
- } else {
1443
- val = trimmed;
1444
- }
1445
- } else {
1446
- val = trimmed;
1447
- }
1448
- }
1449
- } else {
1450
- const isIndexedTuple = keys.length > 0 && keys.every((key) => /^\d+$/.test(key)) && (() => {
1451
- const indices = keys.map((k2) => parseInt(k2)).sort((a, b) => a - b);
1452
- return indices[0] === 0 && indices.every((val2, idx) => val2 === idx);
1453
- })();
1454
- if (isIndexedTuple) {
1455
- const sortedKeys = keys.sort(
1456
- (a, b) => parseInt(a) - parseInt(b)
1457
- );
1458
- val = sortedKeys.map((key) => {
1459
- const item = obj[key];
1460
- if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
1461
- const textVal = item == null ? void 0 : item["#text"];
1462
- return typeof textVal === "string" ? textVal.trim() : textVal;
1463
- }
1464
- return typeof item === "string" ? item.trim() : item;
1465
- });
1466
- } else {
1467
- val = v;
1468
- }
1469
- }
1470
- }
1471
- args[k] = typeof val === "string" ? val.trim() : val;
1472
- }
1473
- const originalSchema = originalSchemas[toolName];
1474
- const fallbackSchema = (_b = tools.find((t) => t.name === toolName)) == null ? void 0 : _b.inputSchema;
1475
- const schema = originalSchema || fallbackSchema;
1476
- const coercedArgs = coerceBySchema(args, schema);
1477
1444
  processedElements.push({
1478
1445
  type: "tool-call",
1479
1446
  toolCallId: (0, import_provider_utils3.generateId)(),
1480
- toolName,
1481
- input: JSON.stringify(coercedArgs)
1447
+ toolName: toolCall.toolName,
1448
+ input: JSON.stringify(parsed)
1482
1449
  });
1483
1450
  } catch (error) {
1484
- const message = `Could not process XML tool call, keeping original text: ${match[0]}`;
1485
- (_c = options == null ? void 0 : options.onError) == null ? void 0 : _c.call(options, message, { toolCall: match[0], toolName, error });
1486
- processedElements.push({ type: "text", text: match[0] });
1451
+ const originalCallText = text.substring(
1452
+ toolCall.startIndex,
1453
+ toolCall.endIndex
1454
+ );
1455
+ const message = `Could not process XML tool call, keeping original text: ${originalCallText}`;
1456
+ (_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, message, {
1457
+ toolCall: originalCallText,
1458
+ toolName: toolCall.toolName,
1459
+ error
1460
+ });
1461
+ processedElements.push({ type: "text", text: originalCallText });
1487
1462
  }
1488
- currentIndex = startIndex + match[0].length;
1463
+ currentIndex = toolCall.endIndex;
1489
1464
  }
1490
1465
  if (currentIndex < text.length) {
1491
1466
  const remainingText = text.substring(currentIndex);
@@ -1524,7 +1499,7 @@ var morphXmlProtocol = () => ({
1524
1499
  };
1525
1500
  return new TransformStream({
1526
1501
  transform(chunk, controller) {
1527
- var _a, _b;
1502
+ var _a;
1528
1503
  if (chunk.type !== "text-delta") {
1529
1504
  if (buffer) flushText(controller);
1530
1505
  controller.enqueue(chunk);
@@ -1539,112 +1514,36 @@ var morphXmlProtocol = () => ({
1539
1514
  const toolContent = buffer.substring(0, endTagIndex);
1540
1515
  buffer = buffer.substring(endTagIndex + endTag.length);
1541
1516
  try {
1542
- const parser = new import_fast_xml_parser.XMLParser({
1543
- ignoreAttributes: false,
1544
- parseTagValue: false,
1545
- ignoreDeclaration: true,
1546
- textNodeName: "#text"
1517
+ const toolSchema = getToolSchema(
1518
+ tools,
1519
+ originalSchemas,
1520
+ currentToolCall.name
1521
+ );
1522
+ const parsed = (0, import_rxml.parse)(toolContent, toolSchema, {
1523
+ onError: options == null ? void 0 : options.onError
1547
1524
  });
1548
- const parsedArgs = ((_a = parser.parse(`<root>${toolContent}</root>`)) == null ? void 0 : _a.root) || {};
1549
- const args = {};
1550
- for (const k of Object.keys(parsedArgs || {})) {
1551
- const v = parsedArgs[k];
1552
- let val = v;
1553
- if (v && typeof v === "object" && Object.prototype.hasOwnProperty.call(v, "#text")) {
1554
- val = v == null ? void 0 : v["#text"];
1555
- }
1556
- if (Array.isArray(v)) {
1557
- val = v.map((item) => {
1558
- if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
1559
- const textVal = item == null ? void 0 : item["#text"];
1560
- return typeof textVal === "string" ? textVal.trim() : textVal;
1561
- }
1562
- return typeof item === "string" ? item.trim() : item;
1563
- });
1564
- } else if (v && typeof v === "object" && !Object.prototype.hasOwnProperty.call(v, "#text")) {
1565
- const obj = v;
1566
- const keys = Object.keys(obj);
1567
- if (keys.length === 1 && keys[0] === "item") {
1568
- const itemValue = obj.item;
1569
- if (Array.isArray(itemValue)) {
1570
- val = itemValue.map((item) => {
1571
- if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
1572
- const textVal = item == null ? void 0 : item["#text"];
1573
- const trimmed2 = typeof textVal === "string" ? textVal.trim() : textVal;
1574
- if (typeof trimmed2 === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed2)) {
1575
- const num = Number(trimmed2);
1576
- if (Number.isFinite(num)) return num;
1577
- }
1578
- return trimmed2;
1579
- }
1580
- const trimmed = typeof item === "string" ? item.trim() : item;
1581
- if (typeof trimmed === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed)) {
1582
- const num = Number(trimmed);
1583
- if (Number.isFinite(num)) return num;
1584
- }
1585
- return trimmed;
1586
- });
1587
- } else {
1588
- const trimmed = typeof itemValue === "string" ? itemValue.trim() : itemValue;
1589
- if (typeof trimmed === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed)) {
1590
- const num = Number(trimmed);
1591
- if (Number.isFinite(num)) {
1592
- val = num;
1593
- } else {
1594
- val = trimmed;
1595
- }
1596
- } else {
1597
- val = trimmed;
1598
- }
1599
- }
1600
- } else {
1601
- const isIndexedTuple = keys.length > 0 && keys.every((key) => /^\d+$/.test(key)) && (() => {
1602
- const indices = keys.map((k2) => parseInt(k2)).sort((a, b) => a - b);
1603
- return indices[0] === 0 && indices.every((val2, idx) => val2 === idx);
1604
- })();
1605
- if (isIndexedTuple) {
1606
- const sortedKeys = keys.sort(
1607
- (a, b) => parseInt(a) - parseInt(b)
1608
- );
1609
- val = sortedKeys.map((key) => {
1610
- const item = obj[key];
1611
- if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
1612
- const textVal = item == null ? void 0 : item["#text"];
1613
- return typeof textVal === "string" ? textVal.trim() : textVal;
1614
- }
1615
- return typeof item === "string" ? item.trim() : item;
1616
- });
1617
- } else {
1618
- val = v;
1619
- }
1620
- }
1621
- }
1622
- args[k] = typeof val === "string" ? val.trim() : val;
1623
- }
1624
- const originalSchema = originalSchemas[currentToolCall.name];
1625
- const fallbackSchema = (_b = tools.find(
1626
- (t) => t.name === currentToolCall.name
1627
- )) == null ? void 0 : _b.inputSchema;
1628
- const toolSchema = originalSchema || fallbackSchema;
1629
- const coercedArgs = coerceBySchema(args, toolSchema);
1630
1525
  flushText(controller);
1631
1526
  controller.enqueue({
1632
1527
  type: "tool-call",
1633
1528
  toolCallId: (0, import_provider_utils3.generateId)(),
1634
1529
  toolName: currentToolCall.name,
1635
- input: JSON.stringify(coercedArgs)
1530
+ input: JSON.stringify(parsed)
1636
1531
  });
1637
- } catch (e) {
1532
+ } catch (error) {
1638
1533
  const originalCallText = `<${currentToolCall.name}>${toolContent}${endTag}`;
1639
- if (options == null ? void 0 : options.onError) {
1640
- options.onError(
1641
- "Could not process streaming XML tool call; emitting original text.",
1642
- {
1643
- toolCall: originalCallText,
1644
- toolName: currentToolCall.name
1645
- }
1646
- );
1534
+ let message = "Could not process streaming XML tool call; emitting original text.";
1535
+ if (error instanceof import_rxml.RXMLDuplicateStringTagError) {
1536
+ message = `Duplicate string tags detected in streaming tool call '${currentToolCall.name}'; emitting original text.`;
1537
+ } else if (error instanceof import_rxml.RXMLCoercionError) {
1538
+ message = `Failed to coerce arguments for streaming tool call '${currentToolCall.name}'; emitting original text.`;
1539
+ } else if (error instanceof import_rxml.RXMLParseError) {
1540
+ message = `Failed to parse XML for streaming tool call '${currentToolCall.name}'; emitting original text.`;
1647
1541
  }
1542
+ (_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, message, {
1543
+ toolCall: originalCallText,
1544
+ toolName: currentToolCall.name,
1545
+ error
1546
+ });
1648
1547
  flushText(controller, originalCallText);
1649
1548
  }
1650
1549
  currentToolCall = null;
@@ -1694,18 +1593,15 @@ var morphXmlProtocol = () => ({
1694
1593
  extractToolCallSegments({ text, tools }) {
1695
1594
  const toolNames = tools.map((t) => t.name).filter(Boolean);
1696
1595
  if (toolNames.length === 0) return [];
1697
- const names = toolNames.map((n) => escapeRegExp(String(n))).join("|");
1698
- if (!names) return [];
1699
- const regex = new RegExp(`<(${names})>[\\s\\S]*?<\\/\\1>`, "g");
1700
- const segments = [];
1701
- let m;
1702
- while ((m = regex.exec(text)) != null) {
1703
- segments.push(m[0]);
1704
- }
1705
- return segments;
1596
+ return findToolCalls(text, toolNames).map((tc) => tc.segment);
1706
1597
  }
1707
1598
  });
1708
1599
 
1600
+ // src/protocols/tool-call-protocol.ts
1601
+ function isProtocolFactory(protocol) {
1602
+ return typeof protocol === "function";
1603
+ }
1604
+
1709
1605
  // src/generate-handler.ts
1710
1606
  var import_provider_utils4 = require("@ai-sdk/provider-utils");
1711
1607
  async function wrapGenerate({
@@ -2321,11 +2217,30 @@ San Fransisco
2321
2217
  });
2322
2218
  // Annotate the CommonJS export names for ESM import in node:
2323
2219
  0 && (module.exports = {
2220
+ RJSON,
2221
+ coerceBySchema,
2222
+ coerceToolCallInput,
2223
+ createDynamicIfThenElseSchema,
2324
2224
  createToolMiddleware,
2225
+ escapeRegExp,
2226
+ extractOnErrorOption,
2227
+ fixToolCallWithSchema,
2325
2228
  gemmaToolMiddleware,
2229
+ getDebugLevel,
2230
+ getFunctionTools,
2231
+ getPotentialStartIndex,
2232
+ getSchemaType,
2233
+ hasInputProperty,
2326
2234
  hermesToolMiddleware,
2235
+ isToolCallContent,
2236
+ isToolChoiceActive,
2237
+ isToolResultPart,
2327
2238
  jsonMixProtocol,
2239
+ logParsedChunk,
2240
+ logParsedSummary,
2241
+ logRawChunk,
2328
2242
  morphXmlProtocol,
2243
+ unwrapJsonSchema,
2329
2244
  xmlToolMiddleware
2330
2245
  });
2331
2246
  //# sourceMappingURL=index.cjs.map