@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.
@@ -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,198 @@ 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;
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 }];
1873
2244
  }
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;
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;
2254
+ }
2255
+ seen.add(key);
2256
+ return true;
2257
+ }).sort((a, b) => a.startIndex - b.startIndex);
2258
+ for (const toolCall of toolCalls) {
2259
+ currentIndex = processTextBeforeToolCall(
2260
+ text,
2261
+ currentIndex,
2262
+ toolCall.startIndex,
2263
+ processedElements
2264
+ );
2265
+ if (pipelineConfig) {
2266
+ processToolCallWithPipeline({
2267
+ toolCall,
2268
+ tools,
2269
+ options,
2270
+ text,
2271
+ processedElements,
2272
+ pipelineConfig,
2273
+ maxReparses
2274
+ });
2275
+ } else {
2276
+ processToolCall({
2277
+ toolCall,
2278
+ tools,
2279
+ options,
2280
+ text,
2281
+ processedElements
2282
+ });
2283
+ }
2284
+ currentIndex = toolCall.endIndex;
1904
2285
  }
1905
- );
1906
- const processChunk = (chunk, controller) => {
1907
- if (chunk.type !== "text-delta") {
1908
- if (buffer) {
2286
+ addRemainingText(text, currentIndex, processedElements);
2287
+ return processedElements;
2288
+ },
2289
+ createStreamParser({ tools, options }) {
2290
+ const toolNames = tools.map((t) => t.name).filter((name) => name != null);
2291
+ const maxStartTagLen = toolNames.length ? Math.max(...toolNames.map((n) => `<${n}>`.length)) : 0;
2292
+ let buffer = "";
2293
+ let currentToolCall = null;
2294
+ let currentTextId = null;
2295
+ const flushText = createFlushTextHandler(
2296
+ () => buffer,
2297
+ (newBuffer) => {
2298
+ buffer = newBuffer;
2299
+ },
2300
+ () => currentTextId,
2301
+ (newId) => {
2302
+ currentTextId = newId;
2303
+ }
2304
+ );
2305
+ const processChunk = (chunk, controller) => {
2306
+ if (chunk.type !== "text-delta") {
2307
+ if (buffer) {
2308
+ flushText(controller);
2309
+ }
2310
+ controller.enqueue(chunk);
2311
+ return;
2312
+ }
2313
+ buffer += chunk.delta;
2314
+ processBuffer(controller);
2315
+ };
2316
+ const processBuffer = createProcessBufferHandler({
2317
+ getBuffer: () => buffer,
2318
+ setBuffer: (newBuffer) => {
2319
+ buffer = newBuffer;
2320
+ },
2321
+ getCurrentToolCall: () => currentToolCall,
2322
+ setCurrentToolCall: (newToolCall) => {
2323
+ currentToolCall = newToolCall;
2324
+ },
2325
+ tools,
2326
+ options,
2327
+ toolNames,
2328
+ maxStartTagLen,
2329
+ flushText,
2330
+ pipelineConfig,
2331
+ maxReparses
2332
+ });
2333
+ const flushBuffer2 = (controller) => {
2334
+ if (currentToolCall) {
2335
+ const unfinishedCall = `<${currentToolCall.name}>${buffer}`;
2336
+ flushText(controller, unfinishedCall);
2337
+ } else if (buffer) {
1909
2338
  flushText(controller);
1910
2339
  }
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);
1938
- }
1939
- if (currentTextId) {
1940
- controller.enqueue({ type: "text-end", id: currentTextId });
1941
- }
1942
- };
1943
- return new TransformStream({
1944
- transform(chunk, controller) {
1945
- processChunk(chunk, controller);
1946
- },
1947
- flush(controller) {
1948
- flushBuffer2(controller);
2340
+ if (currentTextId) {
2341
+ controller.enqueue({ type: "text-end", id: currentTextId });
2342
+ }
2343
+ };
2344
+ return new TransformStream({
2345
+ transform(chunk, controller) {
2346
+ processChunk(chunk, controller);
2347
+ },
2348
+ flush(controller) {
2349
+ flushBuffer2(controller);
2350
+ }
2351
+ });
2352
+ },
2353
+ extractToolCallSegments({ text, tools }) {
2354
+ const toolNames = tools.map((t) => t.name).filter(Boolean);
2355
+ if (toolNames.length === 0) {
2356
+ return [];
1949
2357
  }
1950
- });
1951
- },
1952
- extractToolCallSegments({ text, tools }) {
1953
- const toolNames = tools.map((t) => t.name).filter(Boolean);
1954
- if (toolNames.length === 0) {
1955
- return [];
2358
+ return findToolCalls(text, toolNames).map((tc) => tc.segment);
1956
2359
  }
1957
- return findToolCalls(text, toolNames).map((tc) => tc.segment);
1958
- }
1959
- });
2360
+ };
2361
+ };
1960
2362
  function getToolSchema(tools, toolName) {
1961
2363
  var _a;
1962
2364
  return (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
@@ -1989,32 +2391,22 @@ function skipSpecialSegment(text, lt) {
1989
2391
  }
1990
2392
  return gt + 1;
1991
2393
  }
1992
- function consumeClosingTag(text, lt, toolName) {
2394
+ function consumeClosingTag(text, lt, _toolName) {
1993
2395
  let p = lt + 2;
1994
- while (p < text.length && WHITESPACE_REGEX2.test(text[p])) {
2396
+ while (p < text.length && WHITESPACE_REGEX3.test(text[p])) {
1995
2397
  p += 1;
1996
2398
  }
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
2399
  const gt = text.indexOf(">", lt + 1);
2008
2400
  const endPos = gt === -1 ? text.length : gt + 1;
2009
2401
  return { matched: false, endPos };
2010
2402
  }
2011
2403
  function consumeOpenTag(text, lt) {
2012
2404
  let p = lt + 1;
2013
- while (p < text.length && WHITESPACE_REGEX2.test(text[p])) {
2405
+ while (p < text.length && WHITESPACE_REGEX3.test(text[p])) {
2014
2406
  p += 1;
2015
2407
  }
2016
2408
  const nameStart = p;
2017
- while (p < text.length && NAME_CHAR_RE.test(text.charAt(p))) {
2409
+ while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
2018
2410
  p += 1;
2019
2411
  }
2020
2412
  const name = text.slice(nameStart, p);
@@ -2023,7 +2415,7 @@ function consumeOpenTag(text, lt) {
2023
2415
  return null;
2024
2416
  }
2025
2417
  let r = q - 1;
2026
- while (r >= nameStart && WHITESPACE_REGEX2.test(text[r])) {
2418
+ while (r >= nameStart && WHITESPACE_REGEX3.test(text[r])) {
2027
2419
  r -= 1;
2028
2420
  }
2029
2421
  const selfClosing = text[r] === "/";
@@ -2052,11 +2444,11 @@ function nextTagToken(text, fromPos) {
2052
2444
  if (next === "/") {
2053
2445
  const closing = consumeClosingTag(text, lt, "");
2054
2446
  let p = lt + 2;
2055
- while (p < text.length && WHITESPACE_REGEX2.test(text[p])) {
2447
+ while (p < text.length && WHITESPACE_REGEX3.test(text[p])) {
2056
2448
  p += 1;
2057
2449
  }
2058
2450
  const nameStart = p;
2059
- while (p < text.length && NAME_CHAR_RE.test(text.charAt(p))) {
2451
+ while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
2060
2452
  p += 1;
2061
2453
  }
2062
2454
  const name = text.slice(nameStart, p);
@@ -2105,7 +2497,7 @@ function collectToolCallsFromNormalizedText(text, toolNames) {
2105
2497
  endOrig = Math.min(text.length, tagStartOrig + approxLen);
2106
2498
  }
2107
2499
  const segment = text.substring(tagStartOrig, endOrig);
2108
- const inner = (_a = (0, import_rxml.extractRawInner)(segment, toolName)) != null ? _a : segment.substring(startTag.length, segment.lastIndexOf("<"));
2500
+ const inner = (_a = (0, import_rxml2.extractRawInner)(segment, toolName)) != null ? _a : segment.substring(startTag.length, segment.lastIndexOf("<"));
2109
2501
  collected.push({
2110
2502
  toolName,
2111
2503
  startIndex: tagStartOrig,
@@ -2169,7 +2561,7 @@ function findToolCallsForName(text, toolName) {
2169
2561
  const fullTagEnd = findClosingTagEndFlexible(text, contentStart, toolName);
2170
2562
  if (fullTagEnd !== -1 && fullTagEnd > contentStart) {
2171
2563
  const segment = text.substring(tagStart, fullTagEnd);
2172
- const inner = (_a = (0, import_rxml.extractRawInner)(segment, toolName)) != null ? _a : segment.substring(startTag.length, segment.lastIndexOf("<"));
2564
+ const inner = (_a = (0, import_rxml2.extractRawInner)(segment, toolName)) != null ? _a : segment.substring(startTag.length, segment.lastIndexOf("<"));
2173
2565
  toolCalls.push({
2174
2566
  toolName,
2175
2567
  startIndex: tagStart,
@@ -2195,7 +2587,7 @@ function findToolCalls(text, toolNames) {
2195
2587
 
2196
2588
  // src/generate-handler.ts
2197
2589
  var import_provider_utils3 = require("@ai-sdk/provider-utils");
2198
- var import_rxml2 = require("@ai-sdk-tool/rxml");
2590
+ var import_rxml3 = require("@ai-sdk-tool/rxml");
2199
2591
 
2200
2592
  // src/utils/on-error.ts
2201
2593
  function extractOnErrorOption(providerOptions) {
@@ -2399,7 +2791,7 @@ function fixToolCallWithSchema(part, tools) {
2399
2791
  args = tc.input;
2400
2792
  }
2401
2793
  const schema = (_a = tools.find((t) => t.name === tc.toolName)) == null ? void 0 : _a.inputSchema;
2402
- const coerced = (0, import_rxml2.coerceBySchema)(args, schema);
2794
+ const coerced = (0, import_rxml3.coerceBySchema)(args, schema);
2403
2795
  return {
2404
2796
  ...part,
2405
2797
  input: JSON.stringify(coerced != null ? coerced : {})