@ai-sdk-tool/parser 2.1.2 → 2.1.3

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/dist/index.js CHANGED
@@ -1300,6 +1300,607 @@ var jsonMixProtocol = ({
1300
1300
  // src/protocols/morph-xml-protocol.ts
1301
1301
  import { generateId as generateId3 } from "@ai-sdk/provider-utils";
1302
1302
  import { XMLBuilder, XMLParser } from "fast-xml-parser";
1303
+ var WARN_ON_DUPLICATE_STRING_TAGS = true;
1304
+ function getToolSchema(tools, originalSchemas, toolName) {
1305
+ var _a;
1306
+ const original = originalSchemas[toolName];
1307
+ if (original) return original;
1308
+ const fallback = (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
1309
+ return fallback;
1310
+ }
1311
+ function getPropertySchema(toolSchema, key) {
1312
+ const unwrapped = unwrapJsonSchema(toolSchema);
1313
+ if (!unwrapped || typeof unwrapped !== "object") return void 0;
1314
+ const u = unwrapped;
1315
+ const props = u.properties;
1316
+ if (props && Object.prototype.hasOwnProperty.call(props, key)) {
1317
+ return props[key];
1318
+ }
1319
+ return void 0;
1320
+ }
1321
+ function extractRawInner(xmlContent, tagName) {
1322
+ const isNameStartChar = (ch) => /[A-Za-z_:]/.test(ch);
1323
+ const isNameChar = (ch) => /[A-Za-z0-9_.:-]/.test(ch);
1324
+ const len = xmlContent.length;
1325
+ const target = tagName;
1326
+ let bestStart = -1;
1327
+ let bestEnd = -1;
1328
+ let bestDepth = Number.POSITIVE_INFINITY;
1329
+ const skipQuoted = (s, i2) => {
1330
+ const quote = s[i2];
1331
+ i2++;
1332
+ while (i2 < s.length) {
1333
+ const ch = s[i2];
1334
+ if (ch === "\\") {
1335
+ i2 += 2;
1336
+ continue;
1337
+ }
1338
+ if (ch === quote) {
1339
+ return i2 + 1;
1340
+ }
1341
+ i2++;
1342
+ }
1343
+ return i2;
1344
+ };
1345
+ let i = 0;
1346
+ let depth = 0;
1347
+ while (i < len) {
1348
+ const lt = xmlContent.indexOf("<", i);
1349
+ if (lt === -1) return void 0;
1350
+ i = lt + 1;
1351
+ if (i >= len) return void 0;
1352
+ const ch = xmlContent[i];
1353
+ if (ch === "!") {
1354
+ if (xmlContent.startsWith("!--", i + 1)) {
1355
+ const close = xmlContent.indexOf("-->", i + 4);
1356
+ i = close === -1 ? len : close + 3;
1357
+ continue;
1358
+ }
1359
+ if (xmlContent.startsWith("![CDATA[", i + 1)) {
1360
+ const close = xmlContent.indexOf("]]>", i + 9);
1361
+ i = close === -1 ? len : close + 3;
1362
+ continue;
1363
+ }
1364
+ const gt = xmlContent.indexOf(">", i + 1);
1365
+ i = gt === -1 ? len : gt + 1;
1366
+ continue;
1367
+ } else if (ch === "?") {
1368
+ const close = xmlContent.indexOf("?>", i + 1);
1369
+ i = close === -1 ? len : close + 2;
1370
+ continue;
1371
+ } else if (ch === "/") {
1372
+ let j = i + 1;
1373
+ if (j < len && isNameStartChar(xmlContent[j])) {
1374
+ j++;
1375
+ while (j < len && isNameChar(xmlContent[j])) j++;
1376
+ }
1377
+ const gt = xmlContent.indexOf(">", j);
1378
+ i = gt === -1 ? len : gt + 1;
1379
+ depth = Math.max(0, depth - 1);
1380
+ continue;
1381
+ } else {
1382
+ let j = i;
1383
+ if (j < len && isNameStartChar(xmlContent[j])) {
1384
+ j++;
1385
+ while (j < len && isNameChar(xmlContent[j])) j++;
1386
+ }
1387
+ const name = xmlContent.slice(i, j);
1388
+ let k = j;
1389
+ let isSelfClosing = false;
1390
+ while (k < len) {
1391
+ const c = xmlContent[k];
1392
+ if (c === '"' || c === "'") {
1393
+ k = skipQuoted(xmlContent, k);
1394
+ continue;
1395
+ }
1396
+ if (c === ">") {
1397
+ break;
1398
+ }
1399
+ if (c === "/" && xmlContent[k + 1] === ">") {
1400
+ isSelfClosing = true;
1401
+ k++;
1402
+ break;
1403
+ }
1404
+ k++;
1405
+ }
1406
+ const tagEnd = k;
1407
+ if (name === target) {
1408
+ const contentStart = xmlContent[tagEnd] === ">" ? tagEnd + 1 : tagEnd + 1;
1409
+ if (isSelfClosing) {
1410
+ if (depth < bestDepth) {
1411
+ bestStart = contentStart;
1412
+ bestEnd = contentStart;
1413
+ bestDepth = depth;
1414
+ if (bestDepth === 0) {
1415
+ }
1416
+ }
1417
+ } else {
1418
+ let pos = contentStart;
1419
+ let sameDepth = 1;
1420
+ while (pos < len) {
1421
+ const nextLt = xmlContent.indexOf("<", pos);
1422
+ if (nextLt === -1) break;
1423
+ const nx = nextLt + 1;
1424
+ if (nx >= len) break;
1425
+ const h = xmlContent[nx];
1426
+ if (h === "!") {
1427
+ if (xmlContent.startsWith("!--", nx + 1)) {
1428
+ const close = xmlContent.indexOf("-->", nx + 4);
1429
+ pos = close === -1 ? len : close + 3;
1430
+ continue;
1431
+ }
1432
+ if (xmlContent.startsWith("![CDATA[", nx + 1)) {
1433
+ const close = xmlContent.indexOf("]]>", nx + 9);
1434
+ pos = close === -1 ? len : close + 3;
1435
+ continue;
1436
+ }
1437
+ const gt2 = xmlContent.indexOf(">", nx + 1);
1438
+ pos = gt2 === -1 ? len : gt2 + 1;
1439
+ continue;
1440
+ } else if (h === "?") {
1441
+ const close = xmlContent.indexOf("?>", nx + 1);
1442
+ pos = close === -1 ? len : close + 2;
1443
+ continue;
1444
+ } else if (h === "/") {
1445
+ let t = nx + 1;
1446
+ if (t < len && isNameStartChar(xmlContent[t])) {
1447
+ t++;
1448
+ while (t < len && isNameChar(xmlContent[t])) t++;
1449
+ }
1450
+ const endName = xmlContent.slice(nx + 1, t);
1451
+ const gt2 = xmlContent.indexOf(">", t);
1452
+ if (endName === target) {
1453
+ sameDepth--;
1454
+ if (sameDepth === 0) {
1455
+ if (depth < bestDepth) {
1456
+ bestStart = contentStart;
1457
+ bestEnd = nextLt;
1458
+ bestDepth = depth;
1459
+ if (bestDepth === 0) {
1460
+ }
1461
+ }
1462
+ break;
1463
+ }
1464
+ }
1465
+ pos = gt2 === -1 ? len : gt2 + 1;
1466
+ continue;
1467
+ } else {
1468
+ let t = nx;
1469
+ if (t < len && isNameStartChar(xmlContent[t])) {
1470
+ t++;
1471
+ while (t < len && isNameChar(xmlContent[t])) t++;
1472
+ }
1473
+ const startName = xmlContent.slice(nx, t);
1474
+ let u = t;
1475
+ let selfClose = false;
1476
+ while (u < len) {
1477
+ const cu = xmlContent[u];
1478
+ if (cu === '"' || cu === "'") {
1479
+ u = skipQuoted(xmlContent, u);
1480
+ continue;
1481
+ }
1482
+ if (cu === ">") break;
1483
+ if (cu === "/" && xmlContent[u + 1] === ">") {
1484
+ selfClose = true;
1485
+ u++;
1486
+ break;
1487
+ }
1488
+ u++;
1489
+ }
1490
+ if (startName === target && !selfClose) {
1491
+ sameDepth++;
1492
+ }
1493
+ pos = xmlContent[u] === ">" ? u + 1 : u + 1;
1494
+ continue;
1495
+ }
1496
+ }
1497
+ }
1498
+ }
1499
+ i = xmlContent[tagEnd] === ">" ? tagEnd + 1 : tagEnd + 1;
1500
+ depth += isSelfClosing ? 0 : 1;
1501
+ continue;
1502
+ }
1503
+ }
1504
+ if (bestStart !== -1) {
1505
+ return xmlContent.slice(bestStart, bestEnd);
1506
+ }
1507
+ return void 0;
1508
+ }
1509
+ function findFirstTopLevelRange(xmlContent, tagName) {
1510
+ const isNameStartChar = (ch) => /[A-Za-z_:]/.test(ch);
1511
+ const isNameChar = (ch) => /[A-Za-z0-9_.:-]/.test(ch);
1512
+ const len = xmlContent.length;
1513
+ const target = tagName;
1514
+ const skipQuoted = (s, i2) => {
1515
+ const quote = s[i2];
1516
+ i2++;
1517
+ while (i2 < s.length) {
1518
+ const ch = s[i2];
1519
+ if (ch === "\\") {
1520
+ i2 += 2;
1521
+ continue;
1522
+ }
1523
+ if (ch === quote) return i2 + 1;
1524
+ i2++;
1525
+ }
1526
+ return i2;
1527
+ };
1528
+ let i = 0;
1529
+ let depth = 0;
1530
+ while (i < len) {
1531
+ const lt = xmlContent.indexOf("<", i);
1532
+ if (lt === -1) return void 0;
1533
+ i = lt + 1;
1534
+ if (i >= len) return void 0;
1535
+ const ch = xmlContent[i];
1536
+ if (ch === "!") {
1537
+ if (xmlContent.startsWith("!--", i + 1)) {
1538
+ const close = xmlContent.indexOf("-->", i + 4);
1539
+ i = close === -1 ? len : close + 3;
1540
+ continue;
1541
+ }
1542
+ if (xmlContent.startsWith("![CDATA[", i + 1)) {
1543
+ const close = xmlContent.indexOf("]]>", i + 9);
1544
+ i = close === -1 ? len : close + 3;
1545
+ continue;
1546
+ }
1547
+ const gt = xmlContent.indexOf(">", i + 1);
1548
+ i = gt === -1 ? len : gt + 1;
1549
+ continue;
1550
+ } else if (ch === "?") {
1551
+ const close = xmlContent.indexOf("?>", i + 1);
1552
+ i = close === -1 ? len : close + 2;
1553
+ continue;
1554
+ } else if (ch === "/") {
1555
+ const gt = xmlContent.indexOf(">", i + 1);
1556
+ i = gt === -1 ? len : gt + 1;
1557
+ depth = Math.max(0, depth - 1);
1558
+ continue;
1559
+ } else {
1560
+ let j = i;
1561
+ if (j < len && isNameStartChar(xmlContent[j])) {
1562
+ j++;
1563
+ while (j < len && isNameChar(xmlContent[j])) j++;
1564
+ }
1565
+ const name = xmlContent.slice(i, j);
1566
+ let k = j;
1567
+ let isSelfClosing = false;
1568
+ while (k < len) {
1569
+ const c = xmlContent[k];
1570
+ if (c === '"' || c === "'") {
1571
+ k = skipQuoted(xmlContent, k);
1572
+ continue;
1573
+ }
1574
+ if (c === ">") break;
1575
+ if (c === "/" && xmlContent[k + 1] === ">") {
1576
+ isSelfClosing = true;
1577
+ k++;
1578
+ break;
1579
+ }
1580
+ k++;
1581
+ }
1582
+ const tagEnd = k;
1583
+ if (depth === 0 && name === target) {
1584
+ const contentStart = xmlContent[tagEnd] === ">" ? tagEnd + 1 : tagEnd + 1;
1585
+ if (isSelfClosing) return { start: contentStart, end: contentStart };
1586
+ let pos = contentStart;
1587
+ let sameDepth = 1;
1588
+ while (pos < len) {
1589
+ const nextLt = xmlContent.indexOf("<", pos);
1590
+ if (nextLt === -1) break;
1591
+ const nx = nextLt + 1;
1592
+ if (nx >= len) break;
1593
+ const h = xmlContent[nx];
1594
+ if (h === "!") {
1595
+ if (xmlContent.startsWith("!--", nx + 1)) {
1596
+ const close = xmlContent.indexOf("-->", nx + 4);
1597
+ pos = close === -1 ? len : close + 3;
1598
+ continue;
1599
+ }
1600
+ if (xmlContent.startsWith("![CDATA[", nx + 1)) {
1601
+ const close = xmlContent.indexOf("]]>", nx + 9);
1602
+ pos = close === -1 ? len : close + 3;
1603
+ continue;
1604
+ }
1605
+ const gt2 = xmlContent.indexOf(">", nx + 1);
1606
+ pos = gt2 === -1 ? len : gt2 + 1;
1607
+ continue;
1608
+ } else if (h === "?") {
1609
+ const close = xmlContent.indexOf("?>", nx + 1);
1610
+ pos = close === -1 ? len : close + 2;
1611
+ continue;
1612
+ } else if (h === "/") {
1613
+ let t = nx + 1;
1614
+ if (t < len && isNameStartChar(xmlContent[t])) {
1615
+ t++;
1616
+ while (t < len && isNameChar(xmlContent[t])) t++;
1617
+ }
1618
+ const endName = xmlContent.slice(nx + 1, t);
1619
+ const gt2 = xmlContent.indexOf(">", t);
1620
+ if (endName === target) {
1621
+ sameDepth--;
1622
+ if (sameDepth === 0) {
1623
+ return { start: contentStart, end: nextLt };
1624
+ }
1625
+ }
1626
+ pos = gt2 === -1 ? len : gt2 + 1;
1627
+ continue;
1628
+ } else {
1629
+ let t = nx;
1630
+ if (t < len && isNameStartChar(xmlContent[t])) {
1631
+ t++;
1632
+ while (t < len && isNameChar(xmlContent[t])) t++;
1633
+ }
1634
+ let u = t;
1635
+ let selfClose = false;
1636
+ while (u < len) {
1637
+ const cu = xmlContent[u];
1638
+ if (cu === '"' || cu === "'") {
1639
+ u = skipQuoted(xmlContent, u);
1640
+ continue;
1641
+ }
1642
+ if (cu === ">") break;
1643
+ if (cu === "/" && xmlContent[u + 1] === ">") {
1644
+ selfClose = true;
1645
+ u++;
1646
+ break;
1647
+ }
1648
+ u++;
1649
+ }
1650
+ if (!selfClose) {
1651
+ }
1652
+ pos = xmlContent[u] === ">" ? u + 1 : u + 1;
1653
+ continue;
1654
+ }
1655
+ }
1656
+ return void 0;
1657
+ }
1658
+ i = xmlContent[tagEnd] === ">" ? tagEnd + 1 : tagEnd + 1;
1659
+ depth += isSelfClosing ? 0 : 1;
1660
+ continue;
1661
+ }
1662
+ }
1663
+ return void 0;
1664
+ }
1665
+ function countTagOccurrences(xmlContent, tagName, excludeRanges, skipFirst = true) {
1666
+ const isNameStartChar = (ch) => /[A-Za-z_:]/.test(ch);
1667
+ const isNameChar = (ch) => /[A-Za-z0-9_.:-]/.test(ch);
1668
+ const len = xmlContent.length;
1669
+ const target = tagName;
1670
+ const skipQuoted = (s, i2) => {
1671
+ const quote = s[i2];
1672
+ i2++;
1673
+ while (i2 < s.length) {
1674
+ const ch = s[i2];
1675
+ if (ch === "\\") {
1676
+ i2 += 2;
1677
+ continue;
1678
+ }
1679
+ if (ch === quote) return i2 + 1;
1680
+ i2++;
1681
+ }
1682
+ return i2;
1683
+ };
1684
+ let i = 0;
1685
+ let count = 0;
1686
+ const isExcluded = (pos) => {
1687
+ if (!excludeRanges || excludeRanges.length === 0) return false;
1688
+ for (const r of excludeRanges) {
1689
+ if (pos >= r.start && pos < r.end) return true;
1690
+ }
1691
+ return false;
1692
+ };
1693
+ while (i < len) {
1694
+ const lt = xmlContent.indexOf("<", i);
1695
+ if (lt === -1) break;
1696
+ i = lt + 1;
1697
+ if (i >= len) break;
1698
+ const ch = xmlContent[i];
1699
+ if (ch === "!") {
1700
+ if (xmlContent.startsWith("!--", i + 1)) {
1701
+ const close = xmlContent.indexOf("-->", i + 4);
1702
+ i = close === -1 ? len : close + 3;
1703
+ continue;
1704
+ }
1705
+ if (xmlContent.startsWith("![CDATA[", i + 1)) {
1706
+ const close = xmlContent.indexOf("]]>", i + 9);
1707
+ i = close === -1 ? len : close + 3;
1708
+ continue;
1709
+ }
1710
+ const gt = xmlContent.indexOf(">", i + 1);
1711
+ i = gt === -1 ? len : gt + 1;
1712
+ continue;
1713
+ } else if (ch === "?") {
1714
+ const close = xmlContent.indexOf("?>", i + 1);
1715
+ i = close === -1 ? len : close + 2;
1716
+ continue;
1717
+ } else if (ch === "/") {
1718
+ const gt = xmlContent.indexOf(">", i + 1);
1719
+ i = gt === -1 ? len : gt + 1;
1720
+ continue;
1721
+ } else {
1722
+ let j = i;
1723
+ if (j < len && isNameStartChar(xmlContent[j])) {
1724
+ j++;
1725
+ while (j < len && isNameChar(xmlContent[j])) j++;
1726
+ }
1727
+ const name = xmlContent.slice(i, j);
1728
+ let k = j;
1729
+ while (k < len) {
1730
+ const c = xmlContent[k];
1731
+ if (c === '"' || c === "'") {
1732
+ k = skipQuoted(xmlContent, k);
1733
+ continue;
1734
+ }
1735
+ if (c === ">") break;
1736
+ if (c === "/" && xmlContent[k + 1] === ">") {
1737
+ k++;
1738
+ break;
1739
+ }
1740
+ k++;
1741
+ }
1742
+ if (name === target && !isExcluded(lt)) {
1743
+ if (skipFirst) {
1744
+ skipFirst = false;
1745
+ } else {
1746
+ count++;
1747
+ }
1748
+ }
1749
+ i = k + 1;
1750
+ continue;
1751
+ }
1752
+ }
1753
+ return count;
1754
+ }
1755
+ function processParsedArgs(parsedArgs, toolSchema, toolContent, toolName, options) {
1756
+ var _a, _b, _c;
1757
+ const args = {};
1758
+ let cancelToolCall = false;
1759
+ const stringTypedProps = (() => {
1760
+ const set = /* @__PURE__ */ new Set();
1761
+ const unwrapped = unwrapJsonSchema(toolSchema);
1762
+ if (unwrapped && typeof unwrapped === "object") {
1763
+ const u = unwrapped;
1764
+ const props = u.properties;
1765
+ if (props && typeof props === "object") {
1766
+ for (const key of Object.keys(props)) {
1767
+ const t = getSchemaType(props[key]);
1768
+ if (t === "string") set.add(key);
1769
+ }
1770
+ }
1771
+ }
1772
+ return set;
1773
+ })();
1774
+ for (const k of Object.keys(parsedArgs || {})) {
1775
+ const v = parsedArgs[k];
1776
+ let val = v;
1777
+ const propSchema = getPropertySchema(toolSchema, k);
1778
+ const propType = getSchemaType(propSchema);
1779
+ if (propType === "string" && !Array.isArray(v)) {
1780
+ const excludeRanges = [];
1781
+ for (const other of stringTypedProps) {
1782
+ if (other === k) continue;
1783
+ const range = findFirstTopLevelRange(toolContent, other);
1784
+ if (range) excludeRanges.push(range);
1785
+ }
1786
+ const occurrences = countTagOccurrences(
1787
+ toolContent,
1788
+ k,
1789
+ excludeRanges,
1790
+ true
1791
+ );
1792
+ if (occurrences > 0) {
1793
+ if (WARN_ON_DUPLICATE_STRING_TAGS) {
1794
+ (_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
1795
+ options,
1796
+ `Duplicate string tags for <${k}> detected; cancelling tool call`,
1797
+ {
1798
+ toolName,
1799
+ toolCall: `<${toolName}>${toolContent}</${toolName}>`
1800
+ }
1801
+ );
1802
+ }
1803
+ cancelToolCall = true;
1804
+ break;
1805
+ }
1806
+ const raw = extractRawInner(toolContent, k);
1807
+ if (typeof raw === "string") {
1808
+ args[k] = raw;
1809
+ continue;
1810
+ }
1811
+ }
1812
+ if (v && typeof v === "object" && Object.prototype.hasOwnProperty.call(v, "#text")) {
1813
+ val = v == null ? void 0 : v["#text"];
1814
+ }
1815
+ if (Array.isArray(v)) {
1816
+ if (propType === "string") {
1817
+ const mapped = v.map((item) => {
1818
+ if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
1819
+ const textVal = item == null ? void 0 : item["#text"];
1820
+ return typeof textVal === "string" ? textVal : String(textVal);
1821
+ }
1822
+ return typeof item === "string" ? item : String(item);
1823
+ });
1824
+ if (mapped.length > 1 && WARN_ON_DUPLICATE_STRING_TAGS) {
1825
+ (_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
1826
+ options,
1827
+ `Duplicate string tags for <${k}> detected; cancelling tool call`,
1828
+ {
1829
+ toolName,
1830
+ toolCall: `<${toolName}>${toolContent}</${toolName}>`
1831
+ }
1832
+ );
1833
+ }
1834
+ if (mapped.length > 1) {
1835
+ cancelToolCall = true;
1836
+ break;
1837
+ } else {
1838
+ args[k] = (_c = mapped[0]) != null ? _c : "";
1839
+ continue;
1840
+ }
1841
+ } else {
1842
+ val = v.map((item) => {
1843
+ if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
1844
+ const textVal = item == null ? void 0 : item["#text"];
1845
+ return typeof textVal === "string" ? textVal.trim() : textVal;
1846
+ }
1847
+ return typeof item === "string" ? item.trim() : item;
1848
+ });
1849
+ }
1850
+ } else if (v && typeof v === "object" && !Object.prototype.hasOwnProperty.call(v, "#text")) {
1851
+ const obj = v;
1852
+ const keys = Object.keys(obj);
1853
+ if (keys.length === 1 && keys[0] === "item") {
1854
+ const itemValue = obj.item;
1855
+ if (Array.isArray(itemValue)) {
1856
+ val = itemValue.map((item) => {
1857
+ let currentVal = item;
1858
+ if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
1859
+ currentVal = item == null ? void 0 : item["#text"];
1860
+ }
1861
+ const trimmed = typeof currentVal === "string" ? currentVal.trim() : currentVal;
1862
+ if (typeof trimmed === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed)) {
1863
+ const num = Number(trimmed);
1864
+ if (Number.isFinite(num)) return num;
1865
+ }
1866
+ return trimmed;
1867
+ });
1868
+ } else {
1869
+ const trimmed = typeof itemValue === "string" ? itemValue.trim() : itemValue;
1870
+ if (typeof trimmed === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed)) {
1871
+ const num = Number(trimmed);
1872
+ val = Number.isFinite(num) ? num : trimmed;
1873
+ } else {
1874
+ val = trimmed;
1875
+ }
1876
+ }
1877
+ } else {
1878
+ let isIndexedTuple = false;
1879
+ if (keys.length > 0 && keys.every((key) => /^\d+$/.test(key))) {
1880
+ const indices = keys.map((k2) => parseInt(k2, 10)).sort((a, b) => a - b);
1881
+ isIndexedTuple = indices[0] === 0 && indices.every((val2, idx) => val2 === idx);
1882
+ }
1883
+ if (isIndexedTuple) {
1884
+ const sortedKeys = keys.sort(
1885
+ (a, b) => parseInt(a, 10) - parseInt(b, 10)
1886
+ );
1887
+ val = sortedKeys.map((key) => {
1888
+ const item = obj[key];
1889
+ if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
1890
+ const textVal = item == null ? void 0 : item["#text"];
1891
+ return typeof textVal === "string" ? textVal.trim() : textVal;
1892
+ }
1893
+ return typeof item === "string" ? item.trim() : item;
1894
+ });
1895
+ } else {
1896
+ val = v;
1897
+ }
1898
+ }
1899
+ }
1900
+ args[k] = typeof val === "string" ? val.trim() : val;
1901
+ }
1902
+ return { args, cancelToolCall };
1903
+ }
1303
1904
  var morphXmlProtocol = () => ({
1304
1905
  formatTools({ tools, toolSystemPromptTemplate }) {
1305
1906
  const toolsForPrompt = (tools || []).map((tool) => ({
@@ -1370,91 +1971,31 @@ var morphXmlProtocol = () => ({
1370
1971
  textNodeName: "#text"
1371
1972
  });
1372
1973
  const parsedArgs = ((_a = parser.parse(`<root>${toolContent}</root>`)) == null ? void 0 : _a.root) || {};
1373
- const args = {};
1374
- for (const k of Object.keys(parsedArgs || {})) {
1375
- const v = parsedArgs[k];
1376
- let val = v;
1377
- if (v && typeof v === "object" && Object.prototype.hasOwnProperty.call(v, "#text")) {
1378
- val = v == null ? void 0 : v["#text"];
1379
- }
1380
- if (Array.isArray(v)) {
1381
- val = v.map((item) => {
1382
- if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
1383
- const textVal = item == null ? void 0 : item["#text"];
1384
- return typeof textVal === "string" ? textVal.trim() : textVal;
1385
- }
1386
- return typeof item === "string" ? item.trim() : item;
1387
- });
1388
- } else if (v && typeof v === "object" && !Object.prototype.hasOwnProperty.call(v, "#text")) {
1389
- const obj = v;
1390
- const keys = Object.keys(obj);
1391
- if (keys.length === 1 && keys[0] === "item") {
1392
- const itemValue = obj.item;
1393
- if (Array.isArray(itemValue)) {
1394
- val = itemValue.map((item) => {
1395
- if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
1396
- const textVal = item == null ? void 0 : item["#text"];
1397
- const trimmed2 = typeof textVal === "string" ? textVal.trim() : textVal;
1398
- if (typeof trimmed2 === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed2)) {
1399
- const num = Number(trimmed2);
1400
- if (Number.isFinite(num)) return num;
1401
- }
1402
- return trimmed2;
1403
- }
1404
- const trimmed = typeof item === "string" ? item.trim() : item;
1405
- if (typeof trimmed === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed)) {
1406
- const num = Number(trimmed);
1407
- if (Number.isFinite(num)) return num;
1408
- }
1409
- return trimmed;
1410
- });
1411
- } else {
1412
- const trimmed = typeof itemValue === "string" ? itemValue.trim() : itemValue;
1413
- if (typeof trimmed === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed)) {
1414
- const num = Number(trimmed);
1415
- if (Number.isFinite(num)) {
1416
- val = num;
1417
- } else {
1418
- val = trimmed;
1419
- }
1420
- } else {
1421
- val = trimmed;
1422
- }
1423
- }
1424
- } else {
1425
- const isIndexedTuple = keys.length > 0 && keys.every((key) => /^\d+$/.test(key)) && (() => {
1426
- const indices = keys.map((k2) => parseInt(k2)).sort((a, b) => a - b);
1427
- return indices[0] === 0 && indices.every((val2, idx) => val2 === idx);
1428
- })();
1429
- if (isIndexedTuple) {
1430
- const sortedKeys = keys.sort(
1431
- (a, b) => parseInt(a) - parseInt(b)
1432
- );
1433
- val = sortedKeys.map((key) => {
1434
- const item = obj[key];
1435
- if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
1436
- const textVal = item == null ? void 0 : item["#text"];
1437
- return typeof textVal === "string" ? textVal.trim() : textVal;
1438
- }
1439
- return typeof item === "string" ? item.trim() : item;
1440
- });
1441
- } else {
1442
- val = v;
1443
- }
1444
- }
1445
- }
1446
- args[k] = typeof val === "string" ? val.trim() : val;
1447
- }
1448
- const originalSchema = originalSchemas[toolName];
1449
- const fallbackSchema = (_b = tools.find((t) => t.name === toolName)) == null ? void 0 : _b.inputSchema;
1450
- const schema = originalSchema || fallbackSchema;
1451
- const coercedArgs = coerceBySchema(args, schema);
1452
- processedElements.push({
1453
- type: "tool-call",
1454
- toolCallId: generateId3(),
1974
+ const toolSchema = getToolSchema(tools, originalSchemas, toolName);
1975
+ const { args, cancelToolCall } = processParsedArgs(
1976
+ parsedArgs,
1977
+ toolSchema,
1978
+ toolContent,
1455
1979
  toolName,
1456
- input: JSON.stringify(coercedArgs)
1457
- });
1980
+ options
1981
+ );
1982
+ if (cancelToolCall) {
1983
+ const originalCallText = match[0];
1984
+ (_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
1985
+ options,
1986
+ `Duplicate string tags detected; cancelling tool call`,
1987
+ { toolCall: originalCallText, toolName }
1988
+ );
1989
+ processedElements.push({ type: "text", text: originalCallText });
1990
+ } else {
1991
+ const coercedArgs = coerceBySchema(args, toolSchema);
1992
+ processedElements.push({
1993
+ type: "tool-call",
1994
+ toolCallId: generateId3(),
1995
+ toolName,
1996
+ input: JSON.stringify(coercedArgs)
1997
+ });
1998
+ }
1458
1999
  } catch (error) {
1459
2000
  const message = `Could not process XML tool call, keeping original text: ${match[0]}`;
1460
2001
  (_c = options == null ? void 0 : options.onError) == null ? void 0 : _c.call(options, message, { toolCall: match[0], toolName, error });
@@ -1499,7 +2040,7 @@ var morphXmlProtocol = () => ({
1499
2040
  };
1500
2041
  return new TransformStream({
1501
2042
  transform(chunk, controller) {
1502
- var _a, _b;
2043
+ var _a;
1503
2044
  if (chunk.type !== "text-delta") {
1504
2045
  if (buffer) flushText(controller);
1505
2046
  controller.enqueue(chunk);
@@ -1521,94 +2062,43 @@ var morphXmlProtocol = () => ({
1521
2062
  textNodeName: "#text"
1522
2063
  });
1523
2064
  const parsedArgs = ((_a = parser.parse(`<root>${toolContent}</root>`)) == null ? void 0 : _a.root) || {};
1524
- const args = {};
1525
- for (const k of Object.keys(parsedArgs || {})) {
1526
- const v = parsedArgs[k];
1527
- let val = v;
1528
- if (v && typeof v === "object" && Object.prototype.hasOwnProperty.call(v, "#text")) {
1529
- val = v == null ? void 0 : v["#text"];
1530
- }
1531
- if (Array.isArray(v)) {
1532
- val = v.map((item) => {
1533
- if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
1534
- const textVal = item == null ? void 0 : item["#text"];
1535
- return typeof textVal === "string" ? textVal.trim() : textVal;
1536
- }
1537
- return typeof item === "string" ? item.trim() : item;
1538
- });
1539
- } else if (v && typeof v === "object" && !Object.prototype.hasOwnProperty.call(v, "#text")) {
1540
- const obj = v;
1541
- const keys = Object.keys(obj);
1542
- if (keys.length === 1 && keys[0] === "item") {
1543
- const itemValue = obj.item;
1544
- if (Array.isArray(itemValue)) {
1545
- val = itemValue.map((item) => {
1546
- if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
1547
- const textVal = item == null ? void 0 : item["#text"];
1548
- const trimmed2 = typeof textVal === "string" ? textVal.trim() : textVal;
1549
- if (typeof trimmed2 === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed2)) {
1550
- const num = Number(trimmed2);
1551
- if (Number.isFinite(num)) return num;
1552
- }
1553
- return trimmed2;
1554
- }
1555
- const trimmed = typeof item === "string" ? item.trim() : item;
1556
- if (typeof trimmed === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed)) {
1557
- const num = Number(trimmed);
1558
- if (Number.isFinite(num)) return num;
1559
- }
1560
- return trimmed;
1561
- });
1562
- } else {
1563
- const trimmed = typeof itemValue === "string" ? itemValue.trim() : itemValue;
1564
- if (typeof trimmed === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed)) {
1565
- const num = Number(trimmed);
1566
- if (Number.isFinite(num)) {
1567
- val = num;
1568
- } else {
1569
- val = trimmed;
1570
- }
1571
- } else {
1572
- val = trimmed;
1573
- }
1574
- }
1575
- } else {
1576
- const isIndexedTuple = keys.length > 0 && keys.every((key) => /^\d+$/.test(key)) && (() => {
1577
- const indices = keys.map((k2) => parseInt(k2)).sort((a, b) => a - b);
1578
- return indices[0] === 0 && indices.every((val2, idx) => val2 === idx);
1579
- })();
1580
- if (isIndexedTuple) {
1581
- const sortedKeys = keys.sort(
1582
- (a, b) => parseInt(a) - parseInt(b)
1583
- );
1584
- val = sortedKeys.map((key) => {
1585
- const item = obj[key];
1586
- if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
1587
- const textVal = item == null ? void 0 : item["#text"];
1588
- return typeof textVal === "string" ? textVal.trim() : textVal;
1589
- }
1590
- return typeof item === "string" ? item.trim() : item;
1591
- });
1592
- } else {
1593
- val = v;
2065
+ const toolSchema = getToolSchema(
2066
+ tools,
2067
+ originalSchemas,
2068
+ currentToolCall.name
2069
+ );
2070
+ const { args, cancelToolCall } = processParsedArgs(
2071
+ parsedArgs,
2072
+ toolSchema,
2073
+ toolContent,
2074
+ currentToolCall.name,
2075
+ options
2076
+ );
2077
+ if (cancelToolCall) {
2078
+ const originalCallText = `<${currentToolCall.name}>${toolContent}</${currentToolCall.name}>`;
2079
+ if (options == null ? void 0 : options.onError) {
2080
+ options.onError(
2081
+ "Duplicate string tags detected; cancelling tool call",
2082
+ {
2083
+ toolCall: originalCallText,
2084
+ toolName: currentToolCall.name
1594
2085
  }
1595
- }
2086
+ );
1596
2087
  }
1597
- args[k] = typeof val === "string" ? val.trim() : val;
2088
+ flushText(controller, originalCallText);
2089
+ } else {
2090
+ const coercedArgs = coerceBySchema(
2091
+ args,
2092
+ toolSchema
2093
+ );
2094
+ flushText(controller);
2095
+ controller.enqueue({
2096
+ type: "tool-call",
2097
+ toolCallId: generateId3(),
2098
+ toolName: currentToolCall.name,
2099
+ input: JSON.stringify(coercedArgs)
2100
+ });
1598
2101
  }
1599
- const originalSchema = originalSchemas[currentToolCall.name];
1600
- const fallbackSchema = (_b = tools.find(
1601
- (t) => t.name === currentToolCall.name
1602
- )) == null ? void 0 : _b.inputSchema;
1603
- const toolSchema = originalSchema || fallbackSchema;
1604
- const coercedArgs = coerceBySchema(args, toolSchema);
1605
- flushText(controller);
1606
- controller.enqueue({
1607
- type: "tool-call",
1608
- toolCallId: generateId3(),
1609
- toolName: currentToolCall.name,
1610
- input: JSON.stringify(coercedArgs)
1611
- });
1612
2102
  } catch (e) {
1613
2103
  const originalCallText = `<${currentToolCall.name}>${toolContent}${endTag}`;
1614
2104
  if (options == null ? void 0 : options.onError) {