@ai-sdk-tool/parser 3.0.0-canary.1 → 3.0.0-canary.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.
@@ -1141,27 +1141,226 @@ var jsonMixProtocol = ({
1141
1141
 
1142
1142
  // src/protocols/morph-xml-protocol.ts
1143
1143
  var import_provider_utils2 = require("@ai-sdk/provider-utils");
1144
- var import_rxml = require("@ai-sdk-tool/rxml");
1144
+ var import_rxml2 = require("@ai-sdk-tool/rxml");
1145
1145
 
1146
- // src/utils/type-guards.ts
1147
- function isToolCallContent(content) {
1148
- return content.type === "tool-call" && typeof content.toolName === "string" && // input may be a JSON string or an already-parsed object depending on provider/runtime
1149
- (typeof content.input === "string" || typeof content.input === "object");
1146
+ // src/heuristics/engine.ts
1147
+ function applyRawSegmentUpdate(current, result) {
1148
+ if (result.rawSegment !== void 0) {
1149
+ return { ...current, rawSegment: result.rawSegment };
1150
+ }
1151
+ return current;
1150
1152
  }
1151
- function hasInputProperty(obj) {
1152
- return typeof obj === "object" && obj !== null && "input" in obj;
1153
+ function applyParsedUpdate(current, result) {
1154
+ if (result.parsed !== void 0) {
1155
+ return { ...current, parsed: result.parsed };
1156
+ }
1157
+ return current;
1158
+ }
1159
+ function applyWarningsUpdate(current, result) {
1160
+ var _a, _b;
1161
+ if (result.warnings && result.warnings.length > 0) {
1162
+ const meta = (_a = current.meta) != null ? _a : {};
1163
+ const existingWarnings = (_b = meta.warnings) != null ? _b : [];
1164
+ return {
1165
+ ...current,
1166
+ meta: { ...meta, warnings: [...existingWarnings, ...result.warnings] }
1167
+ };
1168
+ }
1169
+ return current;
1170
+ }
1171
+ function attemptReparse(current, result, reparseCount, maxReparses, parse4) {
1172
+ if (!result.reparse || result.rawSegment === void 0 || reparseCount >= maxReparses) {
1173
+ return { state: current, newCount: reparseCount };
1174
+ }
1175
+ try {
1176
+ const reparsed = parse4(result.rawSegment, current.schema);
1177
+ return {
1178
+ state: { ...current, parsed: reparsed, errors: [] },
1179
+ newCount: reparseCount + 1
1180
+ };
1181
+ } catch (error) {
1182
+ return {
1183
+ state: { ...current, errors: [...current.errors, error] },
1184
+ newCount: reparseCount + 1
1185
+ };
1186
+ }
1187
+ }
1188
+ function executePhase(ctx, heuristics, options) {
1189
+ var _a;
1190
+ let current = ctx;
1191
+ let reparseCount = 0;
1192
+ const maxReparses = (_a = options.maxReparses) != null ? _a : 2;
1193
+ for (const heuristic of heuristics) {
1194
+ if (!heuristic.applies(current)) {
1195
+ continue;
1196
+ }
1197
+ const result = heuristic.run(current);
1198
+ current = applyRawSegmentUpdate(current, result);
1199
+ current = applyParsedUpdate(current, result);
1200
+ current = applyWarningsUpdate(current, result);
1201
+ const reparseResult = attemptReparse(
1202
+ current,
1203
+ result,
1204
+ reparseCount,
1205
+ maxReparses,
1206
+ options.parse
1207
+ );
1208
+ current = reparseResult.state;
1209
+ reparseCount = reparseResult.newCount;
1210
+ if (result.stop) {
1211
+ break;
1212
+ }
1213
+ }
1214
+ return current;
1215
+ }
1216
+ function applyHeuristicPipeline(ctx, config, options) {
1217
+ let current = ctx;
1218
+ if (config.preParse && config.preParse.length > 0) {
1219
+ current = executePhase(current, config.preParse, options);
1220
+ }
1221
+ if (current.parsed === null && current.errors.length === 0) {
1222
+ try {
1223
+ const parsed = options.parse(current.rawSegment, current.schema);
1224
+ current = { ...current, parsed, errors: [] };
1225
+ } catch (error) {
1226
+ current = { ...current, errors: [error] };
1227
+ }
1228
+ }
1229
+ if (current.errors.length > 0 && config.fallbackReparse && config.fallbackReparse.length > 0) {
1230
+ current = executePhase(current, config.fallbackReparse, options);
1231
+ }
1232
+ if (current.parsed !== null && config.postParse && config.postParse.length > 0) {
1233
+ current = executePhase(current, config.postParse, options);
1234
+ }
1235
+ return current;
1236
+ }
1237
+ function createIntermediateCall(toolName, rawSegment, schema) {
1238
+ return {
1239
+ toolName,
1240
+ schema,
1241
+ rawSegment,
1242
+ parsed: null,
1243
+ errors: [],
1244
+ meta: { originalContent: rawSegment }
1245
+ };
1246
+ }
1247
+ function mergePipelineConfigs(...configs) {
1248
+ var _a, _b, _c;
1249
+ const result = {
1250
+ preParse: [],
1251
+ fallbackReparse: [],
1252
+ postParse: []
1253
+ };
1254
+ for (const config of configs) {
1255
+ if (config.preParse) {
1256
+ result.preParse = [...(_a = result.preParse) != null ? _a : [], ...config.preParse];
1257
+ }
1258
+ if (config.fallbackReparse) {
1259
+ result.fallbackReparse = [
1260
+ ...(_b = result.fallbackReparse) != null ? _b : [],
1261
+ ...config.fallbackReparse
1262
+ ];
1263
+ }
1264
+ if (config.postParse) {
1265
+ result.postParse = [...(_c = result.postParse) != null ? _c : [], ...config.postParse];
1266
+ }
1267
+ }
1268
+ return result;
1153
1269
  }
1154
1270
 
1155
- // src/protocols/morph-xml-protocol.ts
1156
- var WHITESPACE_REGEX2 = /\s/;
1157
- var MALFORMED_CLOSE_RE = /<\/\s+([A-Za-z0-9_:-]+)\s*>/;
1271
+ // src/heuristics/xml-defaults.ts
1272
+ var import_rxml = require("@ai-sdk-tool/rxml");
1158
1273
  var MALFORMED_CLOSE_RE_G = /<\/\s+([A-Za-z0-9_:-]+)\s*>/g;
1159
- var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
1274
+ var MALFORMED_CLOSE_RE = /<\/\s+([A-Za-z0-9_:-]+)\s*>/;
1160
1275
  var STATUS_TO_STEP_BOUNDARY_RE = /<\/status>\s*<step>/g;
1276
+ var WHITESPACE_REGEX2 = /\s/;
1277
+ var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
1278
+ var NAME_START_CHAR_RE = /[A-Za-z_:]/;
1161
1279
  var STEP_TAG_RE = /<step>([\s\S]*?)<\/step>/i;
1162
1280
  var STATUS_TAG_RE = /<status>([\s\S]*?)<\/status>/i;
1163
- function normalizeCloseTags(xml) {
1164
- return xml.replace(MALFORMED_CLOSE_RE_G, "</$1>");
1281
+ var normalizeCloseTagsHeuristic = {
1282
+ id: "normalize-close-tags",
1283
+ phase: "pre-parse",
1284
+ applies: () => true,
1285
+ run: (ctx) => {
1286
+ const normalized = ctx.rawSegment.replace(MALFORMED_CLOSE_RE_G, "</$1>");
1287
+ if (normalized !== ctx.rawSegment) {
1288
+ return { rawSegment: normalized };
1289
+ }
1290
+ return {};
1291
+ }
1292
+ };
1293
+ var escapeInvalidLtHeuristic = {
1294
+ id: "escape-invalid-lt",
1295
+ phase: "pre-parse",
1296
+ applies: () => true,
1297
+ run: (ctx) => {
1298
+ const escaped = escapeInvalidLt(ctx.rawSegment);
1299
+ if (escaped !== ctx.rawSegment) {
1300
+ return { rawSegment: escaped };
1301
+ }
1302
+ return {};
1303
+ }
1304
+ };
1305
+ var balanceTagsHeuristic = {
1306
+ id: "balance-tags",
1307
+ phase: "fallback-reparse",
1308
+ applies: (ctx) => {
1309
+ var _a;
1310
+ const original = ((_a = ctx.meta) == null ? void 0 : _a.originalContent) || ctx.rawSegment;
1311
+ const normalized = original.replace(MALFORMED_CLOSE_RE_G, "</$1>");
1312
+ const balanced = balanceTags(original);
1313
+ const hasMalformedClose = MALFORMED_CLOSE_RE.test(original);
1314
+ if (!hasMalformedClose && balanced.length > normalized.length) {
1315
+ return false;
1316
+ }
1317
+ return balanced !== normalized;
1318
+ },
1319
+ run: (ctx) => {
1320
+ var _a;
1321
+ const original = ((_a = ctx.meta) == null ? void 0 : _a.originalContent) || ctx.rawSegment;
1322
+ const balanced = balanceTags(original);
1323
+ const escaped = escapeInvalidLt(balanced);
1324
+ return { rawSegment: escaped, reparse: true };
1325
+ }
1326
+ };
1327
+ var dedupeShellStringTagsHeuristic = {
1328
+ id: "dedupe-shell-string-tags",
1329
+ phase: "fallback-reparse",
1330
+ applies: (ctx) => shouldDeduplicateStringTags(ctx.schema),
1331
+ run: (ctx) => {
1332
+ const names = getStringPropertyNames(ctx.schema);
1333
+ let deduped = ctx.rawSegment;
1334
+ for (const key of names) {
1335
+ deduped = dedupeSingleTag(deduped, key);
1336
+ }
1337
+ if (deduped !== ctx.rawSegment) {
1338
+ return { rawSegment: deduped, reparse: true };
1339
+ }
1340
+ return {};
1341
+ }
1342
+ };
1343
+ var repairAgainstSchemaHeuristic = {
1344
+ id: "repair-against-schema",
1345
+ phase: "post-parse",
1346
+ applies: (ctx) => ctx.parsed !== null && typeof ctx.parsed === "object",
1347
+ run: (ctx) => {
1348
+ const repaired = repairParsedAgainstSchema(ctx.parsed, ctx.schema);
1349
+ if (repaired !== ctx.parsed) {
1350
+ return { parsed: repaired };
1351
+ }
1352
+ return {};
1353
+ }
1354
+ };
1355
+ var defaultPipelineConfig = {
1356
+ preParse: [normalizeCloseTagsHeuristic, escapeInvalidLtHeuristic],
1357
+ fallbackReparse: [balanceTagsHeuristic, dedupeShellStringTagsHeuristic],
1358
+ postParse: [repairAgainstSchemaHeuristic]
1359
+ };
1360
+ var INDEX_TAG_RE = /^<(\d+)(?:>|\/?>)/;
1361
+ function isIndexTagAt(xml, pos) {
1362
+ const remaining = xml.slice(pos);
1363
+ return INDEX_TAG_RE.test(remaining);
1165
1364
  }
1166
1365
  function escapeInvalidLt(xml) {
1167
1366
  const len = xml.length;
@@ -1170,7 +1369,9 @@ function escapeInvalidLt(xml) {
1170
1369
  const ch = xml[i];
1171
1370
  if (ch === "<") {
1172
1371
  const next = i + 1 < len ? xml[i + 1] : "";
1173
- if (!(NAME_CHAR_RE.test(next) || next === "/" || next === "!" || next === "?")) {
1372
+ const isValidStart = NAME_START_CHAR_RE.test(next) || next === "/" || next === "!" || next === "?";
1373
+ const isIndexTag = !isValidStart && isIndexTagAt(xml, i);
1374
+ if (!(isValidStart || isIndexTag)) {
1174
1375
  out += "&lt;";
1175
1376
  continue;
1176
1377
  }
@@ -1179,60 +1380,8 @@ function escapeInvalidLt(xml) {
1179
1380
  }
1180
1381
  return out;
1181
1382
  }
1182
- function shouldDeduplicateStringTags(schema) {
1183
- const unwrapped = (0, import_rxml.unwrapJsonSchema)(schema);
1184
- if (!unwrapped || typeof unwrapped !== "object") {
1185
- return false;
1186
- }
1187
- const props = unwrapped.properties;
1188
- if (!props) {
1189
- return false;
1190
- }
1191
- const commandRaw = props.command;
1192
- if (!commandRaw) {
1193
- return false;
1194
- }
1195
- const command = (0, import_rxml.unwrapJsonSchema)(commandRaw);
1196
- return (command == null ? void 0 : command.type) === "array";
1197
- }
1198
- function tryParseSecondaryXml(content, toolSchema, options) {
1199
- const normalized = normalizeCloseTags(content);
1200
- const balanced = balanceTags(content);
1201
- const hasMalformedClose = MALFORMED_CLOSE_RE.test(content);
1202
- if (!hasMalformedClose && balanced.length > normalized.length) {
1203
- return null;
1204
- }
1205
- try {
1206
- let parsed = (0, import_rxml.parse)(balanced, toolSchema, {
1207
- onError: options == null ? void 0 : options.onError,
1208
- noChildNodes: []
1209
- });
1210
- parsed = repairParsedAgainstSchema(parsed, toolSchema, options);
1211
- return parsed;
1212
- } catch (_e) {
1213
- if (shouldDeduplicateStringTags(toolSchema)) {
1214
- const deduped = dedupeStringTagsAgainstSchema(balanced, toolSchema);
1215
- if (deduped !== balanced) {
1216
- try {
1217
- let reparsed = (0, import_rxml.parse)(deduped, toolSchema, {
1218
- onError: options == null ? void 0 : options.onError,
1219
- noChildNodes: []
1220
- });
1221
- reparsed = repairParsedAgainstSchema(reparsed, toolSchema, options);
1222
- return reparsed;
1223
- } catch (_) {
1224
- return null;
1225
- }
1226
- }
1227
- }
1228
- return null;
1229
- }
1230
- }
1231
1383
  function balanceTags(xml) {
1232
- const src = normalizeCloseTags(xml).replace(
1233
- STATUS_TO_STEP_BOUNDARY_RE,
1234
- "</status></step><step>"
1235
- );
1384
+ const src = xml.replace(MALFORMED_CLOSE_RE_G, "</$1>").replace(STATUS_TO_STEP_BOUNDARY_RE, "</status></step><step>");
1236
1385
  let i = 0;
1237
1386
  const len = src.length;
1238
1387
  const out = [];
@@ -1328,7 +1477,69 @@ function handleOpeningTagSegment(src, lt, out, stack) {
1328
1477
  }
1329
1478
  return q + 1;
1330
1479
  }
1331
- function repairParsedAgainstSchema(input, schema, options) {
1480
+ function shouldDeduplicateStringTags(schema) {
1481
+ const unwrapped = (0, import_rxml.unwrapJsonSchema)(schema);
1482
+ if (!unwrapped || typeof unwrapped !== "object") {
1483
+ return false;
1484
+ }
1485
+ const props = unwrapped.properties;
1486
+ if (!props) {
1487
+ return false;
1488
+ }
1489
+ const commandRaw = props.command;
1490
+ if (!commandRaw) {
1491
+ return false;
1492
+ }
1493
+ const command = (0, import_rxml.unwrapJsonSchema)(commandRaw);
1494
+ return (command == null ? void 0 : command.type) === "array";
1495
+ }
1496
+ function getStringPropertyNames(schema) {
1497
+ const unwrapped = (0, import_rxml.unwrapJsonSchema)(schema);
1498
+ if (!unwrapped || typeof unwrapped !== "object") {
1499
+ return [];
1500
+ }
1501
+ const props = unwrapped.properties;
1502
+ if (!props) {
1503
+ return [];
1504
+ }
1505
+ const names = [];
1506
+ for (const key of Object.keys(props)) {
1507
+ const prop = (0, import_rxml.unwrapJsonSchema)(
1508
+ props[key]
1509
+ );
1510
+ const type = prop.type;
1511
+ if (type === "string") {
1512
+ names.push(key);
1513
+ }
1514
+ }
1515
+ return names;
1516
+ }
1517
+ function escapeRegExp2(s) {
1518
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1519
+ }
1520
+ function dedupeSingleTag(xml, key) {
1521
+ var _a, _b;
1522
+ const escaped = escapeRegExp2(key);
1523
+ const re = new RegExp(`<${escaped}>([\\s\\S]*?)<\\/${escaped}>`, "g");
1524
+ const matches = Array.from(xml.matchAll(re));
1525
+ if (matches.length <= 1) {
1526
+ return xml;
1527
+ }
1528
+ const last = matches.at(-1);
1529
+ let result = "";
1530
+ let cursor = 0;
1531
+ for (const m of matches) {
1532
+ const idx = (_a = m.index) != null ? _a : 0;
1533
+ result += xml.slice(cursor, idx);
1534
+ if (last && idx === ((_b = last.index) != null ? _b : -1)) {
1535
+ result += m[0];
1536
+ }
1537
+ cursor = idx + m[0].length;
1538
+ }
1539
+ result += xml.slice(cursor);
1540
+ return result;
1541
+ }
1542
+ function repairParsedAgainstSchema(input, schema) {
1332
1543
  if (!input || typeof input !== "object") {
1333
1544
  return input;
1334
1545
  }
@@ -1340,10 +1551,10 @@ function repairParsedAgainstSchema(input, schema, options) {
1340
1551
  if (!properties) {
1341
1552
  return input;
1342
1553
  }
1343
- applySchemaProps(input, properties, options);
1554
+ applySchemaProps(input, properties);
1344
1555
  return input;
1345
1556
  }
1346
- function applySchemaProps(obj, properties, options) {
1557
+ function applySchemaProps(obj, properties) {
1347
1558
  for (const key of Object.keys(obj)) {
1348
1559
  const propSchema = properties[key];
1349
1560
  if (!propSchema) {
@@ -1354,121 +1565,122 @@ function applySchemaProps(obj, properties, options) {
1354
1565
  if (propType === "array" && prop.items) {
1355
1566
  const itemSchemaRaw = prop.items;
1356
1567
  const itemSchema = (0, import_rxml.unwrapJsonSchema)(itemSchemaRaw);
1357
- obj[key] = coerceArrayItems(obj[key], itemSchema, options);
1568
+ obj[key] = coerceArrayItems(obj[key], itemSchema);
1358
1569
  continue;
1359
1570
  }
1360
1571
  if (propType === "object") {
1361
1572
  const val = obj[key];
1362
1573
  if (val && typeof val === "object") {
1363
- obj[key] = repairParsedAgainstSchema(
1364
- val,
1365
- prop,
1366
- options
1367
- );
1574
+ obj[key] = repairParsedAgainstSchema(val, prop);
1368
1575
  }
1369
1576
  }
1370
1577
  }
1371
1578
  }
1372
- function coerceArrayItems(val, itemSchema, options) {
1579
+ function coerceArrayItems(val, itemSchema) {
1373
1580
  if (!Array.isArray(val)) {
1374
1581
  return val;
1375
1582
  }
1376
- return val.map((v) => coerceArrayItem(v, itemSchema, options));
1583
+ return val.map((v) => coerceArrayItem(v, itemSchema));
1377
1584
  }
1378
- function coerceArrayItem(v, itemSchema, options) {
1585
+ function coerceArrayItem(v, itemSchema) {
1379
1586
  const itemType = itemSchema == null ? void 0 : itemSchema.type;
1380
1587
  if (typeof v === "string" && itemType === "object") {
1381
- const parsed = tryParseStringToSchemaObject(v, itemSchema, options);
1588
+ const parsed = tryParseStringToSchemaObject(v, itemSchema);
1382
1589
  if (parsed !== null) {
1383
1590
  return parsed;
1384
1591
  }
1385
- const fallback = extractStepStatusFromString(normalizeCloseTags(v));
1592
+ const fallback = extractStepStatusFromString(
1593
+ v.replace(MALFORMED_CLOSE_RE_G, "</$1>")
1594
+ );
1386
1595
  if (fallback) {
1387
1596
  return fallback;
1388
1597
  }
1389
1598
  return v;
1390
1599
  }
1391
1600
  if (v && typeof v === "object" && itemType === "object") {
1392
- return repairParsedAgainstSchema(
1393
- v,
1394
- itemSchema,
1395
- options
1396
- );
1601
+ return repairParsedAgainstSchema(v, itemSchema);
1397
1602
  }
1398
1603
  return v;
1399
1604
  }
1400
- function getStringPropertyNames(schema) {
1401
- const unwrapped = (0, import_rxml.unwrapJsonSchema)(schema);
1402
- if (!unwrapped || typeof unwrapped !== "object") {
1403
- return [];
1404
- }
1405
- const props = unwrapped.properties;
1406
- if (!props) {
1407
- return [];
1605
+ function tryParseStringToSchemaObject(xml, itemSchema) {
1606
+ try {
1607
+ const normalized = xml.replace(MALFORMED_CLOSE_RE_G, "</$1>");
1608
+ const fixed = (0, import_rxml.parse)(normalized, itemSchema, { noChildNodes: [] });
1609
+ return typeof fixed === "string" ? null : fixed;
1610
+ } catch (e) {
1611
+ return null;
1408
1612
  }
1409
- const names = [];
1410
- for (const key of Object.keys(props)) {
1411
- const prop = (0, import_rxml.unwrapJsonSchema)(
1412
- props[key]
1413
- );
1414
- const type = prop.type;
1415
- if (type === "string") {
1416
- names.push(key);
1417
- }
1613
+ }
1614
+ function extractStepStatusFromString(normXml) {
1615
+ const stepMatch = normXml.match(STEP_TAG_RE);
1616
+ const statusMatch = normXml.match(STATUS_TAG_RE);
1617
+ if (stepMatch && statusMatch) {
1618
+ return { step: stepMatch[1], status: statusMatch[1] };
1418
1619
  }
1419
- return names;
1620
+ return null;
1420
1621
  }
1421
- function escapeRegExp2(s) {
1422
- return s.replace(/[.*+?^${}()|[\\]\\]/g, "\\$&");
1622
+
1623
+ // src/utils/type-guards.ts
1624
+ function isToolCallContent(content) {
1625
+ return content.type === "tool-call" && typeof content.toolName === "string" && // input may be a JSON string or an already-parsed object depending on provider/runtime
1626
+ (typeof content.input === "string" || typeof content.input === "object");
1423
1627
  }
1424
- function dedupeStringTagsAgainstSchema(xml, schema) {
1425
- const names = getStringPropertyNames(schema);
1426
- let out = xml;
1427
- for (const key of names) {
1428
- out = dedupeSingleTag(out, key);
1429
- }
1430
- return out;
1628
+ function hasInputProperty(obj) {
1629
+ return typeof obj === "object" && obj !== null && "input" in obj;
1431
1630
  }
1432
- function dedupeSingleTag(xml, key) {
1433
- var _a, _b;
1434
- const escaped = escapeRegExp2(key);
1435
- const re = new RegExp(`<${escaped}>([\\s\\S]*?)<\\/${escaped}>`, "g");
1436
- const matches = Array.from(xml.matchAll(re));
1437
- if (matches.length <= 1) {
1438
- return xml;
1439
- }
1440
- const last = matches.at(-1);
1441
- let result = "";
1442
- let cursor = 0;
1443
- for (const m of matches) {
1444
- const idx = (_a = m.index) != null ? _a : 0;
1445
- result += xml.slice(cursor, idx);
1446
- if (last && idx === ((_b = last.index) != null ? _b : -1)) {
1447
- result += m[0];
1448
- }
1449
- cursor = idx + m[0].length;
1450
- }
1451
- result += xml.slice(cursor);
1452
- return result;
1631
+
1632
+ // src/protocols/morph-xml-protocol.ts
1633
+ var defaultPipelineConfig2 = defaultPipelineConfig;
1634
+ var applyHeuristicPipeline2 = applyHeuristicPipeline;
1635
+ var createIntermediateCall2 = createIntermediateCall;
1636
+ var mergePipelineConfigs2 = mergePipelineConfigs;
1637
+ var WHITESPACE_REGEX3 = /\s/;
1638
+ var MALFORMED_CLOSE_RE2 = /<\/\s+([A-Za-z0-9_:-]+)\s*>/;
1639
+ var MALFORMED_CLOSE_RE_G2 = /<\/\s+([A-Za-z0-9_:-]+)\s*>/g;
1640
+ var NAME_CHAR_RE2 = /[A-Za-z0-9_:-]/;
1641
+ function normalizeCloseTags(xml) {
1642
+ return xml.replace(MALFORMED_CLOSE_RE_G2, "</$1>");
1453
1643
  }
1454
- function tryParseStringToSchemaObject(xml, itemSchema, options) {
1644
+ function tryParseSecondaryXml(content, toolSchema, options) {
1645
+ const normalized = normalizeCloseTags(content);
1646
+ const balanced = balanceTags(content);
1647
+ const hasMalformedClose = MALFORMED_CLOSE_RE2.test(content);
1648
+ if (!hasMalformedClose && balanced.length > normalized.length) {
1649
+ return null;
1650
+ }
1455
1651
  try {
1456
- const fixed = (0, import_rxml.parse)(normalizeCloseTags(xml), itemSchema, {
1652
+ let parsed = (0, import_rxml2.parse)(balanced, toolSchema, {
1457
1653
  onError: options == null ? void 0 : options.onError,
1458
1654
  noChildNodes: []
1459
1655
  });
1460
- return typeof fixed === "string" ? null : fixed;
1656
+ parsed = repairParsedAgainstSchema(parsed, toolSchema);
1657
+ return parsed;
1461
1658
  } catch (e) {
1659
+ if (shouldDeduplicateStringTags(toolSchema)) {
1660
+ const deduped = dedupeStringTagsAgainstSchema(balanced, toolSchema);
1661
+ if (deduped !== balanced) {
1662
+ try {
1663
+ let reparsed = (0, import_rxml2.parse)(deduped, toolSchema, {
1664
+ onError: options == null ? void 0 : options.onError,
1665
+ noChildNodes: []
1666
+ });
1667
+ reparsed = repairParsedAgainstSchema(reparsed, toolSchema);
1668
+ return reparsed;
1669
+ } catch (e2) {
1670
+ return null;
1671
+ }
1672
+ }
1673
+ }
1462
1674
  return null;
1463
1675
  }
1464
1676
  }
1465
- function extractStepStatusFromString(normXml) {
1466
- const stepMatch = normXml.match(STEP_TAG_RE);
1467
- const statusMatch = normXml.match(STATUS_TAG_RE);
1468
- if (stepMatch && statusMatch) {
1469
- return { step: stepMatch[1], status: statusMatch[1] };
1677
+ function dedupeStringTagsAgainstSchema(xml, schema) {
1678
+ const names = getStringPropertyNames(schema);
1679
+ let out = xml;
1680
+ for (const key of names) {
1681
+ out = dedupeSingleTag(out, key);
1470
1682
  }
1471
- return null;
1683
+ return out;
1472
1684
  }
1473
1685
  function processTextBeforeToolCall(text, currentIndex, toolCallStartIndex, processedElements) {
1474
1686
  if (toolCallStartIndex > currentIndex) {
@@ -1479,18 +1691,60 @@ function processTextBeforeToolCall(text, currentIndex, toolCallStartIndex, proce
1479
1691
  }
1480
1692
  return currentIndex;
1481
1693
  }
1694
+ function processToolCallWithPipeline(params) {
1695
+ var _a;
1696
+ const {
1697
+ toolCall,
1698
+ tools,
1699
+ options,
1700
+ text,
1701
+ processedElements,
1702
+ pipelineConfig = defaultPipelineConfig2,
1703
+ maxReparses
1704
+ } = params;
1705
+ const toolSchema = getToolSchema(tools, toolCall.toolName);
1706
+ const ctx = createIntermediateCall2(
1707
+ toolCall.toolName,
1708
+ toolCall.content,
1709
+ toolSchema
1710
+ );
1711
+ const result = applyHeuristicPipeline2(ctx, pipelineConfig, {
1712
+ parse: (xml, schema) => (0, import_rxml2.parse)(xml, schema, { onError: options == null ? void 0 : options.onError, noChildNodes: [] }),
1713
+ onError: options == null ? void 0 : options.onError,
1714
+ maxReparses
1715
+ });
1716
+ if (result.parsed !== null) {
1717
+ processedElements.push({
1718
+ type: "tool-call",
1719
+ toolCallId: (0, import_provider_utils2.generateId)(),
1720
+ toolName: toolCall.toolName,
1721
+ input: JSON.stringify(result.parsed)
1722
+ });
1723
+ } else {
1724
+ const originalCallText = text.substring(
1725
+ toolCall.startIndex,
1726
+ toolCall.endIndex
1727
+ );
1728
+ const message = `Could not process XML tool call, keeping original text: ${originalCallText}`;
1729
+ (_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, message, {
1730
+ toolCall: originalCallText,
1731
+ toolName: toolCall.toolName,
1732
+ error: result.errors[0]
1733
+ });
1734
+ processedElements.push({ type: "text", text: originalCallText });
1735
+ }
1736
+ }
1482
1737
  function processToolCall(params) {
1483
1738
  var _a;
1484
1739
  const { toolCall, tools, options, text, processedElements } = params;
1485
1740
  const toolSchema = getToolSchema(tools, toolCall.toolName);
1486
1741
  try {
1487
1742
  const primary = escapeInvalidLt(normalizeCloseTags(toolCall.content));
1488
- let parsed = (0, import_rxml.parse)(primary, toolSchema, {
1743
+ let parsed = (0, import_rxml2.parse)(primary, toolSchema, {
1489
1744
  onError: options == null ? void 0 : options.onError,
1490
- // Disable HTML self-closing tag behavior to allow base, meta, link etc. as regular tags
1491
1745
  noChildNodes: []
1492
1746
  });
1493
- parsed = repairParsedAgainstSchema(parsed, toolSchema, options);
1747
+ parsed = repairParsedAgainstSchema(parsed, toolSchema);
1494
1748
  processedElements.push({
1495
1749
  type: "tool-call",
1496
1750
  toolCallId: (0, import_provider_utils2.generateId)(),
@@ -1533,16 +1787,67 @@ function addRemainingText(text, currentIndex, processedElements) {
1533
1787
  }
1534
1788
  }
1535
1789
  }
1790
+ function handleStreamingToolCallEndWithPipeline(params) {
1791
+ var _a;
1792
+ const {
1793
+ toolContent,
1794
+ currentToolCall,
1795
+ tools,
1796
+ options,
1797
+ ctrl,
1798
+ flushText,
1799
+ pipelineConfig = defaultPipelineConfig2,
1800
+ maxReparses
1801
+ } = params;
1802
+ const toolSchema = getToolSchema(tools, currentToolCall.name);
1803
+ const ctx = createIntermediateCall2(
1804
+ currentToolCall.name,
1805
+ toolContent,
1806
+ toolSchema
1807
+ );
1808
+ const result = applyHeuristicPipeline2(ctx, pipelineConfig, {
1809
+ parse: (xml, schema) => (0, import_rxml2.parse)(xml, schema, { onError: options == null ? void 0 : options.onError, noChildNodes: [] }),
1810
+ onError: options == null ? void 0 : options.onError,
1811
+ maxReparses
1812
+ });
1813
+ flushText(ctrl);
1814
+ if (result.parsed !== null) {
1815
+ ctrl.enqueue({
1816
+ type: "tool-call",
1817
+ toolCallId: (0, import_provider_utils2.generateId)(),
1818
+ toolName: currentToolCall.name,
1819
+ input: JSON.stringify(result.parsed)
1820
+ });
1821
+ } else {
1822
+ const endTag = `</${currentToolCall.name}>`;
1823
+ const originalCallText = `<${currentToolCall.name}>${toolContent}${endTag}`;
1824
+ const error = result.errors[0];
1825
+ let message = "Could not process streaming XML tool call; emitting original text.";
1826
+ if (error instanceof import_rxml2.RXMLDuplicateStringTagError) {
1827
+ message = `Duplicate string tags detected in streaming tool call '${currentToolCall.name}'; emitting original text.`;
1828
+ } else if (error instanceof import_rxml2.RXMLCoercionError) {
1829
+ message = `Failed to coerce arguments for streaming tool call '${currentToolCall.name}'; emitting original text.`;
1830
+ } else if (error instanceof import_rxml2.RXMLParseError) {
1831
+ message = `Failed to parse XML for streaming tool call '${currentToolCall.name}'; emitting original text.`;
1832
+ }
1833
+ (_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, message, {
1834
+ toolCall: originalCallText,
1835
+ toolName: currentToolCall.name,
1836
+ error
1837
+ });
1838
+ flushText(ctrl, originalCallText);
1839
+ }
1840
+ }
1536
1841
  function handleStreamingToolCallEnd(params) {
1537
1842
  const { toolContent, currentToolCall, tools, options, ctrl, flushText } = params;
1538
1843
  const toolSchema = getToolSchema(tools, currentToolCall.name);
1539
1844
  try {
1540
1845
  const primary = escapeInvalidLt(normalizeCloseTags(toolContent));
1541
- let parsed = (0, import_rxml.parse)(primary, toolSchema, {
1846
+ let parsed = (0, import_rxml2.parse)(primary, toolSchema, {
1542
1847
  onError: options == null ? void 0 : options.onError,
1543
1848
  noChildNodes: []
1544
1849
  });
1545
- parsed = repairParsedAgainstSchema(parsed, toolSchema, options);
1850
+ parsed = repairParsedAgainstSchema(parsed, toolSchema);
1546
1851
  flushText(ctrl);
1547
1852
  ctrl.enqueue({
1548
1853
  type: "tool-call",
@@ -1578,11 +1883,11 @@ function handleStreamingToolCallError(params) {
1578
1883
  const endTag = `</${currentToolCall.name}>`;
1579
1884
  const originalCallText = `<${currentToolCall.name}>${toolContent}${endTag}`;
1580
1885
  let message = "Could not process streaming XML tool call; emitting original text.";
1581
- if (error instanceof import_rxml.RXMLDuplicateStringTagError) {
1886
+ if (error instanceof import_rxml2.RXMLDuplicateStringTagError) {
1582
1887
  message = `Duplicate string tags detected in streaming tool call '${currentToolCall.name}'; emitting original text.`;
1583
- } else if (error instanceof import_rxml.RXMLCoercionError) {
1888
+ } else if (error instanceof import_rxml2.RXMLCoercionError) {
1584
1889
  message = `Failed to coerce arguments for streaming tool call '${currentToolCall.name}'; emitting original text.`;
1585
- } else if (error instanceof import_rxml.RXMLParseError) {
1890
+ } else if (error instanceof import_rxml2.RXMLParseError) {
1586
1891
  message = `Failed to parse XML for streaming tool call '${currentToolCall.name}'; emitting original text.`;
1587
1892
  }
1588
1893
  (_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, message, {
@@ -1634,7 +1939,9 @@ function processToolCallInBuffer(params) {
1634
1939
  options,
1635
1940
  controller,
1636
1941
  flushText,
1637
- setBuffer
1942
+ setBuffer,
1943
+ pipelineConfig,
1944
+ maxReparses
1638
1945
  } = params;
1639
1946
  const endTag = `</${currentToolCall.name}>`;
1640
1947
  const normalized = normalizeCloseTags(buffer);
@@ -1644,14 +1951,27 @@ function processToolCallInBuffer(params) {
1644
1951
  const toolContent = effectiveBuffer.substring(0, endTagIndex);
1645
1952
  const newBuffer = effectiveBuffer.substring(endTagIndex + endTag.length);
1646
1953
  setBuffer("");
1647
- handleStreamingToolCallEnd({
1648
- toolContent,
1649
- currentToolCall,
1650
- tools,
1651
- options,
1652
- ctrl: controller,
1653
- flushText
1654
- });
1954
+ if (pipelineConfig) {
1955
+ handleStreamingToolCallEndWithPipeline({
1956
+ toolContent,
1957
+ currentToolCall,
1958
+ tools,
1959
+ options,
1960
+ ctrl: controller,
1961
+ flushText,
1962
+ pipelineConfig,
1963
+ maxReparses
1964
+ });
1965
+ } else {
1966
+ handleStreamingToolCallEnd({
1967
+ toolContent,
1968
+ currentToolCall,
1969
+ tools,
1970
+ options,
1971
+ ctrl: controller,
1972
+ flushText
1973
+ });
1974
+ }
1655
1975
  setBuffer(newBuffer);
1656
1976
  return { buffer: newBuffer, currentToolCall: null, shouldBreak: false };
1657
1977
  }
@@ -1665,7 +1985,9 @@ function processNoToolCallInBuffer(params) {
1665
1985
  controller,
1666
1986
  flushText,
1667
1987
  tools,
1668
- options
1988
+ options,
1989
+ pipelineConfig,
1990
+ maxReparses
1669
1991
  } = params;
1670
1992
  const {
1671
1993
  index: earliestStartTagIndex,
@@ -1680,14 +2002,27 @@ function processNoToolCallInBuffer(params) {
1680
2002
  const newBuffer2 = buffer.substring(
1681
2003
  earliestStartTagIndex + selfTag.length
1682
2004
  );
1683
- handleStreamingToolCallEnd({
1684
- toolContent: "",
1685
- currentToolCall: { name: earliestToolName, content: "" },
1686
- tools,
1687
- options,
1688
- ctrl: controller,
1689
- flushText
1690
- });
2005
+ if (pipelineConfig) {
2006
+ handleStreamingToolCallEndWithPipeline({
2007
+ toolContent: "",
2008
+ currentToolCall: { name: earliestToolName, content: "" },
2009
+ tools,
2010
+ options,
2011
+ ctrl: controller,
2012
+ flushText,
2013
+ pipelineConfig,
2014
+ maxReparses
2015
+ });
2016
+ } else {
2017
+ handleStreamingToolCallEnd({
2018
+ toolContent: "",
2019
+ currentToolCall: { name: earliestToolName, content: "" },
2020
+ tools,
2021
+ options,
2022
+ ctrl: controller,
2023
+ flushText
2024
+ });
2025
+ }
1691
2026
  return {
1692
2027
  buffer: newBuffer2,
1693
2028
  currentToolCall: null,
@@ -1751,7 +2086,9 @@ function processBufferWithToolCall(params, controller) {
1751
2086
  setCurrentToolCall,
1752
2087
  tools,
1753
2088
  options,
1754
- flushText
2089
+ flushText,
2090
+ pipelineConfig,
2091
+ maxReparses
1755
2092
  } = params;
1756
2093
  const currentToolCall = getCurrentToolCall();
1757
2094
  if (!currentToolCall) {
@@ -1764,7 +2101,9 @@ function processBufferWithToolCall(params, controller) {
1764
2101
  options,
1765
2102
  controller,
1766
2103
  flushText,
1767
- setBuffer
2104
+ setBuffer,
2105
+ pipelineConfig,
2106
+ maxReparses
1768
2107
  });
1769
2108
  setBuffer(result.buffer);
1770
2109
  setCurrentToolCall(result.currentToolCall);
@@ -1779,7 +2118,9 @@ function processBufferWithoutToolCall(params, controller) {
1779
2118
  options,
1780
2119
  toolNames,
1781
2120
  maxStartTagLen,
1782
- flushText
2121
+ flushText,
2122
+ pipelineConfig,
2123
+ maxReparses
1783
2124
  } = params;
1784
2125
  const result = processNoToolCallInBuffer({
1785
2126
  buffer: getBuffer(),
@@ -1788,7 +2129,9 @@ function processBufferWithoutToolCall(params, controller) {
1788
2129
  controller,
1789
2130
  flushText,
1790
2131
  tools,
1791
- options
2132
+ options,
2133
+ pipelineConfig,
2134
+ maxReparses
1792
2135
  });
1793
2136
  setBuffer(result.buffer);
1794
2137
  setCurrentToolCall(result.currentToolCall);
@@ -1824,139 +2167,218 @@ function createProcessBufferHandler(params) {
1824
2167
  processBufferLoop(params, controller);
1825
2168
  };
1826
2169
  }
1827
- var morphXmlProtocol = () => ({
1828
- formatTools({ tools, toolSystemPromptTemplate }) {
1829
- const toolsForPrompt = (tools || []).map((tool) => ({
1830
- name: tool.name,
1831
- description: tool.description,
1832
- parameters: (0, import_rxml.unwrapJsonSchema)(tool.inputSchema)
1833
- }));
1834
- return toolSystemPromptTemplate(JSON.stringify(toolsForPrompt));
1835
- },
1836
- formatToolCall(toolCall) {
1837
- let args = {};
1838
- const inputValue = hasInputProperty(toolCall) ? toolCall.input : void 0;
1839
- if (typeof inputValue === "string") {
1840
- try {
1841
- args = JSON.parse(inputValue);
1842
- } catch (e) {
2170
+ function buildPipelineOptions(protocolOptions) {
2171
+ var _a, _b, _c;
2172
+ const maxReparses = protocolOptions == null ? void 0 : protocolOptions.maxReparses;
2173
+ if (protocolOptions == null ? void 0 : protocolOptions.pipeline) {
2174
+ return {
2175
+ pipelineConfig: mergePipelineConfigs2(
2176
+ defaultPipelineConfig2,
2177
+ protocolOptions.pipeline
2178
+ ),
2179
+ maxReparses
2180
+ };
2181
+ }
2182
+ if (protocolOptions == null ? void 0 : protocolOptions.heuristics) {
2183
+ return {
2184
+ pipelineConfig: {
2185
+ ...defaultPipelineConfig2,
2186
+ preParse: [
2187
+ ...(_a = defaultPipelineConfig2.preParse) != null ? _a : [],
2188
+ ...protocolOptions.heuristics.filter((h) => h.phase === "pre-parse")
2189
+ ],
2190
+ fallbackReparse: [
2191
+ ...(_b = defaultPipelineConfig2.fallbackReparse) != null ? _b : [],
2192
+ ...protocolOptions.heuristics.filter(
2193
+ (h) => h.phase === "fallback-reparse"
2194
+ )
2195
+ ],
2196
+ postParse: [
2197
+ ...(_c = defaultPipelineConfig2.postParse) != null ? _c : [],
2198
+ ...protocolOptions.heuristics.filter((h) => h.phase === "post-parse")
2199
+ ]
2200
+ },
2201
+ maxReparses
2202
+ };
2203
+ }
2204
+ return { pipelineConfig: void 0, maxReparses };
2205
+ }
2206
+ var morphXmlProtocol = (protocolOptions) => {
2207
+ const { pipelineConfig, maxReparses } = buildPipelineOptions(protocolOptions);
2208
+ return {
2209
+ formatTools({ tools, toolSystemPromptTemplate }) {
2210
+ const toolsForPrompt = (tools || []).map((tool) => ({
2211
+ name: tool.name,
2212
+ description: tool.description,
2213
+ parameters: (0, import_rxml2.unwrapJsonSchema)(tool.inputSchema)
2214
+ }));
2215
+ return toolSystemPromptTemplate(JSON.stringify(toolsForPrompt));
2216
+ },
2217
+ formatToolCall(toolCall) {
2218
+ let args = {};
2219
+ const inputValue = hasInputProperty(toolCall) ? toolCall.input : void 0;
2220
+ if (typeof inputValue === "string") {
2221
+ try {
2222
+ args = JSON.parse(inputValue);
2223
+ } catch (e) {
2224
+ args = inputValue;
2225
+ }
2226
+ } else {
1843
2227
  args = inputValue;
1844
2228
  }
1845
- } else {
1846
- args = inputValue;
1847
- }
1848
- return (0, import_rxml.stringify)(toolCall.toolName, args, {
1849
- suppressEmptyNode: false,
1850
- format: false
1851
- });
1852
- },
1853
- formatToolResponse(toolResult) {
1854
- return (0, import_rxml.stringify)("tool_response", {
1855
- tool_name: toolResult.toolName,
1856
- result: toolResult.output
1857
- });
1858
- },
1859
- parseGeneratedText({ text, tools, options }) {
1860
- const toolNames = tools.map((t) => t.name).filter((name) => name != null);
1861
- if (toolNames.length === 0) {
1862
- return [{ type: "text", text }];
1863
- }
1864
- const processedElements = [];
1865
- let currentIndex = 0;
1866
- const toolCallsRaw = findToolCalls(text, toolNames);
1867
- const toolCallsNorm = collectToolCallsFromNormalizedText(text, toolNames);
1868
- const seen = /* @__PURE__ */ new Set();
1869
- const toolCalls = [...toolCallsRaw, ...toolCallsNorm].filter((tc) => {
1870
- const key = `${tc.toolName}:${tc.startIndex}:${tc.endIndex}`;
1871
- if (seen.has(key)) {
1872
- return false;
1873
- }
1874
- seen.add(key);
1875
- return true;
1876
- }).sort((a, b) => a.startIndex - b.startIndex);
1877
- for (const toolCall of toolCalls) {
1878
- currentIndex = processTextBeforeToolCall(
1879
- text,
1880
- currentIndex,
1881
- toolCall.startIndex,
1882
- processedElements
1883
- );
1884
- processToolCall({ toolCall, tools, options, text, processedElements });
1885
- currentIndex = toolCall.endIndex;
1886
- }
1887
- addRemainingText(text, currentIndex, processedElements);
1888
- return processedElements;
1889
- },
1890
- createStreamParser({ tools, options }) {
1891
- const toolNames = tools.map((t) => t.name).filter((name) => name != null);
1892
- const maxStartTagLen = toolNames.length ? Math.max(...toolNames.map((n) => `<${n}>`.length)) : 0;
1893
- let buffer = "";
1894
- let currentToolCall = null;
1895
- let currentTextId = null;
1896
- const flushText = createFlushTextHandler(
1897
- () => buffer,
1898
- (newBuffer) => {
1899
- buffer = newBuffer;
1900
- },
1901
- () => currentTextId,
1902
- (newId) => {
1903
- currentTextId = newId;
2229
+ return (0, import_rxml2.stringify)(toolCall.toolName, args, {
2230
+ suppressEmptyNode: false,
2231
+ format: false
2232
+ });
2233
+ },
2234
+ formatToolResponse(toolResult) {
2235
+ return (0, import_rxml2.stringify)("tool_response", {
2236
+ tool_name: toolResult.toolName,
2237
+ result: toolResult.output
2238
+ });
2239
+ },
2240
+ parseGeneratedText({ text, tools, options }) {
2241
+ const toolNames = tools.map((t) => t.name).filter((name) => name != null);
2242
+ if (toolNames.length === 0) {
2243
+ return [{ type: "text", text }];
1904
2244
  }
1905
- );
1906
- const processChunk = (chunk, controller) => {
1907
- if (chunk.type !== "text-delta") {
1908
- if (buffer) {
1909
- flushText(controller);
2245
+ const processedElements = [];
2246
+ let currentIndex = 0;
2247
+ const toolCallsRaw = findToolCalls(text, toolNames);
2248
+ const toolCallsNorm = collectToolCallsFromNormalizedText(text, toolNames);
2249
+ const seen = /* @__PURE__ */ new Set();
2250
+ const toolCalls = [...toolCallsRaw, ...toolCallsNorm].filter((tc) => {
2251
+ const key = `${tc.toolName}:${tc.startIndex}:${tc.endIndex}`;
2252
+ if (seen.has(key)) {
2253
+ return false;
1910
2254
  }
1911
- controller.enqueue(chunk);
1912
- return;
1913
- }
1914
- buffer += chunk.delta;
1915
- processBuffer(controller);
1916
- };
1917
- const processBuffer = createProcessBufferHandler({
1918
- getBuffer: () => buffer,
1919
- setBuffer: (newBuffer) => {
1920
- buffer = newBuffer;
1921
- },
1922
- getCurrentToolCall: () => currentToolCall,
1923
- setCurrentToolCall: (newToolCall) => {
1924
- currentToolCall = newToolCall;
1925
- },
1926
- tools,
1927
- options,
1928
- toolNames,
1929
- maxStartTagLen,
1930
- flushText
1931
- });
1932
- const flushBuffer2 = (controller) => {
1933
- if (currentToolCall) {
1934
- const unfinishedCall = `<${currentToolCall.name}>${buffer}`;
1935
- flushText(controller, unfinishedCall);
1936
- } else if (buffer) {
1937
- flushText(controller);
2255
+ seen.add(key);
2256
+ return true;
2257
+ }).sort((a, b) => a.startIndex - b.startIndex);
2258
+ if (process.env.DEBUG_PARSER_OUTPUT === "true") {
2259
+ console.log("\n=== PARSER DEBUG ===");
2260
+ console.log(`Available tools: ${toolNames.join(", ")}`);
2261
+ console.log(`Full text length: ${text.length}`);
2262
+ console.log(`Full text:
2263
+ ${text}
2264
+ `);
2265
+ console.log(`Tool calls found: ${toolCalls.length}`);
2266
+ for (let i = 0; i < toolCalls.length; i++) {
2267
+ const tc = toolCalls[i];
2268
+ console.log(`
2269
+ [Tool Call ${i + 1}] ${tc.toolName}`);
2270
+ console.log(`Position: ${tc.startIndex} - ${tc.endIndex}`);
2271
+ console.log(`Segment:
2272
+ ${tc.segment}`);
2273
+ console.log(`Content:
2274
+ ${tc.content}`);
2275
+ }
2276
+ console.log("===================\n");
1938
2277
  }
1939
- if (currentTextId) {
1940
- controller.enqueue({ type: "text-end", id: currentTextId });
2278
+ for (const toolCall of toolCalls) {
2279
+ currentIndex = processTextBeforeToolCall(
2280
+ text,
2281
+ currentIndex,
2282
+ toolCall.startIndex,
2283
+ processedElements
2284
+ );
2285
+ if (pipelineConfig) {
2286
+ processToolCallWithPipeline({
2287
+ toolCall,
2288
+ tools,
2289
+ options,
2290
+ text,
2291
+ processedElements,
2292
+ pipelineConfig,
2293
+ maxReparses
2294
+ });
2295
+ } else {
2296
+ processToolCall({
2297
+ toolCall,
2298
+ tools,
2299
+ options,
2300
+ text,
2301
+ processedElements
2302
+ });
2303
+ }
2304
+ currentIndex = toolCall.endIndex;
1941
2305
  }
1942
- };
1943
- return new TransformStream({
1944
- transform(chunk, controller) {
1945
- processChunk(chunk, controller);
1946
- },
1947
- flush(controller) {
1948
- flushBuffer2(controller);
2306
+ addRemainingText(text, currentIndex, processedElements);
2307
+ return processedElements;
2308
+ },
2309
+ createStreamParser({ tools, options }) {
2310
+ const toolNames = tools.map((t) => t.name).filter((name) => name != null);
2311
+ const maxStartTagLen = toolNames.length ? Math.max(...toolNames.map((n) => `<${n}>`.length)) : 0;
2312
+ let buffer = "";
2313
+ let currentToolCall = null;
2314
+ let currentTextId = null;
2315
+ const flushText = createFlushTextHandler(
2316
+ () => buffer,
2317
+ (newBuffer) => {
2318
+ buffer = newBuffer;
2319
+ },
2320
+ () => currentTextId,
2321
+ (newId) => {
2322
+ currentTextId = newId;
2323
+ }
2324
+ );
2325
+ const processChunk = (chunk, controller) => {
2326
+ if (chunk.type !== "text-delta") {
2327
+ if (buffer) {
2328
+ flushText(controller);
2329
+ }
2330
+ controller.enqueue(chunk);
2331
+ return;
2332
+ }
2333
+ buffer += chunk.delta;
2334
+ processBuffer(controller);
2335
+ };
2336
+ const processBuffer = createProcessBufferHandler({
2337
+ getBuffer: () => buffer,
2338
+ setBuffer: (newBuffer) => {
2339
+ buffer = newBuffer;
2340
+ },
2341
+ getCurrentToolCall: () => currentToolCall,
2342
+ setCurrentToolCall: (newToolCall) => {
2343
+ currentToolCall = newToolCall;
2344
+ },
2345
+ tools,
2346
+ options,
2347
+ toolNames,
2348
+ maxStartTagLen,
2349
+ flushText,
2350
+ pipelineConfig,
2351
+ maxReparses
2352
+ });
2353
+ const flushBuffer2 = (controller) => {
2354
+ if (currentToolCall) {
2355
+ const unfinishedCall = `<${currentToolCall.name}>${buffer}`;
2356
+ flushText(controller, unfinishedCall);
2357
+ } else if (buffer) {
2358
+ flushText(controller);
2359
+ }
2360
+ if (currentTextId) {
2361
+ controller.enqueue({ type: "text-end", id: currentTextId });
2362
+ }
2363
+ };
2364
+ return new TransformStream({
2365
+ transform(chunk, controller) {
2366
+ processChunk(chunk, controller);
2367
+ },
2368
+ flush(controller) {
2369
+ flushBuffer2(controller);
2370
+ }
2371
+ });
2372
+ },
2373
+ extractToolCallSegments({ text, tools }) {
2374
+ const toolNames = tools.map((t) => t.name).filter(Boolean);
2375
+ if (toolNames.length === 0) {
2376
+ return [];
1949
2377
  }
1950
- });
1951
- },
1952
- extractToolCallSegments({ text, tools }) {
1953
- const toolNames = tools.map((t) => t.name).filter(Boolean);
1954
- if (toolNames.length === 0) {
1955
- return [];
2378
+ return findToolCalls(text, toolNames).map((tc) => tc.segment);
1956
2379
  }
1957
- return findToolCalls(text, toolNames).map((tc) => tc.segment);
1958
- }
1959
- });
2380
+ };
2381
+ };
1960
2382
  function getToolSchema(tools, toolName) {
1961
2383
  var _a;
1962
2384
  return (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
@@ -1989,32 +2411,22 @@ function skipSpecialSegment(text, lt) {
1989
2411
  }
1990
2412
  return gt + 1;
1991
2413
  }
1992
- function consumeClosingTag(text, lt, toolName) {
2414
+ function consumeClosingTag(text, lt, _toolName) {
1993
2415
  let p = lt + 2;
1994
- while (p < text.length && WHITESPACE_REGEX2.test(text[p])) {
2416
+ while (p < text.length && WHITESPACE_REGEX3.test(text[p])) {
1995
2417
  p += 1;
1996
2418
  }
1997
- if (text.slice(p, p + toolName.length) === toolName) {
1998
- p += toolName.length;
1999
- while (p < text.length && WHITESPACE_REGEX2.test(text[p])) {
2000
- p += 1;
2001
- }
2002
- if (text[p] === ">") {
2003
- const endPos2 = p + 1;
2004
- return { matched: true, endPos: endPos2 };
2005
- }
2006
- }
2007
2419
  const gt = text.indexOf(">", lt + 1);
2008
2420
  const endPos = gt === -1 ? text.length : gt + 1;
2009
2421
  return { matched: false, endPos };
2010
2422
  }
2011
2423
  function consumeOpenTag(text, lt) {
2012
2424
  let p = lt + 1;
2013
- while (p < text.length && WHITESPACE_REGEX2.test(text[p])) {
2425
+ while (p < text.length && WHITESPACE_REGEX3.test(text[p])) {
2014
2426
  p += 1;
2015
2427
  }
2016
2428
  const nameStart = p;
2017
- while (p < text.length && NAME_CHAR_RE.test(text.charAt(p))) {
2429
+ while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
2018
2430
  p += 1;
2019
2431
  }
2020
2432
  const name = text.slice(nameStart, p);
@@ -2023,7 +2435,7 @@ function consumeOpenTag(text, lt) {
2023
2435
  return null;
2024
2436
  }
2025
2437
  let r = q - 1;
2026
- while (r >= nameStart && WHITESPACE_REGEX2.test(text[r])) {
2438
+ while (r >= nameStart && WHITESPACE_REGEX3.test(text[r])) {
2027
2439
  r -= 1;
2028
2440
  }
2029
2441
  const selfClosing = text[r] === "/";
@@ -2052,11 +2464,11 @@ function nextTagToken(text, fromPos) {
2052
2464
  if (next === "/") {
2053
2465
  const closing = consumeClosingTag(text, lt, "");
2054
2466
  let p = lt + 2;
2055
- while (p < text.length && WHITESPACE_REGEX2.test(text[p])) {
2467
+ while (p < text.length && WHITESPACE_REGEX3.test(text[p])) {
2056
2468
  p += 1;
2057
2469
  }
2058
2470
  const nameStart = p;
2059
- while (p < text.length && NAME_CHAR_RE.test(text.charAt(p))) {
2471
+ while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
2060
2472
  p += 1;
2061
2473
  }
2062
2474
  const name = text.slice(nameStart, p);
@@ -2105,7 +2517,7 @@ function collectToolCallsFromNormalizedText(text, toolNames) {
2105
2517
  endOrig = Math.min(text.length, tagStartOrig + approxLen);
2106
2518
  }
2107
2519
  const segment = text.substring(tagStartOrig, endOrig);
2108
- const inner = (_a = (0, import_rxml.extractRawInner)(segment, toolName)) != null ? _a : segment.substring(startTag.length, segment.lastIndexOf("<"));
2520
+ const inner = (_a = (0, import_rxml2.extractRawInner)(segment, toolName)) != null ? _a : segment.substring(startTag.length, segment.lastIndexOf("<"));
2109
2521
  collected.push({
2110
2522
  toolName,
2111
2523
  startIndex: tagStartOrig,
@@ -2169,7 +2581,7 @@ function findToolCallsForName(text, toolName) {
2169
2581
  const fullTagEnd = findClosingTagEndFlexible(text, contentStart, toolName);
2170
2582
  if (fullTagEnd !== -1 && fullTagEnd > contentStart) {
2171
2583
  const segment = text.substring(tagStart, fullTagEnd);
2172
- const inner = (_a = (0, import_rxml.extractRawInner)(segment, toolName)) != null ? _a : segment.substring(startTag.length, segment.lastIndexOf("<"));
2584
+ const inner = (_a = (0, import_rxml2.extractRawInner)(segment, toolName)) != null ? _a : segment.substring(startTag.length, segment.lastIndexOf("<"));
2173
2585
  toolCalls.push({
2174
2586
  toolName,
2175
2587
  startIndex: tagStart,
@@ -2195,7 +2607,7 @@ function findToolCalls(text, toolNames) {
2195
2607
 
2196
2608
  // src/generate-handler.ts
2197
2609
  var import_provider_utils3 = require("@ai-sdk/provider-utils");
2198
- var import_rxml2 = require("@ai-sdk-tool/rxml");
2610
+ var import_rxml3 = require("@ai-sdk-tool/rxml");
2199
2611
 
2200
2612
  // src/utils/on-error.ts
2201
2613
  function extractOnErrorOption(providerOptions) {
@@ -2399,7 +2811,7 @@ function fixToolCallWithSchema(part, tools) {
2399
2811
  args = tc.input;
2400
2812
  }
2401
2813
  const schema = (_a = tools.find((t) => t.name === tc.toolName)) == null ? void 0 : _a.inputSchema;
2402
- const coerced = (0, import_rxml2.coerceBySchema)(args, schema);
2814
+ const coerced = (0, import_rxml3.coerceBySchema)(args, schema);
2403
2815
  return {
2404
2816
  ...part,
2405
2817
  input: JSON.stringify(coerced != null ? coerced : {})