@ai-sdk-tool/parser 3.0.0-canary.1 → 3.0.0-canary.2

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