@ai-sdk-tool/parser 3.0.0-canary.1 → 3.0.0-canary.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-L4X363EL.js → chunk-2B2YNKXY.js} +738 -317
- package/dist/chunk-2B2YNKXY.js.map +1 -0
- package/dist/community.cjs +731 -319
- package/dist/community.cjs.map +1 -1
- package/dist/community.js +1 -1
- package/dist/index.cjs +752 -322
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +67 -2
- package/dist/index.d.ts +67 -2
- package/dist/index.js +19 -1
- package/package.json +6 -6
- package/dist/chunk-L4X363EL.js.map +0 -1
package/dist/community.cjs
CHANGED
|
@@ -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
|
|
1144
|
+
var import_rxml2 = require("@ai-sdk-tool/rxml");
|
|
1145
1145
|
|
|
1146
|
-
// src/
|
|
1147
|
-
function
|
|
1148
|
-
|
|
1149
|
-
|
|
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
|
|
1152
|
-
|
|
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/
|
|
1156
|
-
var
|
|
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
|
|
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
|
-
|
|
1164
|
-
|
|
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
|
-
|
|
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 += "<";
|
|
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 =
|
|
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
|
|
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
|
|
1554
|
+
applySchemaProps(input, properties);
|
|
1344
1555
|
return input;
|
|
1345
1556
|
}
|
|
1346
|
-
function applySchemaProps(obj, properties
|
|
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
|
|
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
|
|
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
|
|
1583
|
+
return val.map((v) => coerceArrayItem(v, itemSchema));
|
|
1377
1584
|
}
|
|
1378
|
-
function coerceArrayItem(v, itemSchema
|
|
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
|
|
1588
|
+
const parsed = tryParseStringToSchemaObject(v, itemSchema);
|
|
1382
1589
|
if (parsed !== null) {
|
|
1383
1590
|
return parsed;
|
|
1384
1591
|
}
|
|
1385
|
-
const fallback = extractStepStatusFromString(
|
|
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
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
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
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
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
|
|
1620
|
+
return null;
|
|
1420
1621
|
}
|
|
1421
|
-
|
|
1422
|
-
|
|
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
|
|
1425
|
-
|
|
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
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
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
|
|
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
|
-
|
|
1652
|
+
let parsed = (0, import_rxml2.parse)(balanced, toolSchema, {
|
|
1457
1653
|
onError: options == null ? void 0 : options.onError,
|
|
1458
1654
|
noChildNodes: []
|
|
1459
1655
|
});
|
|
1460
|
-
|
|
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
|
|
1466
|
-
const
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
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
|
|
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,
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
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
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
2005
|
+
if (pipelineConfig) {
|
|
2006
|
+
handleStreamingToolCallEndWithPipeline({
|
|
2007
|
+
toolContent: "",
|
|
2008
|
+
currentToolCall: { name: earliestToolName, content: "" },
|
|
2009
|
+
tools,
|
|
2010
|
+
options,
|
|
2011
|
+
ctrl: controller,
|
|
2012
|
+
flushText,
|
|
2013
|
+
pipelineConfig,
|
|
2014
|
+
maxReparses
|
|
2015
|
+
});
|
|
2016
|
+
} else {
|
|
2017
|
+
handleStreamingToolCallEnd({
|
|
2018
|
+
toolContent: "",
|
|
2019
|
+
currentToolCall: { name: earliestToolName, content: "" },
|
|
2020
|
+
tools,
|
|
2021
|
+
options,
|
|
2022
|
+
ctrl: controller,
|
|
2023
|
+
flushText
|
|
2024
|
+
});
|
|
2025
|
+
}
|
|
1691
2026
|
return {
|
|
1692
2027
|
buffer: newBuffer2,
|
|
1693
2028
|
currentToolCall: null,
|
|
@@ -1751,7 +2086,9 @@ function processBufferWithToolCall(params, controller) {
|
|
|
1751
2086
|
setCurrentToolCall,
|
|
1752
2087
|
tools,
|
|
1753
2088
|
options,
|
|
1754
|
-
flushText
|
|
2089
|
+
flushText,
|
|
2090
|
+
pipelineConfig,
|
|
2091
|
+
maxReparses
|
|
1755
2092
|
} = params;
|
|
1756
2093
|
const currentToolCall = getCurrentToolCall();
|
|
1757
2094
|
if (!currentToolCall) {
|
|
@@ -1764,7 +2101,9 @@ function processBufferWithToolCall(params, controller) {
|
|
|
1764
2101
|
options,
|
|
1765
2102
|
controller,
|
|
1766
2103
|
flushText,
|
|
1767
|
-
setBuffer
|
|
2104
|
+
setBuffer,
|
|
2105
|
+
pipelineConfig,
|
|
2106
|
+
maxReparses
|
|
1768
2107
|
});
|
|
1769
2108
|
setBuffer(result.buffer);
|
|
1770
2109
|
setCurrentToolCall(result.currentToolCall);
|
|
@@ -1779,7 +2118,9 @@ function processBufferWithoutToolCall(params, controller) {
|
|
|
1779
2118
|
options,
|
|
1780
2119
|
toolNames,
|
|
1781
2120
|
maxStartTagLen,
|
|
1782
|
-
flushText
|
|
2121
|
+
flushText,
|
|
2122
|
+
pipelineConfig,
|
|
2123
|
+
maxReparses
|
|
1783
2124
|
} = params;
|
|
1784
2125
|
const result = processNoToolCallInBuffer({
|
|
1785
2126
|
buffer: getBuffer(),
|
|
@@ -1788,7 +2129,9 @@ function processBufferWithoutToolCall(params, controller) {
|
|
|
1788
2129
|
controller,
|
|
1789
2130
|
flushText,
|
|
1790
2131
|
tools,
|
|
1791
|
-
options
|
|
2132
|
+
options,
|
|
2133
|
+
pipelineConfig,
|
|
2134
|
+
maxReparses
|
|
1792
2135
|
});
|
|
1793
2136
|
setBuffer(result.buffer);
|
|
1794
2137
|
setCurrentToolCall(result.currentToolCall);
|
|
@@ -1824,139 +2167,218 @@ function createProcessBufferHandler(params) {
|
|
|
1824
2167
|
processBufferLoop(params, controller);
|
|
1825
2168
|
};
|
|
1826
2169
|
}
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
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
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
const toolNames = tools.map((t) => t.name).filter((name) => name != null);
|
|
1861
|
-
if (toolNames.length === 0) {
|
|
1862
|
-
return [{ type: "text", text }];
|
|
1863
|
-
}
|
|
1864
|
-
const processedElements = [];
|
|
1865
|
-
let currentIndex = 0;
|
|
1866
|
-
const toolCallsRaw = findToolCalls(text, toolNames);
|
|
1867
|
-
const toolCallsNorm = collectToolCallsFromNormalizedText(text, toolNames);
|
|
1868
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1869
|
-
const toolCalls = [...toolCallsRaw, ...toolCallsNorm].filter((tc) => {
|
|
1870
|
-
const key = `${tc.toolName}:${tc.startIndex}:${tc.endIndex}`;
|
|
1871
|
-
if (seen.has(key)) {
|
|
1872
|
-
return false;
|
|
1873
|
-
}
|
|
1874
|
-
seen.add(key);
|
|
1875
|
-
return true;
|
|
1876
|
-
}).sort((a, b) => a.startIndex - b.startIndex);
|
|
1877
|
-
for (const toolCall of toolCalls) {
|
|
1878
|
-
currentIndex = processTextBeforeToolCall(
|
|
1879
|
-
text,
|
|
1880
|
-
currentIndex,
|
|
1881
|
-
toolCall.startIndex,
|
|
1882
|
-
processedElements
|
|
1883
|
-
);
|
|
1884
|
-
processToolCall({ toolCall, tools, options, text, processedElements });
|
|
1885
|
-
currentIndex = toolCall.endIndex;
|
|
1886
|
-
}
|
|
1887
|
-
addRemainingText(text, currentIndex, processedElements);
|
|
1888
|
-
return processedElements;
|
|
1889
|
-
},
|
|
1890
|
-
createStreamParser({ tools, options }) {
|
|
1891
|
-
const toolNames = tools.map((t) => t.name).filter((name) => name != null);
|
|
1892
|
-
const maxStartTagLen = toolNames.length ? Math.max(...toolNames.map((n) => `<${n}>`.length)) : 0;
|
|
1893
|
-
let buffer = "";
|
|
1894
|
-
let currentToolCall = null;
|
|
1895
|
-
let currentTextId = null;
|
|
1896
|
-
const flushText = createFlushTextHandler(
|
|
1897
|
-
() => buffer,
|
|
1898
|
-
(newBuffer) => {
|
|
1899
|
-
buffer = newBuffer;
|
|
1900
|
-
},
|
|
1901
|
-
() => currentTextId,
|
|
1902
|
-
(newId) => {
|
|
1903
|
-
currentTextId = newId;
|
|
2229
|
+
return (0, import_rxml2.stringify)(toolCall.toolName, args, {
|
|
2230
|
+
suppressEmptyNode: false,
|
|
2231
|
+
format: false
|
|
2232
|
+
});
|
|
2233
|
+
},
|
|
2234
|
+
formatToolResponse(toolResult) {
|
|
2235
|
+
return (0, import_rxml2.stringify)("tool_response", {
|
|
2236
|
+
tool_name: toolResult.toolName,
|
|
2237
|
+
result: toolResult.output
|
|
2238
|
+
});
|
|
2239
|
+
},
|
|
2240
|
+
parseGeneratedText({ text, tools, options }) {
|
|
2241
|
+
const toolNames = tools.map((t) => t.name).filter((name) => name != null);
|
|
2242
|
+
if (toolNames.length === 0) {
|
|
2243
|
+
return [{ type: "text", text }];
|
|
1904
2244
|
}
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
2245
|
+
const processedElements = [];
|
|
2246
|
+
let currentIndex = 0;
|
|
2247
|
+
const toolCallsRaw = findToolCalls(text, toolNames);
|
|
2248
|
+
const toolCallsNorm = collectToolCallsFromNormalizedText(text, toolNames);
|
|
2249
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2250
|
+
const toolCalls = [...toolCallsRaw, ...toolCallsNorm].filter((tc) => {
|
|
2251
|
+
const key = `${tc.toolName}:${tc.startIndex}:${tc.endIndex}`;
|
|
2252
|
+
if (seen.has(key)) {
|
|
2253
|
+
return false;
|
|
1910
2254
|
}
|
|
1911
|
-
|
|
1912
|
-
return;
|
|
1913
|
-
}
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
if (currentToolCall) {
|
|
1934
|
-
const unfinishedCall = `<${currentToolCall.name}>${buffer}`;
|
|
1935
|
-
flushText(controller, unfinishedCall);
|
|
1936
|
-
} else if (buffer) {
|
|
1937
|
-
flushText(controller);
|
|
2255
|
+
seen.add(key);
|
|
2256
|
+
return true;
|
|
2257
|
+
}).sort((a, b) => a.startIndex - b.startIndex);
|
|
2258
|
+
if (process.env.DEBUG_PARSER_OUTPUT === "true") {
|
|
2259
|
+
console.log("\n=== PARSER DEBUG ===");
|
|
2260
|
+
console.log(`Available tools: ${toolNames.join(", ")}`);
|
|
2261
|
+
console.log(`Full text length: ${text.length}`);
|
|
2262
|
+
console.log(`Full text:
|
|
2263
|
+
${text}
|
|
2264
|
+
`);
|
|
2265
|
+
console.log(`Tool calls found: ${toolCalls.length}`);
|
|
2266
|
+
for (let i = 0; i < toolCalls.length; i++) {
|
|
2267
|
+
const tc = toolCalls[i];
|
|
2268
|
+
console.log(`
|
|
2269
|
+
[Tool Call ${i + 1}] ${tc.toolName}`);
|
|
2270
|
+
console.log(`Position: ${tc.startIndex} - ${tc.endIndex}`);
|
|
2271
|
+
console.log(`Segment:
|
|
2272
|
+
${tc.segment}`);
|
|
2273
|
+
console.log(`Content:
|
|
2274
|
+
${tc.content}`);
|
|
2275
|
+
}
|
|
2276
|
+
console.log("===================\n");
|
|
1938
2277
|
}
|
|
1939
|
-
|
|
1940
|
-
|
|
2278
|
+
for (const toolCall of toolCalls) {
|
|
2279
|
+
currentIndex = processTextBeforeToolCall(
|
|
2280
|
+
text,
|
|
2281
|
+
currentIndex,
|
|
2282
|
+
toolCall.startIndex,
|
|
2283
|
+
processedElements
|
|
2284
|
+
);
|
|
2285
|
+
if (pipelineConfig) {
|
|
2286
|
+
processToolCallWithPipeline({
|
|
2287
|
+
toolCall,
|
|
2288
|
+
tools,
|
|
2289
|
+
options,
|
|
2290
|
+
text,
|
|
2291
|
+
processedElements,
|
|
2292
|
+
pipelineConfig,
|
|
2293
|
+
maxReparses
|
|
2294
|
+
});
|
|
2295
|
+
} else {
|
|
2296
|
+
processToolCall({
|
|
2297
|
+
toolCall,
|
|
2298
|
+
tools,
|
|
2299
|
+
options,
|
|
2300
|
+
text,
|
|
2301
|
+
processedElements
|
|
2302
|
+
});
|
|
2303
|
+
}
|
|
2304
|
+
currentIndex = toolCall.endIndex;
|
|
1941
2305
|
}
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
2306
|
+
addRemainingText(text, currentIndex, processedElements);
|
|
2307
|
+
return processedElements;
|
|
2308
|
+
},
|
|
2309
|
+
createStreamParser({ tools, options }) {
|
|
2310
|
+
const toolNames = tools.map((t) => t.name).filter((name) => name != null);
|
|
2311
|
+
const maxStartTagLen = toolNames.length ? Math.max(...toolNames.map((n) => `<${n}>`.length)) : 0;
|
|
2312
|
+
let buffer = "";
|
|
2313
|
+
let currentToolCall = null;
|
|
2314
|
+
let currentTextId = null;
|
|
2315
|
+
const flushText = createFlushTextHandler(
|
|
2316
|
+
() => buffer,
|
|
2317
|
+
(newBuffer) => {
|
|
2318
|
+
buffer = newBuffer;
|
|
2319
|
+
},
|
|
2320
|
+
() => currentTextId,
|
|
2321
|
+
(newId) => {
|
|
2322
|
+
currentTextId = newId;
|
|
2323
|
+
}
|
|
2324
|
+
);
|
|
2325
|
+
const processChunk = (chunk, controller) => {
|
|
2326
|
+
if (chunk.type !== "text-delta") {
|
|
2327
|
+
if (buffer) {
|
|
2328
|
+
flushText(controller);
|
|
2329
|
+
}
|
|
2330
|
+
controller.enqueue(chunk);
|
|
2331
|
+
return;
|
|
2332
|
+
}
|
|
2333
|
+
buffer += chunk.delta;
|
|
2334
|
+
processBuffer(controller);
|
|
2335
|
+
};
|
|
2336
|
+
const processBuffer = createProcessBufferHandler({
|
|
2337
|
+
getBuffer: () => buffer,
|
|
2338
|
+
setBuffer: (newBuffer) => {
|
|
2339
|
+
buffer = newBuffer;
|
|
2340
|
+
},
|
|
2341
|
+
getCurrentToolCall: () => currentToolCall,
|
|
2342
|
+
setCurrentToolCall: (newToolCall) => {
|
|
2343
|
+
currentToolCall = newToolCall;
|
|
2344
|
+
},
|
|
2345
|
+
tools,
|
|
2346
|
+
options,
|
|
2347
|
+
toolNames,
|
|
2348
|
+
maxStartTagLen,
|
|
2349
|
+
flushText,
|
|
2350
|
+
pipelineConfig,
|
|
2351
|
+
maxReparses
|
|
2352
|
+
});
|
|
2353
|
+
const flushBuffer2 = (controller) => {
|
|
2354
|
+
if (currentToolCall) {
|
|
2355
|
+
const unfinishedCall = `<${currentToolCall.name}>${buffer}`;
|
|
2356
|
+
flushText(controller, unfinishedCall);
|
|
2357
|
+
} else if (buffer) {
|
|
2358
|
+
flushText(controller);
|
|
2359
|
+
}
|
|
2360
|
+
if (currentTextId) {
|
|
2361
|
+
controller.enqueue({ type: "text-end", id: currentTextId });
|
|
2362
|
+
}
|
|
2363
|
+
};
|
|
2364
|
+
return new TransformStream({
|
|
2365
|
+
transform(chunk, controller) {
|
|
2366
|
+
processChunk(chunk, controller);
|
|
2367
|
+
},
|
|
2368
|
+
flush(controller) {
|
|
2369
|
+
flushBuffer2(controller);
|
|
2370
|
+
}
|
|
2371
|
+
});
|
|
2372
|
+
},
|
|
2373
|
+
extractToolCallSegments({ text, tools }) {
|
|
2374
|
+
const toolNames = tools.map((t) => t.name).filter(Boolean);
|
|
2375
|
+
if (toolNames.length === 0) {
|
|
2376
|
+
return [];
|
|
1949
2377
|
}
|
|
1950
|
-
|
|
1951
|
-
},
|
|
1952
|
-
extractToolCallSegments({ text, tools }) {
|
|
1953
|
-
const toolNames = tools.map((t) => t.name).filter(Boolean);
|
|
1954
|
-
if (toolNames.length === 0) {
|
|
1955
|
-
return [];
|
|
2378
|
+
return findToolCalls(text, toolNames).map((tc) => tc.segment);
|
|
1956
2379
|
}
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
});
|
|
2380
|
+
};
|
|
2381
|
+
};
|
|
1960
2382
|
function getToolSchema(tools, toolName) {
|
|
1961
2383
|
var _a;
|
|
1962
2384
|
return (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
|
|
@@ -1989,32 +2411,22 @@ function skipSpecialSegment(text, lt) {
|
|
|
1989
2411
|
}
|
|
1990
2412
|
return gt + 1;
|
|
1991
2413
|
}
|
|
1992
|
-
function consumeClosingTag(text, lt,
|
|
2414
|
+
function consumeClosingTag(text, lt, _toolName) {
|
|
1993
2415
|
let p = lt + 2;
|
|
1994
|
-
while (p < text.length &&
|
|
2416
|
+
while (p < text.length && WHITESPACE_REGEX3.test(text[p])) {
|
|
1995
2417
|
p += 1;
|
|
1996
2418
|
}
|
|
1997
|
-
if (text.slice(p, p + toolName.length) === toolName) {
|
|
1998
|
-
p += toolName.length;
|
|
1999
|
-
while (p < text.length && WHITESPACE_REGEX2.test(text[p])) {
|
|
2000
|
-
p += 1;
|
|
2001
|
-
}
|
|
2002
|
-
if (text[p] === ">") {
|
|
2003
|
-
const endPos2 = p + 1;
|
|
2004
|
-
return { matched: true, endPos: endPos2 };
|
|
2005
|
-
}
|
|
2006
|
-
}
|
|
2007
2419
|
const gt = text.indexOf(">", lt + 1);
|
|
2008
2420
|
const endPos = gt === -1 ? text.length : gt + 1;
|
|
2009
2421
|
return { matched: false, endPos };
|
|
2010
2422
|
}
|
|
2011
2423
|
function consumeOpenTag(text, lt) {
|
|
2012
2424
|
let p = lt + 1;
|
|
2013
|
-
while (p < text.length &&
|
|
2425
|
+
while (p < text.length && WHITESPACE_REGEX3.test(text[p])) {
|
|
2014
2426
|
p += 1;
|
|
2015
2427
|
}
|
|
2016
2428
|
const nameStart = p;
|
|
2017
|
-
while (p < text.length &&
|
|
2429
|
+
while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
|
|
2018
2430
|
p += 1;
|
|
2019
2431
|
}
|
|
2020
2432
|
const name = text.slice(nameStart, p);
|
|
@@ -2023,7 +2435,7 @@ function consumeOpenTag(text, lt) {
|
|
|
2023
2435
|
return null;
|
|
2024
2436
|
}
|
|
2025
2437
|
let r = q - 1;
|
|
2026
|
-
while (r >= nameStart &&
|
|
2438
|
+
while (r >= nameStart && WHITESPACE_REGEX3.test(text[r])) {
|
|
2027
2439
|
r -= 1;
|
|
2028
2440
|
}
|
|
2029
2441
|
const selfClosing = text[r] === "/";
|
|
@@ -2052,11 +2464,11 @@ function nextTagToken(text, fromPos) {
|
|
|
2052
2464
|
if (next === "/") {
|
|
2053
2465
|
const closing = consumeClosingTag(text, lt, "");
|
|
2054
2466
|
let p = lt + 2;
|
|
2055
|
-
while (p < text.length &&
|
|
2467
|
+
while (p < text.length && WHITESPACE_REGEX3.test(text[p])) {
|
|
2056
2468
|
p += 1;
|
|
2057
2469
|
}
|
|
2058
2470
|
const nameStart = p;
|
|
2059
|
-
while (p < text.length &&
|
|
2471
|
+
while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
|
|
2060
2472
|
p += 1;
|
|
2061
2473
|
}
|
|
2062
2474
|
const name = text.slice(nameStart, p);
|
|
@@ -2105,7 +2517,7 @@ function collectToolCallsFromNormalizedText(text, toolNames) {
|
|
|
2105
2517
|
endOrig = Math.min(text.length, tagStartOrig + approxLen);
|
|
2106
2518
|
}
|
|
2107
2519
|
const segment = text.substring(tagStartOrig, endOrig);
|
|
2108
|
-
const inner = (_a = (0,
|
|
2520
|
+
const inner = (_a = (0, import_rxml2.extractRawInner)(segment, toolName)) != null ? _a : segment.substring(startTag.length, segment.lastIndexOf("<"));
|
|
2109
2521
|
collected.push({
|
|
2110
2522
|
toolName,
|
|
2111
2523
|
startIndex: tagStartOrig,
|
|
@@ -2169,7 +2581,7 @@ function findToolCallsForName(text, toolName) {
|
|
|
2169
2581
|
const fullTagEnd = findClosingTagEndFlexible(text, contentStart, toolName);
|
|
2170
2582
|
if (fullTagEnd !== -1 && fullTagEnd > contentStart) {
|
|
2171
2583
|
const segment = text.substring(tagStart, fullTagEnd);
|
|
2172
|
-
const inner = (_a = (0,
|
|
2584
|
+
const inner = (_a = (0, import_rxml2.extractRawInner)(segment, toolName)) != null ? _a : segment.substring(startTag.length, segment.lastIndexOf("<"));
|
|
2173
2585
|
toolCalls.push({
|
|
2174
2586
|
toolName,
|
|
2175
2587
|
startIndex: tagStart,
|
|
@@ -2195,7 +2607,7 @@ function findToolCalls(text, toolNames) {
|
|
|
2195
2607
|
|
|
2196
2608
|
// src/generate-handler.ts
|
|
2197
2609
|
var import_provider_utils3 = require("@ai-sdk/provider-utils");
|
|
2198
|
-
var
|
|
2610
|
+
var import_rxml3 = require("@ai-sdk-tool/rxml");
|
|
2199
2611
|
|
|
2200
2612
|
// src/utils/on-error.ts
|
|
2201
2613
|
function extractOnErrorOption(providerOptions) {
|
|
@@ -2399,7 +2811,7 @@ function fixToolCallWithSchema(part, tools) {
|
|
|
2399
2811
|
args = tc.input;
|
|
2400
2812
|
}
|
|
2401
2813
|
const schema = (_a = tools.find((t) => t.name === tc.toolName)) == null ? void 0 : _a.inputSchema;
|
|
2402
|
-
const coerced = (0,
|
|
2814
|
+
const coerced = (0, import_rxml3.coerceBySchema)(args, schema);
|
|
2403
2815
|
return {
|
|
2404
2816
|
...part,
|
|
2405
2817
|
input: JSON.stringify(coerced != null ? coerced : {})
|