@ai-sdk-tool/parser 2.1.3 → 2.1.5

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
@@ -89,9 +89,9 @@ function escapeRegExp(literal) {
89
89
  return literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
90
90
  }
91
91
 
92
- // src/utils/relaxed-json.ts
93
- var relaxed_json_exports = {};
94
- __export(relaxed_json_exports, {
92
+ // src/utils/robust-json.ts
93
+ var robust_json_exports = {};
94
+ __export(robust_json_exports, {
95
95
  parse: () => parse,
96
96
  stringify: () => stringify,
97
97
  transform: () => transform
@@ -722,210 +722,6 @@ function stringify(obj) {
722
722
  return "null";
723
723
  }
724
724
 
725
- // src/utils/coercion.ts
726
- function unwrapJsonSchema(schema) {
727
- if (!schema || typeof schema !== "object") return schema;
728
- const s = schema;
729
- if (s.jsonSchema && typeof s.jsonSchema === "object") {
730
- return unwrapJsonSchema(s.jsonSchema);
731
- }
732
- return schema;
733
- }
734
- function getSchemaType(schema) {
735
- const unwrapped = unwrapJsonSchema(schema);
736
- if (!unwrapped || typeof unwrapped !== "object") return void 0;
737
- const t = unwrapped.type;
738
- if (typeof t === "string") return t;
739
- if (Array.isArray(t)) {
740
- const preferred = [
741
- "object",
742
- "array",
743
- "boolean",
744
- "number",
745
- "integer",
746
- "string"
747
- ];
748
- for (const p of preferred) if (t.includes(p)) return p;
749
- }
750
- const s = unwrapped;
751
- if (s && typeof s === "object" && (s.properties || s.additionalProperties)) {
752
- return "object";
753
- }
754
- if (s && typeof s === "object" && (s.items || s.prefixItems)) {
755
- return "array";
756
- }
757
- return void 0;
758
- }
759
- function coerceBySchema(value, schema) {
760
- const unwrapped = unwrapJsonSchema(schema);
761
- if (!unwrapped || typeof unwrapped !== "object") {
762
- if (typeof value === "string") {
763
- const s = value.trim();
764
- const lower = s.toLowerCase();
765
- if (lower === "true") return true;
766
- if (lower === "false") return false;
767
- if (/^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(s)) {
768
- const num = Number(s);
769
- if (Number.isFinite(num)) return num;
770
- }
771
- if (s.startsWith("{") && s.endsWith("}") || s.startsWith("[") && s.endsWith("]")) {
772
- try {
773
- const parsed = JSON.parse(s);
774
- return coerceBySchema(parsed, void 0);
775
- } catch (e) {
776
- }
777
- }
778
- }
779
- return value;
780
- }
781
- const schemaType = getSchemaType(unwrapped);
782
- if (typeof value === "string") {
783
- const s = value.trim();
784
- if (schemaType === "object") {
785
- try {
786
- let normalized = s.replace(/'/g, '"');
787
- normalized = normalized.replace(/^\{\s*\}$/s, "{}");
788
- const obj = JSON.parse(normalized);
789
- if (obj && typeof obj === "object" && !Array.isArray(obj)) {
790
- const props = unwrapped.properties;
791
- const out = {};
792
- for (const [k, v] of Object.entries(obj)) {
793
- const propSchema = props ? props[k] : void 0;
794
- out[k] = typeof propSchema === "boolean" ? v : coerceBySchema(v, propSchema);
795
- }
796
- return out;
797
- }
798
- } catch (e) {
799
- }
800
- }
801
- if (schemaType === "array") {
802
- try {
803
- const normalized = s.replace(/'/g, '"');
804
- const arr = JSON.parse(normalized);
805
- if (Array.isArray(arr)) {
806
- const u = unwrapped;
807
- const prefixItems = Array.isArray(
808
- u.prefixItems
809
- ) ? u.prefixItems : void 0;
810
- const itemsSchema = u.items;
811
- if (prefixItems && arr.length === prefixItems.length) {
812
- return arr.map((v, i) => coerceBySchema(v, prefixItems[i]));
813
- }
814
- return arr.map((v) => coerceBySchema(v, itemsSchema));
815
- }
816
- } catch (e) {
817
- const csv = s.includes("\n") ? s.split(/\n+/) : s.split(/,\s*/);
818
- const trimmed = csv.map((x) => x.trim()).filter((x) => x.length > 0);
819
- const u = unwrapped;
820
- const prefixItems = Array.isArray(
821
- u.prefixItems
822
- ) ? u.prefixItems : void 0;
823
- const itemsSchema = u.items;
824
- if (prefixItems && trimmed.length === prefixItems.length) {
825
- return trimmed.map((x, i) => coerceBySchema(x, prefixItems[i]));
826
- }
827
- return trimmed.map((x) => coerceBySchema(x, itemsSchema));
828
- }
829
- }
830
- }
831
- if (schemaType === "object" && value && typeof value === "object" && !Array.isArray(value)) {
832
- const out = {};
833
- const props = unwrapped.properties;
834
- for (const [k, v] of Object.entries(value)) {
835
- const propSchema = props ? props[k] : void 0;
836
- out[k] = typeof propSchema === "boolean" ? v : coerceBySchema(v, propSchema);
837
- }
838
- return out;
839
- }
840
- if (schemaType === "array") {
841
- const u = unwrapped;
842
- const itemsSchema = u.items;
843
- const prefixItems = Array.isArray(
844
- u.prefixItems
845
- ) ? u.prefixItems : void 0;
846
- if (Array.isArray(value)) {
847
- if (prefixItems && value.length === prefixItems.length) {
848
- return value.map((v, i) => coerceBySchema(v, prefixItems[i]));
849
- }
850
- return value.map((v) => coerceBySchema(v, itemsSchema));
851
- }
852
- if (value && typeof value === "object") {
853
- const maybe = value;
854
- if (Object.prototype.hasOwnProperty.call(maybe, "item")) {
855
- const items = maybe.item;
856
- const arr = Array.isArray(items) ? items : [items];
857
- if (prefixItems && arr.length === prefixItems.length) {
858
- return arr.map((v, i) => coerceBySchema(v, prefixItems[i]));
859
- }
860
- return arr.map((v) => coerceBySchema(v, itemsSchema));
861
- }
862
- const keys = Object.keys(maybe);
863
- if (keys.length === 1) {
864
- const singleKey = keys[0];
865
- const singleValue = maybe[singleKey];
866
- if (Array.isArray(singleValue)) {
867
- const coercedArray = singleValue.map(
868
- (v) => coerceBySchema(v, itemsSchema)
869
- );
870
- return coercedArray;
871
- }
872
- }
873
- if (keys.length > 0 && keys.every((k) => /^\d+$/.test(k))) {
874
- const arr = keys.sort((a, b) => Number(a) - Number(b)).map((k) => maybe[k]);
875
- if (prefixItems && arr.length === prefixItems.length) {
876
- return arr.map((v, i) => coerceBySchema(v, prefixItems[i]));
877
- }
878
- return arr.map((v) => coerceBySchema(v, itemsSchema));
879
- }
880
- }
881
- if (value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
882
- if (prefixItems && prefixItems.length > 0) {
883
- return [coerceBySchema(value, prefixItems[0])];
884
- }
885
- return [coerceBySchema(value, itemsSchema)];
886
- }
887
- }
888
- if (typeof value === "string") {
889
- const s = value.trim();
890
- if (schemaType === "boolean") {
891
- const lower = s.toLowerCase();
892
- if (lower === "true") return true;
893
- if (lower === "false") return false;
894
- }
895
- if (schemaType === "number" || schemaType === "integer") {
896
- if (/^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(s)) {
897
- const num = Number(s);
898
- if (Number.isFinite(num)) return num;
899
- }
900
- }
901
- }
902
- return value;
903
- }
904
- function fixToolCallWithSchema(part, tools) {
905
- var _a;
906
- if (part.type !== "tool-call") return part;
907
- const tc = part;
908
- let args = {};
909
- if (typeof tc.input === "string") {
910
- try {
911
- args = JSON.parse(tc.input);
912
- } catch (e) {
913
- return part;
914
- }
915
- } else if (tc.input && typeof tc.input === "object") {
916
- args = tc.input;
917
- }
918
- const schema = (_a = tools.find((t) => t.name === tc.toolName)) == null ? void 0 : _a.inputSchema;
919
- const coerced = coerceBySchema(args, schema);
920
- return {
921
- ...part,
922
- input: JSON.stringify(coerced != null ? coerced : {})
923
- };
924
- }
925
- function coerceToolCallInput(part, tools) {
926
- return fixToolCallWithSchema(part, tools);
927
- }
928
-
929
725
  // src/utils/debug.ts
930
726
  function normalizeBooleanString(value) {
931
727
  const normalized = value.trim().toLowerCase();
@@ -1013,38 +809,34 @@ function extractOnErrorOption(providerOptions) {
1013
809
  return void 0;
1014
810
  }
1015
811
 
1016
- // src/utils/protocol.ts
1017
- function isProtocolFactory(protocol) {
1018
- return typeof protocol === "function";
812
+ // src/utils/provider-options.ts
813
+ var originalToolsSchema = {
814
+ encode: encodeOriginalTools,
815
+ decode: decodeOriginalTools
816
+ };
817
+ function encodeOriginalTools(tools) {
818
+ return (tools == null ? void 0 : tools.map((t) => ({
819
+ name: t.name,
820
+ inputSchema: JSON.stringify(t.inputSchema)
821
+ }))) || [];
822
+ }
823
+ function decodeOriginalTools(originalTools) {
824
+ const tools = (originalTools == null ? void 0 : originalTools.map(
825
+ (t) => ({
826
+ name: t.name,
827
+ inputSchema: JSON.parse(t.inputSchema)
828
+ })
829
+ )) || [];
830
+ return tools;
831
+ }
832
+ function extractToolNamesFromOriginalTools(originalTools) {
833
+ return (originalTools == null ? void 0 : originalTools.map((t) => t.name)) || [];
1019
834
  }
1020
-
1021
- // src/utils/tools.ts
1022
835
  function isToolChoiceActive(params) {
1023
836
  var _a, _b, _c;
1024
837
  const toolChoice = (_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.toolChoice;
1025
838
  return !!(typeof params.providerOptions === "object" && params.providerOptions !== null && typeof ((_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware) === "object" && toolChoice && typeof toolChoice === "object" && (toolChoice.type === "tool" || toolChoice.type === "required"));
1026
839
  }
1027
- function getFunctionTools(params) {
1028
- var _a, _b;
1029
- const functionTools = ((_a = params.tools) != null ? _a : []).filter(
1030
- (t) => t.type === "function"
1031
- );
1032
- if (functionTools.length > 0) return functionTools;
1033
- const rawToolNames = params.providerOptions && typeof params.providerOptions === "object" && ((_b = params.providerOptions.toolCallMiddleware) == null ? void 0 : _b.toolNames) || [];
1034
- const toStringArray = (val) => Array.isArray(val) ? val.filter(
1035
- (item) => typeof item === "string"
1036
- ) : [];
1037
- const toolNames = toStringArray(rawToolNames);
1038
- if (toolNames.length > 0) {
1039
- return toolNames.map((name) => ({
1040
- type: "function",
1041
- name,
1042
- description: "",
1043
- inputSchema: { type: "object" }
1044
- }));
1045
- }
1046
- return [];
1047
- }
1048
840
 
1049
841
  // src/utils/type-guards.ts
1050
842
  function isToolCallContent(content) {
@@ -1114,7 +906,7 @@ var jsonMixProtocol = ({
1114
906
  }
1115
907
  if (toolCallJson) {
1116
908
  try {
1117
- const parsedToolCall = relaxed_json_exports.parse(toolCallJson);
909
+ const parsedToolCall = robust_json_exports.parse(toolCallJson);
1118
910
  processedElements.push({
1119
911
  type: "tool-call",
1120
912
  toolCallId: generateId2(),
@@ -1237,7 +1029,7 @@ var jsonMixProtocol = ({
1237
1029
  isInsideToolCall = true;
1238
1030
  } else {
1239
1031
  try {
1240
- const parsedToolCall = relaxed_json_exports.parse(currentToolCallJson);
1032
+ const parsedToolCall = robust_json_exports.parse(currentToolCallJson);
1241
1033
  if (currentTextId && hasEmittedTextStart) {
1242
1034
  controller.enqueue({ type: "text-end", id: currentTextId });
1243
1035
  currentTextId = null;
@@ -1299,619 +1091,17 @@ var jsonMixProtocol = ({
1299
1091
 
1300
1092
  // src/protocols/morph-xml-protocol.ts
1301
1093
  import { generateId as generateId3 } from "@ai-sdk/provider-utils";
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
- }
1094
+ import * as RXML from "@ai-sdk-tool/rxml";
1904
1095
  var morphXmlProtocol = () => ({
1905
1096
  formatTools({ tools, toolSystemPromptTemplate }) {
1906
1097
  const toolsForPrompt = (tools || []).map((tool) => ({
1907
1098
  name: tool.name,
1908
1099
  description: tool.description,
1909
- parameters: unwrapJsonSchema(tool.inputSchema)
1100
+ parameters: RXML.unwrapJsonSchema(tool.inputSchema)
1910
1101
  }));
1911
1102
  return toolSystemPromptTemplate(JSON.stringify(toolsForPrompt));
1912
1103
  },
1913
1104
  formatToolCall(toolCall) {
1914
- const builder = new XMLBuilder({ format: true, suppressEmptyNode: true });
1915
1105
  let args = {};
1916
1106
  const inputValue = hasInputProperty(toolCall) ? toolCall.input : void 0;
1917
1107
  if (typeof inputValue === "string") {
@@ -1923,85 +1113,60 @@ var morphXmlProtocol = () => ({
1923
1113
  } else {
1924
1114
  args = inputValue;
1925
1115
  }
1926
- const xmlContent = builder.build({
1927
- [toolCall.toolName]: args
1116
+ return RXML.stringify(toolCall.toolName, args, {
1117
+ suppressEmptyNode: false,
1118
+ format: false
1928
1119
  });
1929
- return xmlContent;
1930
1120
  },
1931
1121
  formatToolResponse(toolResult) {
1932
- const builder = new XMLBuilder({ format: true });
1933
- const xmlContent = builder.build({
1934
- tool_response: {
1935
- tool_name: toolResult.toolName,
1936
- result: toolResult.output
1937
- }
1122
+ return RXML.stringify("tool_response", {
1123
+ tool_name: toolResult.toolName,
1124
+ result: toolResult.output
1938
1125
  });
1939
- return xmlContent;
1940
1126
  },
1941
1127
  parseGeneratedText({ text, tools, options }) {
1942
- var _a, _b, _c;
1943
- const originalSchemas = (options == null ? void 0 : options.originalToolSchemas) || {};
1128
+ var _a;
1944
1129
  const toolNames = tools.map((t) => t.name).filter((name) => name != null);
1945
1130
  if (toolNames.length === 0) {
1946
1131
  return [{ type: "text", text }];
1947
1132
  }
1948
- const toolNamesPattern = toolNames.map((n) => escapeRegExp(n)).join("|");
1949
- const toolCallRegex = new RegExp(
1950
- String.raw`<(${toolNamesPattern})>([\s\S]*?)<\/\1>`,
1951
- "g"
1952
- );
1953
1133
  const processedElements = [];
1954
1134
  let currentIndex = 0;
1955
- let match;
1956
- while ((match = toolCallRegex.exec(text)) !== null) {
1957
- const startIndex = match.index;
1958
- const toolName = match[1];
1959
- const toolContent = match[2].trim();
1960
- if (startIndex > currentIndex) {
1961
- const textSegment = text.substring(currentIndex, startIndex);
1135
+ const toolCalls = findToolCalls(text, toolNames);
1136
+ for (const toolCall of toolCalls) {
1137
+ if (toolCall.startIndex > currentIndex) {
1138
+ const textSegment = text.substring(currentIndex, toolCall.startIndex);
1962
1139
  if (textSegment.trim()) {
1963
1140
  processedElements.push({ type: "text", text: textSegment });
1964
1141
  }
1965
1142
  }
1966
1143
  try {
1967
- const parser = new XMLParser({
1968
- ignoreAttributes: false,
1969
- parseTagValue: false,
1970
- ignoreDeclaration: true,
1971
- textNodeName: "#text"
1144
+ const toolSchema = getToolSchema(tools, toolCall.toolName);
1145
+ const parsed = RXML.parse(toolCall.content, toolSchema, {
1146
+ onError: options == null ? void 0 : options.onError,
1147
+ // Disable HTML self-closing tag behavior to allow base, meta, link etc. as regular tags
1148
+ noChildNodes: []
1149
+ });
1150
+ processedElements.push({
1151
+ type: "tool-call",
1152
+ toolCallId: generateId3(),
1153
+ toolName: toolCall.toolName,
1154
+ input: JSON.stringify(parsed)
1972
1155
  });
1973
- const parsedArgs = ((_a = parser.parse(`<root>${toolContent}</root>`)) == null ? void 0 : _a.root) || {};
1974
- const toolSchema = getToolSchema(tools, originalSchemas, toolName);
1975
- const { args, cancelToolCall } = processParsedArgs(
1976
- parsedArgs,
1977
- toolSchema,
1978
- toolContent,
1979
- toolName,
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
- }
1999
1156
  } catch (error) {
2000
- const message = `Could not process XML tool call, keeping original text: ${match[0]}`;
2001
- (_c = options == null ? void 0 : options.onError) == null ? void 0 : _c.call(options, message, { toolCall: match[0], toolName, error });
2002
- processedElements.push({ type: "text", text: match[0] });
1157
+ const originalCallText = text.substring(
1158
+ toolCall.startIndex,
1159
+ toolCall.endIndex
1160
+ );
1161
+ const message = `Could not process XML tool call, keeping original text: ${originalCallText}`;
1162
+ (_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, message, {
1163
+ toolCall: originalCallText,
1164
+ toolName: toolCall.toolName,
1165
+ error
1166
+ });
1167
+ processedElements.push({ type: "text", text: originalCallText });
2003
1168
  }
2004
- currentIndex = startIndex + match[0].length;
1169
+ currentIndex = toolCall.endIndex;
2005
1170
  }
2006
1171
  if (currentIndex < text.length) {
2007
1172
  const remainingText = text.substring(currentIndex);
@@ -2012,8 +1177,8 @@ var morphXmlProtocol = () => ({
2012
1177
  return processedElements;
2013
1178
  },
2014
1179
  createStreamParser({ tools, options }) {
2015
- const originalSchemas = (options == null ? void 0 : options.originalToolSchemas) || {};
2016
1180
  const toolNames = tools.map((t) => t.name).filter((name) => name != null);
1181
+ const maxStartTagLen = toolNames.length ? Math.max(...toolNames.map((n) => `<${n}>`.length)) : 0;
2017
1182
  let buffer = "";
2018
1183
  let currentToolCall = null;
2019
1184
  let currentTextId = null;
@@ -2055,61 +1220,34 @@ var morphXmlProtocol = () => ({
2055
1220
  const toolContent = buffer.substring(0, endTagIndex);
2056
1221
  buffer = buffer.substring(endTagIndex + endTag.length);
2057
1222
  try {
2058
- const parser = new XMLParser({
2059
- ignoreAttributes: false,
2060
- parseTagValue: false,
2061
- ignoreDeclaration: true,
2062
- textNodeName: "#text"
1223
+ const toolSchema = getToolSchema(tools, currentToolCall.name);
1224
+ const parsed = RXML.parse(toolContent, toolSchema, {
1225
+ onError: options == null ? void 0 : options.onError,
1226
+ // Disable HTML self-closing tag behavior to allow base, meta, link etc. as regular tags
1227
+ noChildNodes: []
2063
1228
  });
2064
- const parsedArgs = ((_a = parser.parse(`<root>${toolContent}</root>`)) == null ? void 0 : _a.root) || {};
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
2085
- }
2086
- );
2087
- }
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
- });
2101
- }
2102
- } catch (e) {
1229
+ flushText(controller);
1230
+ controller.enqueue({
1231
+ type: "tool-call",
1232
+ toolCallId: generateId3(),
1233
+ toolName: currentToolCall.name,
1234
+ input: JSON.stringify(parsed)
1235
+ });
1236
+ } catch (error) {
2103
1237
  const originalCallText = `<${currentToolCall.name}>${toolContent}${endTag}`;
2104
- if (options == null ? void 0 : options.onError) {
2105
- options.onError(
2106
- "Could not process streaming XML tool call; emitting original text.",
2107
- {
2108
- toolCall: originalCallText,
2109
- toolName: currentToolCall.name
2110
- }
2111
- );
1238
+ let message = "Could not process streaming XML tool call; emitting original text.";
1239
+ if (error instanceof RXML.RXMLDuplicateStringTagError) {
1240
+ message = `Duplicate string tags detected in streaming tool call '${currentToolCall.name}'; emitting original text.`;
1241
+ } else if (error instanceof RXML.RXMLCoercionError) {
1242
+ message = `Failed to coerce arguments for streaming tool call '${currentToolCall.name}'; emitting original text.`;
1243
+ } else if (error instanceof RXML.RXMLParseError) {
1244
+ message = `Failed to parse XML for streaming tool call '${currentToolCall.name}'; emitting original text.`;
2112
1245
  }
1246
+ (_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, message, {
1247
+ toolCall: originalCallText,
1248
+ toolName: currentToolCall.name,
1249
+ error
1250
+ });
2113
1251
  flushText(controller, originalCallText);
2114
1252
  }
2115
1253
  currentToolCall = null;
@@ -2138,6 +1276,14 @@ var morphXmlProtocol = () => ({
2138
1276
  );
2139
1277
  currentToolCall = { name: earliestToolName, content: "" };
2140
1278
  } else {
1279
+ const tail = Math.max(0, maxStartTagLen - 1);
1280
+ const safeLen = Math.max(0, buffer.length - tail);
1281
+ if (safeLen > 0) {
1282
+ const textToFlush = buffer.slice(0, safeLen);
1283
+ flushText(controller, textToFlush);
1284
+ buffer = buffer.slice(safeLen);
1285
+ continue;
1286
+ }
2141
1287
  break;
2142
1288
  }
2143
1289
  }
@@ -2159,26 +1305,66 @@ var morphXmlProtocol = () => ({
2159
1305
  extractToolCallSegments({ text, tools }) {
2160
1306
  const toolNames = tools.map((t) => t.name).filter(Boolean);
2161
1307
  if (toolNames.length === 0) return [];
2162
- const names = toolNames.map((n) => escapeRegExp(String(n))).join("|");
2163
- if (!names) return [];
2164
- const regex = new RegExp(`<(${names})>[\\s\\S]*?<\\/\\1>`, "g");
2165
- const segments = [];
2166
- let m;
2167
- while ((m = regex.exec(text)) != null) {
2168
- segments.push(m[0]);
2169
- }
2170
- return segments;
1308
+ return findToolCalls(text, toolNames).map((tc) => tc.segment);
2171
1309
  }
2172
1310
  });
1311
+ function getToolSchema(tools, toolName) {
1312
+ var _a;
1313
+ return (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
1314
+ }
1315
+ function findToolCalls(text, toolNames) {
1316
+ var _a;
1317
+ const toolCalls = [];
1318
+ for (const toolName of toolNames) {
1319
+ let searchIndex = 0;
1320
+ while (searchIndex < text.length) {
1321
+ const startTag = `<${toolName}>`;
1322
+ const tagStart = text.indexOf(startTag, searchIndex);
1323
+ if (tagStart === -1) break;
1324
+ const remainingText = text.substring(tagStart);
1325
+ const range = RXML.findFirstTopLevelRange(remainingText, toolName);
1326
+ if (range) {
1327
+ const contentStart = tagStart + startTag.length;
1328
+ const contentEnd = contentStart + (range.end - range.start);
1329
+ let fullTagEnd = contentEnd + `</${toolName}>`.length;
1330
+ const closeHead = text.indexOf(`</${toolName}`, contentEnd);
1331
+ if (closeHead === contentEnd) {
1332
+ let p = closeHead + 2 + toolName.length;
1333
+ while (p < text.length && /\s/.test(text[p])) p++;
1334
+ if (text[p] === ">") fullTagEnd = p + 1;
1335
+ }
1336
+ const segment = text.substring(tagStart, fullTagEnd);
1337
+ const content = (_a = RXML.extractRawInner(segment, toolName)) != null ? _a : text.substring(contentStart, contentEnd);
1338
+ toolCalls.push({
1339
+ toolName,
1340
+ startIndex: tagStart,
1341
+ endIndex: fullTagEnd,
1342
+ content,
1343
+ segment
1344
+ });
1345
+ searchIndex = fullTagEnd;
1346
+ } else {
1347
+ searchIndex = tagStart + startTag.length;
1348
+ }
1349
+ }
1350
+ }
1351
+ return toolCalls.sort((a, b) => a.startIndex - b.startIndex);
1352
+ }
1353
+
1354
+ // src/protocols/tool-call-protocol.ts
1355
+ function isProtocolFactory(protocol) {
1356
+ return typeof protocol === "function";
1357
+ }
2173
1358
 
2174
1359
  // src/generate-handler.ts
2175
1360
  import { generateId as generateId4 } from "@ai-sdk/provider-utils";
1361
+ import * as RXML2 from "@ai-sdk-tool/rxml";
2176
1362
  async function wrapGenerate({
2177
1363
  protocol,
2178
1364
  doGenerate,
2179
1365
  params
2180
1366
  }) {
2181
- var _a, _b;
1367
+ var _a, _b, _c, _d;
2182
1368
  if (isToolChoiceActive(params)) {
2183
1369
  const result2 = await doGenerate();
2184
1370
  let parsed2 = {};
@@ -2219,6 +1405,9 @@ async function wrapGenerate({
2219
1405
  content: [toolCall]
2220
1406
  };
2221
1407
  }
1408
+ const tools = originalToolsSchema.decode(
1409
+ (_d = (_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware) == null ? void 0 : _d.originalTools
1410
+ );
2222
1411
  const result = await doGenerate();
2223
1412
  if (result.content.length === 0) {
2224
1413
  return result;
@@ -2234,16 +1423,15 @@ async function wrapGenerate({
2234
1423
  }
2235
1424
  return protocol.parseGeneratedText({
2236
1425
  text: contentItem.text,
2237
- tools: getFunctionTools(params),
1426
+ tools,
2238
1427
  options: {
2239
1428
  ...extractOnErrorOption(params.providerOptions),
2240
1429
  ...(_a2 = params.providerOptions) == null ? void 0 : _a2.toolCallMiddleware
2241
1430
  }
2242
1431
  });
2243
1432
  });
2244
- const tools = getFunctionTools(params);
2245
1433
  const newContent = parsed.map(
2246
- (part) => coerceToolCallInput(part, tools)
1434
+ (part) => fixToolCallWithSchema(part, tools)
2247
1435
  );
2248
1436
  const debugLevel = getDebugLevel();
2249
1437
  if (debugLevel === "stream") {
@@ -2265,6 +1453,27 @@ async function wrapGenerate({
2265
1453
  content: newContent
2266
1454
  };
2267
1455
  }
1456
+ function fixToolCallWithSchema(part, tools) {
1457
+ var _a;
1458
+ if (part.type !== "tool-call") return part;
1459
+ const tc = part;
1460
+ let args = {};
1461
+ if (typeof tc.input === "string") {
1462
+ try {
1463
+ args = JSON.parse(tc.input);
1464
+ } catch (e) {
1465
+ return part;
1466
+ }
1467
+ } else if (tc.input && typeof tc.input === "object") {
1468
+ args = tc.input;
1469
+ }
1470
+ const schema = (_a = tools.find((t) => t.name === tc.toolName)) == null ? void 0 : _a.inputSchema;
1471
+ const coerced = RXML2.coerceBySchema(args, schema);
1472
+ return {
1473
+ ...part,
1474
+ input: JSON.stringify(coerced != null ? coerced : {})
1475
+ };
1476
+ }
2268
1477
 
2269
1478
  // src/stream-handler.ts
2270
1479
  import { generateId as generateId5 } from "@ai-sdk/provider-utils";
@@ -2274,7 +1483,7 @@ async function wrapStream({
2274
1483
  doGenerate,
2275
1484
  params
2276
1485
  }) {
2277
- var _a;
1486
+ var _a, _b, _c;
2278
1487
  if (isToolChoiceActive(params)) {
2279
1488
  return toolChoiceStream({
2280
1489
  doGenerate,
@@ -2283,10 +1492,12 @@ async function wrapStream({
2283
1492
  }
2284
1493
  const { stream, ...rest } = await doStream();
2285
1494
  const debugLevel = getDebugLevel();
2286
- const tools = getFunctionTools(params);
1495
+ const tools = originalToolsSchema.decode(
1496
+ (_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.originalTools
1497
+ );
2287
1498
  const options = {
2288
1499
  ...extractOnErrorOption(params.providerOptions),
2289
- ...(_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware
1500
+ ...(_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware
2290
1501
  };
2291
1502
  if (debugLevel === "off") {
2292
1503
  return {
@@ -2495,10 +1706,10 @@ async function transformParams({
2495
1706
  ...params.providerOptions || {},
2496
1707
  toolCallMiddleware: {
2497
1708
  ...params.providerOptions && typeof params.providerOptions === "object" && params.providerOptions.toolCallMiddleware || {},
2498
- // INTERNAL: used by the middleware to propagate the names of custom
2499
- // function tools into downstream handlers (stream/generate) when
2500
- // providers strip or ignore `params.tools`. Not a stable public API.
2501
- toolNames: functionTools.map((t) => t.name)
1709
+ // INTERNAL: used by the middleware so downstream parsers can access
1710
+ // the original tool schemas even if providers strip `params.tools`.
1711
+ // Not a stable public API.
1712
+ originalTools: originalToolsSchema.encode(functionTools)
2502
1713
  }
2503
1714
  }
2504
1715
  };
@@ -2779,17 +1990,34 @@ When an argument is an array, write each item inside a single element on one lin
2779
1990
  Examples:
2780
1991
  <get_weather>
2781
1992
  <location>
2782
- San Fransisco
1993
+ San Francisco
2783
1994
  </location>
2784
1995
  </get_weather>`;
2785
1996
  }
2786
1997
  });
2787
1998
  export {
1999
+ robust_json_exports as RJSON,
2000
+ createDynamicIfThenElseSchema,
2788
2001
  createToolMiddleware,
2002
+ decodeOriginalTools,
2003
+ encodeOriginalTools,
2004
+ escapeRegExp,
2005
+ extractOnErrorOption,
2006
+ extractToolNamesFromOriginalTools,
2789
2007
  gemmaToolMiddleware,
2008
+ getDebugLevel,
2009
+ getPotentialStartIndex,
2010
+ hasInputProperty,
2790
2011
  hermesToolMiddleware,
2012
+ isToolCallContent,
2013
+ isToolChoiceActive,
2014
+ isToolResultPart,
2791
2015
  jsonMixProtocol,
2016
+ logParsedChunk,
2017
+ logParsedSummary,
2018
+ logRawChunk,
2792
2019
  morphXmlProtocol,
2020
+ originalToolsSchema,
2793
2021
  xmlToolMiddleware
2794
2022
  };
2795
2023
  //# sourceMappingURL=index.js.map