@ai-sdk-tool/parser 3.0.0-canary.0 → 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.
- package/dist/{chunk-FOANBZRH.js → chunk-LB5ALTRD.js} +1510 -455
- package/dist/chunk-LB5ALTRD.js.map +1 -0
- package/dist/community.cjs +1499 -474
- package/dist/community.cjs.map +1 -1
- package/dist/community.js +2 -2
- package/dist/community.js.map +1 -1
- package/dist/index.cjs +1529 -458
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +87 -23
- package/dist/index.d.ts +87 -23
- package/dist/index.js +21 -3
- package/package.json +23 -16
- package/dist/chunk-FOANBZRH.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -20,11 +20,16 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var src_exports = {};
|
|
22
22
|
__export(src_exports, {
|
|
23
|
-
|
|
23
|
+
applyHeuristicPipeline: () => applyHeuristicPipeline,
|
|
24
|
+
balanceTagsHeuristic: () => balanceTagsHeuristic,
|
|
24
25
|
createDynamicIfThenElseSchema: () => createDynamicIfThenElseSchema,
|
|
26
|
+
createIntermediateCall: () => createIntermediateCall,
|
|
25
27
|
createToolMiddleware: () => createToolMiddleware,
|
|
26
28
|
decodeOriginalTools: () => decodeOriginalTools,
|
|
29
|
+
dedupeShellStringTagsHeuristic: () => dedupeShellStringTagsHeuristic,
|
|
30
|
+
defaultPipelineConfig: () => defaultPipelineConfig,
|
|
27
31
|
encodeOriginalTools: () => encodeOriginalTools,
|
|
32
|
+
escapeInvalidLtHeuristic: () => escapeInvalidLtHeuristic,
|
|
28
33
|
escapeRegExp: () => escapeRegExp,
|
|
29
34
|
extractOnErrorOption: () => extractOnErrorOption,
|
|
30
35
|
extractToolNamesFromOriginalTools: () => extractToolNamesFromOriginalTools,
|
|
@@ -37,23 +42,24 @@ __export(src_exports, {
|
|
|
37
42
|
isToolChoiceActive: () => isToolChoiceActive,
|
|
38
43
|
isToolResultPart: () => isToolResultPart,
|
|
39
44
|
jsonMixProtocol: () => jsonMixProtocol,
|
|
45
|
+
logParseFailure: () => logParseFailure,
|
|
40
46
|
logParsedChunk: () => logParsedChunk,
|
|
41
47
|
logParsedSummary: () => logParsedSummary,
|
|
42
48
|
logRawChunk: () => logRawChunk,
|
|
49
|
+
mergePipelineConfigs: () => mergePipelineConfigs,
|
|
43
50
|
morphXmlProtocol: () => morphXmlProtocol,
|
|
44
51
|
morphXmlToolMiddleware: () => morphXmlToolMiddleware,
|
|
52
|
+
normalizeCloseTagsHeuristic: () => normalizeCloseTagsHeuristic,
|
|
45
53
|
originalToolsSchema: () => originalToolsSchema,
|
|
46
54
|
parseRJSON: () => parse,
|
|
55
|
+
repairAgainstSchemaHeuristic: () => repairAgainstSchemaHeuristic,
|
|
47
56
|
stringifyRJSON: () => stringify,
|
|
48
57
|
transformRJSON: () => transform
|
|
49
58
|
});
|
|
50
59
|
module.exports = __toCommonJS(src_exports);
|
|
51
60
|
|
|
52
|
-
// src/protocols/dummy-protocol.ts
|
|
53
|
-
var import_provider_utils = require("@ai-sdk/provider-utils");
|
|
54
|
-
|
|
55
61
|
// src/protocols/json-mix-protocol.ts
|
|
56
|
-
var
|
|
62
|
+
var import_provider_utils = require("@ai-sdk/provider-utils");
|
|
57
63
|
|
|
58
64
|
// src/utils/debug.ts
|
|
59
65
|
var LINE_SPLIT_REGEX = /\r?\n/;
|
|
@@ -101,6 +107,7 @@ var cBgGreen = color(ANSI_BG_GREEN);
|
|
|
101
107
|
var cInverse = color(ANSI_INVERSE);
|
|
102
108
|
var cUnderline = color(ANSI_UNDERLINE);
|
|
103
109
|
var cBold = color(ANSI_BOLD);
|
|
110
|
+
var MAX_SNIPPET_LENGTH = 800;
|
|
104
111
|
function safeStringify(value) {
|
|
105
112
|
try {
|
|
106
113
|
return `
|
|
@@ -109,6 +116,41 @@ ${typeof value === "string" ? value : JSON.stringify(value, null, 2)}`;
|
|
|
109
116
|
return String(value);
|
|
110
117
|
}
|
|
111
118
|
}
|
|
119
|
+
function formatError(error) {
|
|
120
|
+
if (error instanceof Error) {
|
|
121
|
+
const stack = error.stack ? `
|
|
122
|
+
${error.stack}` : "";
|
|
123
|
+
return `
|
|
124
|
+
${error.name}: ${error.message}${stack}`;
|
|
125
|
+
}
|
|
126
|
+
return safeStringify(error);
|
|
127
|
+
}
|
|
128
|
+
function truncateSnippet(snippet) {
|
|
129
|
+
if (snippet.length <= MAX_SNIPPET_LENGTH) {
|
|
130
|
+
return snippet;
|
|
131
|
+
}
|
|
132
|
+
return `${snippet.slice(0, MAX_SNIPPET_LENGTH)}
|
|
133
|
+
\u2026[truncated ${snippet.length - MAX_SNIPPET_LENGTH} chars]`;
|
|
134
|
+
}
|
|
135
|
+
function logParseFailure({
|
|
136
|
+
phase,
|
|
137
|
+
reason,
|
|
138
|
+
snippet,
|
|
139
|
+
error
|
|
140
|
+
}) {
|
|
141
|
+
if (getDebugLevel() !== "parse") {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const label = cBgBlue(`[${phase}]`);
|
|
145
|
+
console.log(cGray("[debug:mw:fail]"), label, cYellow(reason));
|
|
146
|
+
if (snippet) {
|
|
147
|
+
const formatted = truncateSnippet(snippet);
|
|
148
|
+
console.log(cGray("[debug:mw:fail:snippet]"), formatted);
|
|
149
|
+
}
|
|
150
|
+
if (error) {
|
|
151
|
+
console.log(cGray("[debug:mw:fail:error]"), cCyan(formatError(error)));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
112
154
|
function logRawChunk(part) {
|
|
113
155
|
console.log(cGray("[debug:mw:raw]"), cYellow(safeStringify(part)));
|
|
114
156
|
}
|
|
@@ -174,63 +216,6 @@ ${rendered}`);
|
|
|
174
216
|
}
|
|
175
217
|
}
|
|
176
218
|
|
|
177
|
-
// src/utils/dynamic-tool-schema.ts
|
|
178
|
-
function createDynamicIfThenElseSchema(tools) {
|
|
179
|
-
let currentSchema = {};
|
|
180
|
-
const toolNames = [];
|
|
181
|
-
for (let i = tools.length - 1; i >= 0; i -= 1) {
|
|
182
|
-
const tool = tools[i];
|
|
183
|
-
if (tool.type === "provider-defined") {
|
|
184
|
-
throw new Error(
|
|
185
|
-
"Provider-defined tools are not supported by this middleware. Please use custom tools."
|
|
186
|
-
);
|
|
187
|
-
}
|
|
188
|
-
toolNames.unshift(tool.name);
|
|
189
|
-
const toolCondition = {
|
|
190
|
-
if: {
|
|
191
|
-
properties: {
|
|
192
|
-
name: {
|
|
193
|
-
const: tool.name
|
|
194
|
-
}
|
|
195
|
-
},
|
|
196
|
-
required: ["name"]
|
|
197
|
-
},
|
|
198
|
-
// biome-ignore lint/suspicious/noThenProperty: JSON Schema uses 'then' as a keyword
|
|
199
|
-
then: {
|
|
200
|
-
properties: {
|
|
201
|
-
name: {
|
|
202
|
-
const: tool.name
|
|
203
|
-
},
|
|
204
|
-
arguments: tool.inputSchema
|
|
205
|
-
},
|
|
206
|
-
required: ["name", "arguments"]
|
|
207
|
-
}
|
|
208
|
-
};
|
|
209
|
-
if (Object.keys(currentSchema).length > 0) {
|
|
210
|
-
toolCondition.else = currentSchema;
|
|
211
|
-
}
|
|
212
|
-
currentSchema = toolCondition;
|
|
213
|
-
}
|
|
214
|
-
return {
|
|
215
|
-
type: "object",
|
|
216
|
-
// Explicitly specify type as "object"
|
|
217
|
-
properties: {
|
|
218
|
-
name: {
|
|
219
|
-
type: "string",
|
|
220
|
-
description: "Name of the tool to call",
|
|
221
|
-
enum: toolNames
|
|
222
|
-
},
|
|
223
|
-
arguments: {
|
|
224
|
-
type: "object",
|
|
225
|
-
// By default, arguments is also specified as object type
|
|
226
|
-
description: "Argument object to be passed to the tool"
|
|
227
|
-
}
|
|
228
|
-
},
|
|
229
|
-
required: ["name", "arguments"],
|
|
230
|
-
...currentSchema
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
|
|
234
219
|
// src/utils/get-potential-start-index.ts
|
|
235
220
|
function getPotentialStartIndex(text, searchedText) {
|
|
236
221
|
if (searchedText.length === 0) {
|
|
@@ -249,60 +234,12 @@ function getPotentialStartIndex(text, searchedText) {
|
|
|
249
234
|
return null;
|
|
250
235
|
}
|
|
251
236
|
|
|
252
|
-
// src/utils/on-error.ts
|
|
253
|
-
function extractOnErrorOption(providerOptions) {
|
|
254
|
-
var _a;
|
|
255
|
-
if (providerOptions && typeof providerOptions === "object") {
|
|
256
|
-
const onError = (_a = providerOptions.toolCallMiddleware) == null ? void 0 : _a.onError;
|
|
257
|
-
return onError ? { onError } : void 0;
|
|
258
|
-
}
|
|
259
|
-
return;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// src/utils/provider-options.ts
|
|
263
|
-
var originalToolsSchema = {
|
|
264
|
-
encode: encodeOriginalTools,
|
|
265
|
-
decode: decodeOriginalTools
|
|
266
|
-
};
|
|
267
|
-
function encodeOriginalTools(tools) {
|
|
268
|
-
return (tools == null ? void 0 : tools.map((t) => ({
|
|
269
|
-
name: t.name,
|
|
270
|
-
inputSchema: JSON.stringify(t.inputSchema)
|
|
271
|
-
}))) || [];
|
|
272
|
-
}
|
|
273
|
-
function decodeOriginalTools(originalTools) {
|
|
274
|
-
if (!originalTools) {
|
|
275
|
-
return [];
|
|
276
|
-
}
|
|
277
|
-
return originalTools.map(
|
|
278
|
-
(t) => ({
|
|
279
|
-
type: "function",
|
|
280
|
-
name: t.name,
|
|
281
|
-
inputSchema: JSON.parse(t.inputSchema)
|
|
282
|
-
})
|
|
283
|
-
);
|
|
284
|
-
}
|
|
285
|
-
function extractToolNamesFromOriginalTools(originalTools) {
|
|
286
|
-
return (originalTools == null ? void 0 : originalTools.map((t) => t.name)) || [];
|
|
287
|
-
}
|
|
288
|
-
function isToolChoiceActive(params) {
|
|
289
|
-
var _a, _b, _c;
|
|
290
|
-
const toolChoice = (_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.toolChoice;
|
|
291
|
-
return !!(typeof params.providerOptions === "object" && params.providerOptions !== null && typeof ((_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware) === "object" && toolChoice && typeof toolChoice === "object" && (toolChoice.type === "tool" || toolChoice.type === "required"));
|
|
292
|
-
}
|
|
293
|
-
|
|
294
237
|
// src/utils/regex.ts
|
|
295
238
|
function escapeRegExp(literal) {
|
|
296
239
|
return literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
297
240
|
}
|
|
298
241
|
|
|
299
242
|
// src/utils/robust-json.ts
|
|
300
|
-
var robust_json_exports = {};
|
|
301
|
-
__export(robust_json_exports, {
|
|
302
|
-
parse: () => parse,
|
|
303
|
-
stringify: () => stringify,
|
|
304
|
-
transform: () => transform
|
|
305
|
-
});
|
|
306
243
|
var WHITESPACE_TEST_REGEX = /\s/;
|
|
307
244
|
var WHITESPACE_REGEX = /^\s+/;
|
|
308
245
|
var OBJECT_START_REGEX = /^\{/;
|
|
@@ -967,19 +904,6 @@ function stringify(obj) {
|
|
|
967
904
|
return "null";
|
|
968
905
|
}
|
|
969
906
|
|
|
970
|
-
// src/utils/type-guards.ts
|
|
971
|
-
function isToolCallContent(content) {
|
|
972
|
-
return content.type === "tool-call" && typeof content.toolName === "string" && // input may be a JSON string or an already-parsed object depending on provider/runtime
|
|
973
|
-
(typeof content.input === "string" || typeof content.input === "object");
|
|
974
|
-
}
|
|
975
|
-
function isToolResultPart(content) {
|
|
976
|
-
const c = content;
|
|
977
|
-
return !!c && c.type === "tool-result" && typeof c.toolName === "string" && typeof c.toolCallId === "string" && "output" in c;
|
|
978
|
-
}
|
|
979
|
-
function hasInputProperty(obj) {
|
|
980
|
-
return typeof obj === "object" && obj !== null && "input" in obj;
|
|
981
|
-
}
|
|
982
|
-
|
|
983
907
|
// src/protocols/json-mix-protocol.ts
|
|
984
908
|
function processToolCallJson(toolCallJson, fullMatch, processedElements, options) {
|
|
985
909
|
var _a;
|
|
@@ -987,11 +911,17 @@ function processToolCallJson(toolCallJson, fullMatch, processedElements, options
|
|
|
987
911
|
const parsedToolCall = parse(toolCallJson);
|
|
988
912
|
processedElements.push({
|
|
989
913
|
type: "tool-call",
|
|
990
|
-
toolCallId: (0,
|
|
914
|
+
toolCallId: (0, import_provider_utils.generateId)(),
|
|
991
915
|
toolName: parsedToolCall.name,
|
|
992
916
|
input: JSON.stringify((_a = parsedToolCall.arguments) != null ? _a : {})
|
|
993
917
|
});
|
|
994
918
|
} catch (error) {
|
|
919
|
+
logParseFailure({
|
|
920
|
+
phase: "generated-text",
|
|
921
|
+
reason: "Failed to parse tool call JSON segment",
|
|
922
|
+
snippet: fullMatch,
|
|
923
|
+
error
|
|
924
|
+
});
|
|
995
925
|
if (options == null ? void 0 : options.onError) {
|
|
996
926
|
options.onError(
|
|
997
927
|
"Could not process JSON tool call, keeping original text.",
|
|
@@ -1024,7 +954,7 @@ function flushBuffer(state, controller, toolCallStart) {
|
|
|
1024
954
|
return;
|
|
1025
955
|
}
|
|
1026
956
|
if (!state.currentTextId) {
|
|
1027
|
-
state.currentTextId = (0,
|
|
957
|
+
state.currentTextId = (0, import_provider_utils.generateId)();
|
|
1028
958
|
controller.enqueue({ type: "text-start", id: state.currentTextId });
|
|
1029
959
|
state.hasEmittedTextStart = true;
|
|
1030
960
|
}
|
|
@@ -1047,7 +977,12 @@ function emitIncompleteToolCall(state, controller, toolCallStart) {
|
|
|
1047
977
|
if (!state.currentToolCallJson) {
|
|
1048
978
|
return;
|
|
1049
979
|
}
|
|
1050
|
-
|
|
980
|
+
logParseFailure({
|
|
981
|
+
phase: "stream",
|
|
982
|
+
reason: "Incomplete streaming tool call segment emitted as text",
|
|
983
|
+
snippet: `${toolCallStart}${state.currentToolCallJson}`
|
|
984
|
+
});
|
|
985
|
+
const errorId = (0, import_provider_utils.generateId)();
|
|
1051
986
|
controller.enqueue({ type: "text-start", id: errorId });
|
|
1052
987
|
controller.enqueue({
|
|
1053
988
|
type: "text-delta",
|
|
@@ -1071,7 +1006,7 @@ function publishText(text, state, controller) {
|
|
|
1071
1006
|
state.currentToolCallJson += text;
|
|
1072
1007
|
} else if (text.length > 0) {
|
|
1073
1008
|
if (!state.currentTextId) {
|
|
1074
|
-
state.currentTextId = (0,
|
|
1009
|
+
state.currentTextId = (0, import_provider_utils.generateId)();
|
|
1075
1010
|
controller.enqueue({ type: "text-start", id: state.currentTextId });
|
|
1076
1011
|
state.hasEmittedTextStart = true;
|
|
1077
1012
|
}
|
|
@@ -1086,16 +1021,22 @@ function emitToolCall(context) {
|
|
|
1086
1021
|
var _a;
|
|
1087
1022
|
const { state, controller, toolCallStart, toolCallEnd, options } = context;
|
|
1088
1023
|
try {
|
|
1089
|
-
const parsedToolCall =
|
|
1024
|
+
const parsedToolCall = parse(state.currentToolCallJson);
|
|
1090
1025
|
closeTextBlock(state, controller);
|
|
1091
1026
|
controller.enqueue({
|
|
1092
1027
|
type: "tool-call",
|
|
1093
|
-
toolCallId: (0,
|
|
1028
|
+
toolCallId: (0, import_provider_utils.generateId)(),
|
|
1094
1029
|
toolName: parsedToolCall.name,
|
|
1095
1030
|
input: JSON.stringify((_a = parsedToolCall.arguments) != null ? _a : {})
|
|
1096
1031
|
});
|
|
1097
|
-
} catch (
|
|
1098
|
-
|
|
1032
|
+
} catch (error) {
|
|
1033
|
+
logParseFailure({
|
|
1034
|
+
phase: "stream",
|
|
1035
|
+
reason: "Failed to parse streaming tool call JSON segment",
|
|
1036
|
+
snippet: `${toolCallStart}${state.currentToolCallJson}${toolCallEnd}`,
|
|
1037
|
+
error
|
|
1038
|
+
});
|
|
1039
|
+
const errorId = (0, import_provider_utils.generateId)();
|
|
1099
1040
|
controller.enqueue({ type: "text-start", id: errorId });
|
|
1100
1041
|
controller.enqueue({
|
|
1101
1042
|
type: "text-delta",
|
|
@@ -1260,162 +1201,900 @@ var jsonMixProtocol = ({
|
|
|
1260
1201
|
});
|
|
1261
1202
|
|
|
1262
1203
|
// src/protocols/morph-xml-protocol.ts
|
|
1263
|
-
var
|
|
1264
|
-
var
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
processedElements.push({ type: "text", text: textSegment });
|
|
1271
|
-
}
|
|
1204
|
+
var import_provider_utils2 = require("@ai-sdk/provider-utils");
|
|
1205
|
+
var import_rxml2 = require("@ai-sdk-tool/rxml");
|
|
1206
|
+
|
|
1207
|
+
// src/heuristics/engine.ts
|
|
1208
|
+
function applyRawSegmentUpdate(current, result) {
|
|
1209
|
+
if (result.rawSegment !== void 0) {
|
|
1210
|
+
return { ...current, rawSegment: result.rawSegment };
|
|
1272
1211
|
}
|
|
1273
|
-
return
|
|
1212
|
+
return current;
|
|
1274
1213
|
}
|
|
1275
|
-
function
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
try {
|
|
1279
|
-
const toolSchema = getToolSchema(tools, toolCall.toolName);
|
|
1280
|
-
const parsed = (0, import_rxml.parse)(toolCall.content, toolSchema, {
|
|
1281
|
-
onError: options == null ? void 0 : options.onError,
|
|
1282
|
-
// Disable HTML self-closing tag behavior to allow base, meta, link etc. as regular tags
|
|
1283
|
-
noChildNodes: []
|
|
1284
|
-
});
|
|
1285
|
-
processedElements.push({
|
|
1286
|
-
type: "tool-call",
|
|
1287
|
-
toolCallId: (0, import_provider_utils3.generateId)(),
|
|
1288
|
-
toolName: toolCall.toolName,
|
|
1289
|
-
input: JSON.stringify(parsed)
|
|
1290
|
-
});
|
|
1291
|
-
} catch (error) {
|
|
1292
|
-
const originalCallText = text.substring(
|
|
1293
|
-
toolCall.startIndex,
|
|
1294
|
-
toolCall.endIndex
|
|
1295
|
-
);
|
|
1296
|
-
const message = `Could not process XML tool call, keeping original text: ${originalCallText}`;
|
|
1297
|
-
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, message, {
|
|
1298
|
-
toolCall: originalCallText,
|
|
1299
|
-
toolName: toolCall.toolName,
|
|
1300
|
-
error
|
|
1301
|
-
});
|
|
1302
|
-
processedElements.push({ type: "text", text: originalCallText });
|
|
1214
|
+
function applyParsedUpdate(current, result) {
|
|
1215
|
+
if (result.parsed !== void 0) {
|
|
1216
|
+
return { ...current, parsed: result.parsed };
|
|
1303
1217
|
}
|
|
1218
|
+
return current;
|
|
1304
1219
|
}
|
|
1305
|
-
function
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1220
|
+
function applyWarningsUpdate(current, result) {
|
|
1221
|
+
var _a, _b;
|
|
1222
|
+
if (result.warnings && result.warnings.length > 0) {
|
|
1223
|
+
const meta = (_a = current.meta) != null ? _a : {};
|
|
1224
|
+
const existingWarnings = (_b = meta.warnings) != null ? _b : [];
|
|
1225
|
+
return {
|
|
1226
|
+
...current,
|
|
1227
|
+
meta: { ...meta, warnings: [...existingWarnings, ...result.warnings] }
|
|
1228
|
+
};
|
|
1311
1229
|
}
|
|
1230
|
+
return current;
|
|
1312
1231
|
}
|
|
1313
|
-
function
|
|
1314
|
-
|
|
1232
|
+
function attemptReparse(current, result, reparseCount, maxReparses, parse4) {
|
|
1233
|
+
if (!result.reparse || result.rawSegment === void 0 || reparseCount >= maxReparses) {
|
|
1234
|
+
return { state: current, newCount: reparseCount };
|
|
1235
|
+
}
|
|
1315
1236
|
try {
|
|
1316
|
-
const
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
}
|
|
1321
|
-
flushText(ctrl);
|
|
1322
|
-
ctrl.enqueue({
|
|
1323
|
-
type: "tool-call",
|
|
1324
|
-
toolCallId: (0, import_provider_utils3.generateId)(),
|
|
1325
|
-
toolName: currentToolCall.name,
|
|
1326
|
-
input: JSON.stringify(parsed)
|
|
1327
|
-
});
|
|
1237
|
+
const reparsed = parse4(result.rawSegment, current.schema);
|
|
1238
|
+
return {
|
|
1239
|
+
state: { ...current, parsed: reparsed, errors: [] },
|
|
1240
|
+
newCount: reparseCount + 1
|
|
1241
|
+
};
|
|
1328
1242
|
} catch (error) {
|
|
1329
|
-
|
|
1330
|
-
error,
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
options,
|
|
1334
|
-
ctrl,
|
|
1335
|
-
flushText
|
|
1336
|
-
});
|
|
1243
|
+
return {
|
|
1244
|
+
state: { ...current, errors: [...current.errors, error] },
|
|
1245
|
+
newCount: reparseCount + 1
|
|
1246
|
+
};
|
|
1337
1247
|
}
|
|
1338
1248
|
}
|
|
1339
|
-
function
|
|
1249
|
+
function executePhase(ctx, heuristics, options) {
|
|
1340
1250
|
var _a;
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
const
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1251
|
+
let current = ctx;
|
|
1252
|
+
let reparseCount = 0;
|
|
1253
|
+
const maxReparses = (_a = options.maxReparses) != null ? _a : 2;
|
|
1254
|
+
for (const heuristic of heuristics) {
|
|
1255
|
+
if (!heuristic.applies(current)) {
|
|
1256
|
+
continue;
|
|
1257
|
+
}
|
|
1258
|
+
const result = heuristic.run(current);
|
|
1259
|
+
current = applyRawSegmentUpdate(current, result);
|
|
1260
|
+
current = applyParsedUpdate(current, result);
|
|
1261
|
+
current = applyWarningsUpdate(current, result);
|
|
1262
|
+
const reparseResult = attemptReparse(
|
|
1263
|
+
current,
|
|
1264
|
+
result,
|
|
1265
|
+
reparseCount,
|
|
1266
|
+
maxReparses,
|
|
1267
|
+
options.parse
|
|
1268
|
+
);
|
|
1269
|
+
current = reparseResult.state;
|
|
1270
|
+
reparseCount = reparseResult.newCount;
|
|
1271
|
+
if (result.stop) {
|
|
1272
|
+
break;
|
|
1273
|
+
}
|
|
1351
1274
|
}
|
|
1352
|
-
|
|
1353
|
-
toolCall: originalCallText,
|
|
1354
|
-
toolName: currentToolCall.name,
|
|
1355
|
-
error
|
|
1356
|
-
});
|
|
1357
|
-
flushText(ctrl, originalCallText);
|
|
1275
|
+
return current;
|
|
1358
1276
|
}
|
|
1359
|
-
function
|
|
1360
|
-
let
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
}
|
|
1277
|
+
function applyHeuristicPipeline(ctx, config, options) {
|
|
1278
|
+
let current = ctx;
|
|
1279
|
+
if (config.preParse && config.preParse.length > 0) {
|
|
1280
|
+
current = executePhase(current, config.preParse, options);
|
|
1281
|
+
}
|
|
1282
|
+
if (current.parsed === null && current.errors.length === 0) {
|
|
1283
|
+
try {
|
|
1284
|
+
const parsed = options.parse(current.rawSegment, current.schema);
|
|
1285
|
+
current = { ...current, parsed, errors: [] };
|
|
1286
|
+
} catch (error) {
|
|
1287
|
+
current = { ...current, errors: [error] };
|
|
1370
1288
|
}
|
|
1371
1289
|
}
|
|
1372
|
-
|
|
1290
|
+
if (current.errors.length > 0 && config.fallbackReparse && config.fallbackReparse.length > 0) {
|
|
1291
|
+
current = executePhase(current, config.fallbackReparse, options);
|
|
1292
|
+
}
|
|
1293
|
+
if (current.parsed !== null && config.postParse && config.postParse.length > 0) {
|
|
1294
|
+
current = executePhase(current, config.postParse, options);
|
|
1295
|
+
}
|
|
1296
|
+
return current;
|
|
1373
1297
|
}
|
|
1374
|
-
function
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1298
|
+
function createIntermediateCall(toolName, rawSegment, schema) {
|
|
1299
|
+
return {
|
|
1300
|
+
toolName,
|
|
1301
|
+
schema,
|
|
1302
|
+
rawSegment,
|
|
1303
|
+
parsed: null,
|
|
1304
|
+
errors: [],
|
|
1305
|
+
meta: { originalContent: rawSegment }
|
|
1306
|
+
};
|
|
1307
|
+
}
|
|
1308
|
+
function mergePipelineConfigs(...configs) {
|
|
1309
|
+
var _a, _b, _c;
|
|
1310
|
+
const result = {
|
|
1311
|
+
preParse: [],
|
|
1312
|
+
fallbackReparse: [],
|
|
1313
|
+
postParse: []
|
|
1314
|
+
};
|
|
1315
|
+
for (const config of configs) {
|
|
1316
|
+
if (config.preParse) {
|
|
1317
|
+
result.preParse = [...(_a = result.preParse) != null ? _a : [], ...config.preParse];
|
|
1318
|
+
}
|
|
1319
|
+
if (config.fallbackReparse) {
|
|
1320
|
+
result.fallbackReparse = [
|
|
1321
|
+
...(_b = result.fallbackReparse) != null ? _b : [],
|
|
1322
|
+
...config.fallbackReparse
|
|
1323
|
+
];
|
|
1324
|
+
}
|
|
1325
|
+
if (config.postParse) {
|
|
1326
|
+
result.postParse = [...(_c = result.postParse) != null ? _c : [], ...config.postParse];
|
|
1327
|
+
}
|
|
1381
1328
|
}
|
|
1382
|
-
return
|
|
1329
|
+
return result;
|
|
1383
1330
|
}
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1331
|
+
|
|
1332
|
+
// src/heuristics/xml-defaults.ts
|
|
1333
|
+
var import_rxml = require("@ai-sdk-tool/rxml");
|
|
1334
|
+
var MALFORMED_CLOSE_RE_G = /<\/\s+([A-Za-z0-9_:-]+)\s*>/g;
|
|
1335
|
+
var MALFORMED_CLOSE_RE = /<\/\s+([A-Za-z0-9_:-]+)\s*>/;
|
|
1336
|
+
var STATUS_TO_STEP_BOUNDARY_RE = /<\/status>\s*<step>/g;
|
|
1337
|
+
var WHITESPACE_REGEX2 = /\s/;
|
|
1338
|
+
var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
|
|
1339
|
+
var NAME_START_CHAR_RE = /[A-Za-z_:]/;
|
|
1340
|
+
var STEP_TAG_RE = /<step>([\s\S]*?)<\/step>/i;
|
|
1341
|
+
var STATUS_TAG_RE = /<status>([\s\S]*?)<\/status>/i;
|
|
1342
|
+
var normalizeCloseTagsHeuristic = {
|
|
1343
|
+
id: "normalize-close-tags",
|
|
1344
|
+
phase: "pre-parse",
|
|
1345
|
+
applies: () => true,
|
|
1346
|
+
run: (ctx) => {
|
|
1347
|
+
const normalized = ctx.rawSegment.replace(MALFORMED_CLOSE_RE_G, "</$1>");
|
|
1348
|
+
if (normalized !== ctx.rawSegment) {
|
|
1349
|
+
return { rawSegment: normalized };
|
|
1350
|
+
}
|
|
1351
|
+
return {};
|
|
1352
|
+
}
|
|
1353
|
+
};
|
|
1354
|
+
var escapeInvalidLtHeuristic = {
|
|
1355
|
+
id: "escape-invalid-lt",
|
|
1356
|
+
phase: "pre-parse",
|
|
1357
|
+
applies: () => true,
|
|
1358
|
+
run: (ctx) => {
|
|
1359
|
+
const escaped = escapeInvalidLt(ctx.rawSegment);
|
|
1360
|
+
if (escaped !== ctx.rawSegment) {
|
|
1361
|
+
return { rawSegment: escaped };
|
|
1362
|
+
}
|
|
1363
|
+
return {};
|
|
1364
|
+
}
|
|
1365
|
+
};
|
|
1366
|
+
var balanceTagsHeuristic = {
|
|
1367
|
+
id: "balance-tags",
|
|
1368
|
+
phase: "fallback-reparse",
|
|
1369
|
+
applies: (ctx) => {
|
|
1370
|
+
var _a;
|
|
1371
|
+
const original = ((_a = ctx.meta) == null ? void 0 : _a.originalContent) || ctx.rawSegment;
|
|
1372
|
+
const normalized = original.replace(MALFORMED_CLOSE_RE_G, "</$1>");
|
|
1373
|
+
const balanced = balanceTags(original);
|
|
1374
|
+
const hasMalformedClose = MALFORMED_CLOSE_RE.test(original);
|
|
1375
|
+
if (!hasMalformedClose && balanced.length > normalized.length) {
|
|
1376
|
+
return false;
|
|
1377
|
+
}
|
|
1378
|
+
return balanced !== normalized;
|
|
1379
|
+
},
|
|
1380
|
+
run: (ctx) => {
|
|
1381
|
+
var _a;
|
|
1382
|
+
const original = ((_a = ctx.meta) == null ? void 0 : _a.originalContent) || ctx.rawSegment;
|
|
1383
|
+
const balanced = balanceTags(original);
|
|
1384
|
+
const escaped = escapeInvalidLt(balanced);
|
|
1385
|
+
return { rawSegment: escaped, reparse: true };
|
|
1386
|
+
}
|
|
1387
|
+
};
|
|
1388
|
+
var dedupeShellStringTagsHeuristic = {
|
|
1389
|
+
id: "dedupe-shell-string-tags",
|
|
1390
|
+
phase: "fallback-reparse",
|
|
1391
|
+
applies: (ctx) => shouldDeduplicateStringTags(ctx.schema),
|
|
1392
|
+
run: (ctx) => {
|
|
1393
|
+
const names = getStringPropertyNames(ctx.schema);
|
|
1394
|
+
let deduped = ctx.rawSegment;
|
|
1395
|
+
for (const key of names) {
|
|
1396
|
+
deduped = dedupeSingleTag(deduped, key);
|
|
1397
|
+
}
|
|
1398
|
+
if (deduped !== ctx.rawSegment) {
|
|
1399
|
+
return { rawSegment: deduped, reparse: true };
|
|
1400
|
+
}
|
|
1401
|
+
return {};
|
|
1402
|
+
}
|
|
1403
|
+
};
|
|
1404
|
+
var repairAgainstSchemaHeuristic = {
|
|
1405
|
+
id: "repair-against-schema",
|
|
1406
|
+
phase: "post-parse",
|
|
1407
|
+
applies: (ctx) => ctx.parsed !== null && typeof ctx.parsed === "object",
|
|
1408
|
+
run: (ctx) => {
|
|
1409
|
+
const repaired = repairParsedAgainstSchema(ctx.parsed, ctx.schema);
|
|
1410
|
+
if (repaired !== ctx.parsed) {
|
|
1411
|
+
return { parsed: repaired };
|
|
1412
|
+
}
|
|
1413
|
+
return {};
|
|
1414
|
+
}
|
|
1415
|
+
};
|
|
1416
|
+
var defaultPipelineConfig = {
|
|
1417
|
+
preParse: [normalizeCloseTagsHeuristic, escapeInvalidLtHeuristic],
|
|
1418
|
+
fallbackReparse: [balanceTagsHeuristic, dedupeShellStringTagsHeuristic],
|
|
1419
|
+
postParse: [repairAgainstSchemaHeuristic]
|
|
1420
|
+
};
|
|
1421
|
+
var INDEX_TAG_RE = /^<(\d+)(?:>|\/?>)/;
|
|
1422
|
+
function isIndexTagAt(xml, pos) {
|
|
1423
|
+
const remaining = xml.slice(pos);
|
|
1424
|
+
return INDEX_TAG_RE.test(remaining);
|
|
1425
|
+
}
|
|
1426
|
+
function escapeInvalidLt(xml) {
|
|
1427
|
+
const len = xml.length;
|
|
1428
|
+
let out = "";
|
|
1429
|
+
for (let i = 0; i < len; i += 1) {
|
|
1430
|
+
const ch = xml[i];
|
|
1431
|
+
if (ch === "<") {
|
|
1432
|
+
const next = i + 1 < len ? xml[i + 1] : "";
|
|
1433
|
+
const isValidStart = NAME_START_CHAR_RE.test(next) || next === "/" || next === "!" || next === "?";
|
|
1434
|
+
const isIndexTag = !isValidStart && isIndexTagAt(xml, i);
|
|
1435
|
+
if (!(isValidStart || isIndexTag)) {
|
|
1436
|
+
out += "<";
|
|
1437
|
+
continue;
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
out += ch;
|
|
1441
|
+
}
|
|
1442
|
+
return out;
|
|
1443
|
+
}
|
|
1444
|
+
function balanceTags(xml) {
|
|
1445
|
+
const src = xml.replace(MALFORMED_CLOSE_RE_G, "</$1>").replace(STATUS_TO_STEP_BOUNDARY_RE, "</status></step><step>");
|
|
1446
|
+
let i = 0;
|
|
1447
|
+
const len = src.length;
|
|
1448
|
+
const out = [];
|
|
1449
|
+
const stack = [];
|
|
1450
|
+
while (i < len) {
|
|
1451
|
+
const lt = src.indexOf("<", i);
|
|
1452
|
+
if (lt === -1) {
|
|
1453
|
+
out.push(src.slice(i));
|
|
1454
|
+
break;
|
|
1455
|
+
}
|
|
1456
|
+
out.push(src.slice(i, lt));
|
|
1457
|
+
if (lt + 1 >= len) {
|
|
1458
|
+
break;
|
|
1459
|
+
}
|
|
1460
|
+
const next = src[lt + 1];
|
|
1461
|
+
if (next === "!" || next === "?") {
|
|
1462
|
+
i = handleSpecialTagSegment(src, lt, out);
|
|
1463
|
+
continue;
|
|
1464
|
+
}
|
|
1465
|
+
if (next === "/") {
|
|
1466
|
+
i = handleClosingTagSegment(src, lt, out, stack);
|
|
1467
|
+
continue;
|
|
1468
|
+
}
|
|
1469
|
+
i = handleOpeningTagSegment(src, lt, out, stack);
|
|
1470
|
+
}
|
|
1471
|
+
for (let k = stack.length - 1; k >= 0; k -= 1) {
|
|
1472
|
+
out.push(`</${stack[k]}>`);
|
|
1473
|
+
}
|
|
1474
|
+
return out.join("");
|
|
1475
|
+
}
|
|
1476
|
+
function skipWs(s, p, len) {
|
|
1477
|
+
let idx = p;
|
|
1478
|
+
while (idx < len && WHITESPACE_REGEX2.test(s[idx])) {
|
|
1479
|
+
idx += 1;
|
|
1480
|
+
}
|
|
1481
|
+
return idx;
|
|
1482
|
+
}
|
|
1483
|
+
function parseTagNameAt(s, p, len) {
|
|
1484
|
+
let idx = p;
|
|
1485
|
+
const start = idx;
|
|
1486
|
+
while (idx < len && NAME_CHAR_RE.test(s[idx])) {
|
|
1487
|
+
idx += 1;
|
|
1488
|
+
}
|
|
1489
|
+
return { name: s.slice(start, idx), pos: idx };
|
|
1490
|
+
}
|
|
1491
|
+
function handleSpecialTagSegment(src, lt, out) {
|
|
1492
|
+
const gt = src.indexOf(">", lt + 1);
|
|
1493
|
+
if (gt === -1) {
|
|
1494
|
+
out.push(src.slice(lt));
|
|
1495
|
+
return src.length;
|
|
1496
|
+
}
|
|
1497
|
+
out.push(src.slice(lt, gt + 1));
|
|
1498
|
+
return gt + 1;
|
|
1499
|
+
}
|
|
1500
|
+
function handleClosingTagSegment(src, lt, out, stack) {
|
|
1501
|
+
const len = src.length;
|
|
1502
|
+
let p = skipWs(src, lt + 2, len);
|
|
1503
|
+
const { name, pos } = parseTagNameAt(src, p, len);
|
|
1504
|
+
p = pos;
|
|
1505
|
+
const gt = src.indexOf(">", p);
|
|
1506
|
+
const closingText = gt === -1 ? src.slice(lt) : src.slice(lt, gt + 1);
|
|
1507
|
+
const idx = stack.lastIndexOf(name);
|
|
1508
|
+
if (idx !== -1) {
|
|
1509
|
+
for (let k = stack.length - 1; k > idx; k -= 1) {
|
|
1510
|
+
out.push(`</${stack[k]}>`);
|
|
1511
|
+
stack.pop();
|
|
1512
|
+
}
|
|
1513
|
+
out.push(closingText);
|
|
1514
|
+
stack.pop();
|
|
1515
|
+
}
|
|
1516
|
+
return gt === -1 ? len : gt + 1;
|
|
1517
|
+
}
|
|
1518
|
+
function handleOpeningTagSegment(src, lt, out, stack) {
|
|
1519
|
+
const len = src.length;
|
|
1520
|
+
let p = skipWs(src, lt + 1, len);
|
|
1521
|
+
const nameStart = p;
|
|
1522
|
+
const parsed = parseTagNameAt(src, p, len);
|
|
1523
|
+
p = parsed.pos;
|
|
1524
|
+
const name = src.slice(nameStart, p);
|
|
1525
|
+
const q = src.indexOf(">", p);
|
|
1526
|
+
if (q === -1) {
|
|
1527
|
+
out.push(src.slice(lt));
|
|
1528
|
+
return len;
|
|
1529
|
+
}
|
|
1530
|
+
let r = q - 1;
|
|
1531
|
+
while (r >= nameStart && WHITESPACE_REGEX2.test(src[r])) {
|
|
1532
|
+
r -= 1;
|
|
1533
|
+
}
|
|
1534
|
+
const selfClosing = src[r] === "/";
|
|
1535
|
+
out.push(src.slice(lt, q + 1));
|
|
1536
|
+
if (!selfClosing && name) {
|
|
1537
|
+
stack.push(name);
|
|
1538
|
+
}
|
|
1539
|
+
return q + 1;
|
|
1540
|
+
}
|
|
1541
|
+
function shouldDeduplicateStringTags(schema) {
|
|
1542
|
+
const unwrapped = (0, import_rxml.unwrapJsonSchema)(schema);
|
|
1543
|
+
if (!unwrapped || typeof unwrapped !== "object") {
|
|
1544
|
+
return false;
|
|
1545
|
+
}
|
|
1546
|
+
const props = unwrapped.properties;
|
|
1547
|
+
if (!props) {
|
|
1548
|
+
return false;
|
|
1549
|
+
}
|
|
1550
|
+
const commandRaw = props.command;
|
|
1551
|
+
if (!commandRaw) {
|
|
1552
|
+
return false;
|
|
1553
|
+
}
|
|
1554
|
+
const command = (0, import_rxml.unwrapJsonSchema)(commandRaw);
|
|
1555
|
+
return (command == null ? void 0 : command.type) === "array";
|
|
1556
|
+
}
|
|
1557
|
+
function getStringPropertyNames(schema) {
|
|
1558
|
+
const unwrapped = (0, import_rxml.unwrapJsonSchema)(schema);
|
|
1559
|
+
if (!unwrapped || typeof unwrapped !== "object") {
|
|
1560
|
+
return [];
|
|
1561
|
+
}
|
|
1562
|
+
const props = unwrapped.properties;
|
|
1563
|
+
if (!props) {
|
|
1564
|
+
return [];
|
|
1565
|
+
}
|
|
1566
|
+
const names = [];
|
|
1567
|
+
for (const key of Object.keys(props)) {
|
|
1568
|
+
const prop = (0, import_rxml.unwrapJsonSchema)(
|
|
1569
|
+
props[key]
|
|
1570
|
+
);
|
|
1571
|
+
const type = prop.type;
|
|
1572
|
+
if (type === "string") {
|
|
1573
|
+
names.push(key);
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
return names;
|
|
1577
|
+
}
|
|
1578
|
+
function escapeRegExp2(s) {
|
|
1579
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1580
|
+
}
|
|
1581
|
+
function dedupeSingleTag(xml, key) {
|
|
1582
|
+
var _a, _b;
|
|
1583
|
+
const escaped = escapeRegExp2(key);
|
|
1584
|
+
const re = new RegExp(`<${escaped}>([\\s\\S]*?)<\\/${escaped}>`, "g");
|
|
1585
|
+
const matches = Array.from(xml.matchAll(re));
|
|
1586
|
+
if (matches.length <= 1) {
|
|
1587
|
+
return xml;
|
|
1588
|
+
}
|
|
1589
|
+
const last = matches.at(-1);
|
|
1590
|
+
let result = "";
|
|
1591
|
+
let cursor = 0;
|
|
1592
|
+
for (const m of matches) {
|
|
1593
|
+
const idx = (_a = m.index) != null ? _a : 0;
|
|
1594
|
+
result += xml.slice(cursor, idx);
|
|
1595
|
+
if (last && idx === ((_b = last.index) != null ? _b : -1)) {
|
|
1596
|
+
result += m[0];
|
|
1597
|
+
}
|
|
1598
|
+
cursor = idx + m[0].length;
|
|
1599
|
+
}
|
|
1600
|
+
result += xml.slice(cursor);
|
|
1601
|
+
return result;
|
|
1602
|
+
}
|
|
1603
|
+
function repairParsedAgainstSchema(input, schema) {
|
|
1604
|
+
if (!input || typeof input !== "object") {
|
|
1605
|
+
return input;
|
|
1606
|
+
}
|
|
1607
|
+
const unwrapped = (0, import_rxml.unwrapJsonSchema)(schema);
|
|
1608
|
+
if (!unwrapped || typeof unwrapped !== "object") {
|
|
1609
|
+
return input;
|
|
1610
|
+
}
|
|
1611
|
+
const properties = unwrapped.properties;
|
|
1612
|
+
if (!properties) {
|
|
1613
|
+
return input;
|
|
1614
|
+
}
|
|
1615
|
+
applySchemaProps(input, properties);
|
|
1616
|
+
return input;
|
|
1617
|
+
}
|
|
1618
|
+
function applySchemaProps(obj, properties) {
|
|
1619
|
+
for (const key of Object.keys(obj)) {
|
|
1620
|
+
const propSchema = properties[key];
|
|
1621
|
+
if (!propSchema) {
|
|
1622
|
+
continue;
|
|
1623
|
+
}
|
|
1624
|
+
const prop = (0, import_rxml.unwrapJsonSchema)(propSchema);
|
|
1625
|
+
const propType = prop.type;
|
|
1626
|
+
if (propType === "array" && prop.items) {
|
|
1627
|
+
const itemSchemaRaw = prop.items;
|
|
1628
|
+
const itemSchema = (0, import_rxml.unwrapJsonSchema)(itemSchemaRaw);
|
|
1629
|
+
obj[key] = coerceArrayItems(obj[key], itemSchema);
|
|
1630
|
+
continue;
|
|
1631
|
+
}
|
|
1632
|
+
if (propType === "object") {
|
|
1633
|
+
const val = obj[key];
|
|
1634
|
+
if (val && typeof val === "object") {
|
|
1635
|
+
obj[key] = repairParsedAgainstSchema(val, prop);
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1640
|
+
function coerceArrayItems(val, itemSchema) {
|
|
1641
|
+
if (!Array.isArray(val)) {
|
|
1642
|
+
return val;
|
|
1643
|
+
}
|
|
1644
|
+
return val.map((v) => coerceArrayItem(v, itemSchema));
|
|
1645
|
+
}
|
|
1646
|
+
function coerceArrayItem(v, itemSchema) {
|
|
1647
|
+
const itemType = itemSchema == null ? void 0 : itemSchema.type;
|
|
1648
|
+
if (typeof v === "string" && itemType === "object") {
|
|
1649
|
+
const parsed = tryParseStringToSchemaObject(v, itemSchema);
|
|
1650
|
+
if (parsed !== null) {
|
|
1651
|
+
return parsed;
|
|
1652
|
+
}
|
|
1653
|
+
const fallback = extractStepStatusFromString(
|
|
1654
|
+
v.replace(MALFORMED_CLOSE_RE_G, "</$1>")
|
|
1655
|
+
);
|
|
1656
|
+
if (fallback) {
|
|
1657
|
+
return fallback;
|
|
1658
|
+
}
|
|
1659
|
+
return v;
|
|
1660
|
+
}
|
|
1661
|
+
if (v && typeof v === "object" && itemType === "object") {
|
|
1662
|
+
return repairParsedAgainstSchema(v, itemSchema);
|
|
1663
|
+
}
|
|
1664
|
+
return v;
|
|
1665
|
+
}
|
|
1666
|
+
function tryParseStringToSchemaObject(xml, itemSchema) {
|
|
1667
|
+
try {
|
|
1668
|
+
const normalized = xml.replace(MALFORMED_CLOSE_RE_G, "</$1>");
|
|
1669
|
+
const fixed = (0, import_rxml.parse)(normalized, itemSchema, { noChildNodes: [] });
|
|
1670
|
+
return typeof fixed === "string" ? null : fixed;
|
|
1671
|
+
} catch (e) {
|
|
1672
|
+
return null;
|
|
1673
|
+
}
|
|
1674
|
+
}
|
|
1675
|
+
function extractStepStatusFromString(normXml) {
|
|
1676
|
+
const stepMatch = normXml.match(STEP_TAG_RE);
|
|
1677
|
+
const statusMatch = normXml.match(STATUS_TAG_RE);
|
|
1678
|
+
if (stepMatch && statusMatch) {
|
|
1679
|
+
return { step: stepMatch[1], status: statusMatch[1] };
|
|
1680
|
+
}
|
|
1681
|
+
return null;
|
|
1682
|
+
}
|
|
1683
|
+
|
|
1684
|
+
// src/utils/type-guards.ts
|
|
1685
|
+
function isToolCallContent(content) {
|
|
1686
|
+
return content.type === "tool-call" && typeof content.toolName === "string" && // input may be a JSON string or an already-parsed object depending on provider/runtime
|
|
1687
|
+
(typeof content.input === "string" || typeof content.input === "object");
|
|
1688
|
+
}
|
|
1689
|
+
function isToolResultPart(content) {
|
|
1690
|
+
const c = content;
|
|
1691
|
+
return !!c && c.type === "tool-result" && typeof c.toolName === "string" && typeof c.toolCallId === "string" && "output" in c;
|
|
1692
|
+
}
|
|
1693
|
+
function hasInputProperty(obj) {
|
|
1694
|
+
return typeof obj === "object" && obj !== null && "input" in obj;
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1697
|
+
// src/protocols/morph-xml-protocol.ts
|
|
1698
|
+
var defaultPipelineConfig2 = defaultPipelineConfig;
|
|
1699
|
+
var applyHeuristicPipeline2 = applyHeuristicPipeline;
|
|
1700
|
+
var createIntermediateCall2 = createIntermediateCall;
|
|
1701
|
+
var mergePipelineConfigs2 = mergePipelineConfigs;
|
|
1702
|
+
var WHITESPACE_REGEX3 = /\s/;
|
|
1703
|
+
var MALFORMED_CLOSE_RE2 = /<\/\s+([A-Za-z0-9_:-]+)\s*>/;
|
|
1704
|
+
var MALFORMED_CLOSE_RE_G2 = /<\/\s+([A-Za-z0-9_:-]+)\s*>/g;
|
|
1705
|
+
var NAME_CHAR_RE2 = /[A-Za-z0-9_:-]/;
|
|
1706
|
+
function normalizeCloseTags(xml) {
|
|
1707
|
+
return xml.replace(MALFORMED_CLOSE_RE_G2, "</$1>");
|
|
1708
|
+
}
|
|
1709
|
+
function tryParseSecondaryXml(content, toolSchema, options) {
|
|
1710
|
+
const normalized = normalizeCloseTags(content);
|
|
1711
|
+
const balanced = balanceTags(content);
|
|
1712
|
+
const hasMalformedClose = MALFORMED_CLOSE_RE2.test(content);
|
|
1713
|
+
if (!hasMalformedClose && balanced.length > normalized.length) {
|
|
1714
|
+
return null;
|
|
1715
|
+
}
|
|
1716
|
+
try {
|
|
1717
|
+
let parsed = (0, import_rxml2.parse)(balanced, toolSchema, {
|
|
1718
|
+
onError: options == null ? void 0 : options.onError,
|
|
1719
|
+
noChildNodes: []
|
|
1720
|
+
});
|
|
1721
|
+
parsed = repairParsedAgainstSchema(parsed, toolSchema);
|
|
1722
|
+
return parsed;
|
|
1723
|
+
} catch (e) {
|
|
1724
|
+
if (shouldDeduplicateStringTags(toolSchema)) {
|
|
1725
|
+
const deduped = dedupeStringTagsAgainstSchema(balanced, toolSchema);
|
|
1726
|
+
if (deduped !== balanced) {
|
|
1727
|
+
try {
|
|
1728
|
+
let reparsed = (0, import_rxml2.parse)(deduped, toolSchema, {
|
|
1729
|
+
onError: options == null ? void 0 : options.onError,
|
|
1730
|
+
noChildNodes: []
|
|
1731
|
+
});
|
|
1732
|
+
reparsed = repairParsedAgainstSchema(reparsed, toolSchema);
|
|
1733
|
+
return reparsed;
|
|
1734
|
+
} catch (e2) {
|
|
1735
|
+
return null;
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
return null;
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
function dedupeStringTagsAgainstSchema(xml, schema) {
|
|
1743
|
+
const names = getStringPropertyNames(schema);
|
|
1744
|
+
let out = xml;
|
|
1745
|
+
for (const key of names) {
|
|
1746
|
+
out = dedupeSingleTag(out, key);
|
|
1747
|
+
}
|
|
1748
|
+
return out;
|
|
1749
|
+
}
|
|
1750
|
+
function processTextBeforeToolCall(text, currentIndex, toolCallStartIndex, processedElements) {
|
|
1751
|
+
if (toolCallStartIndex > currentIndex) {
|
|
1752
|
+
const textSegment = text.substring(currentIndex, toolCallStartIndex);
|
|
1753
|
+
if (textSegment.trim()) {
|
|
1754
|
+
processedElements.push({ type: "text", text: textSegment });
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1757
|
+
return currentIndex;
|
|
1758
|
+
}
|
|
1759
|
+
function processToolCallWithPipeline(params) {
|
|
1760
|
+
var _a;
|
|
1761
|
+
const {
|
|
1762
|
+
toolCall,
|
|
1763
|
+
tools,
|
|
1389
1764
|
options,
|
|
1390
|
-
|
|
1765
|
+
text,
|
|
1766
|
+
processedElements,
|
|
1767
|
+
pipelineConfig = defaultPipelineConfig2,
|
|
1768
|
+
maxReparses
|
|
1769
|
+
} = params;
|
|
1770
|
+
const toolSchema = getToolSchema(tools, toolCall.toolName);
|
|
1771
|
+
const ctx = createIntermediateCall2(
|
|
1772
|
+
toolCall.toolName,
|
|
1773
|
+
toolCall.content,
|
|
1774
|
+
toolSchema
|
|
1775
|
+
);
|
|
1776
|
+
const result = applyHeuristicPipeline2(ctx, pipelineConfig, {
|
|
1777
|
+
parse: (xml, schema) => (0, import_rxml2.parse)(xml, schema, { onError: options == null ? void 0 : options.onError, noChildNodes: [] }),
|
|
1778
|
+
onError: options == null ? void 0 : options.onError,
|
|
1779
|
+
maxReparses
|
|
1780
|
+
});
|
|
1781
|
+
if (result.parsed !== null) {
|
|
1782
|
+
processedElements.push({
|
|
1783
|
+
type: "tool-call",
|
|
1784
|
+
toolCallId: (0, import_provider_utils2.generateId)(),
|
|
1785
|
+
toolName: toolCall.toolName,
|
|
1786
|
+
input: JSON.stringify(result.parsed)
|
|
1787
|
+
});
|
|
1788
|
+
} else {
|
|
1789
|
+
const originalCallText = text.substring(
|
|
1790
|
+
toolCall.startIndex,
|
|
1791
|
+
toolCall.endIndex
|
|
1792
|
+
);
|
|
1793
|
+
const message = `Could not process XML tool call, keeping original text: ${originalCallText}`;
|
|
1794
|
+
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, message, {
|
|
1795
|
+
toolCall: originalCallText,
|
|
1796
|
+
toolName: toolCall.toolName,
|
|
1797
|
+
error: result.errors[0]
|
|
1798
|
+
});
|
|
1799
|
+
processedElements.push({ type: "text", text: originalCallText });
|
|
1800
|
+
}
|
|
1801
|
+
}
|
|
1802
|
+
function processToolCall(params) {
|
|
1803
|
+
var _a;
|
|
1804
|
+
const { toolCall, tools, options, text, processedElements } = params;
|
|
1805
|
+
const toolSchema = getToolSchema(tools, toolCall.toolName);
|
|
1806
|
+
try {
|
|
1807
|
+
const primary = escapeInvalidLt(normalizeCloseTags(toolCall.content));
|
|
1808
|
+
let parsed = (0, import_rxml2.parse)(primary, toolSchema, {
|
|
1809
|
+
onError: options == null ? void 0 : options.onError,
|
|
1810
|
+
noChildNodes: []
|
|
1811
|
+
});
|
|
1812
|
+
parsed = repairParsedAgainstSchema(parsed, toolSchema);
|
|
1813
|
+
processedElements.push({
|
|
1814
|
+
type: "tool-call",
|
|
1815
|
+
toolCallId: (0, import_provider_utils2.generateId)(),
|
|
1816
|
+
toolName: toolCall.toolName,
|
|
1817
|
+
input: JSON.stringify(parsed)
|
|
1818
|
+
});
|
|
1819
|
+
} catch (error) {
|
|
1820
|
+
const reparsed = tryParseSecondaryXml(
|
|
1821
|
+
toolCall.content,
|
|
1822
|
+
toolSchema,
|
|
1823
|
+
options
|
|
1824
|
+
);
|
|
1825
|
+
if (reparsed !== null) {
|
|
1826
|
+
processedElements.push({
|
|
1827
|
+
type: "tool-call",
|
|
1828
|
+
toolCallId: (0, import_provider_utils2.generateId)(),
|
|
1829
|
+
toolName: toolCall.toolName,
|
|
1830
|
+
input: JSON.stringify(reparsed)
|
|
1831
|
+
});
|
|
1832
|
+
return;
|
|
1833
|
+
}
|
|
1834
|
+
const originalCallText = text.substring(
|
|
1835
|
+
toolCall.startIndex,
|
|
1836
|
+
toolCall.endIndex
|
|
1837
|
+
);
|
|
1838
|
+
const message = `Could not process XML tool call, keeping original text: ${originalCallText}`;
|
|
1839
|
+
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, message, {
|
|
1840
|
+
toolCall: originalCallText,
|
|
1841
|
+
toolName: toolCall.toolName,
|
|
1842
|
+
error
|
|
1843
|
+
});
|
|
1844
|
+
processedElements.push({ type: "text", text: originalCallText });
|
|
1845
|
+
}
|
|
1846
|
+
}
|
|
1847
|
+
function addRemainingText(text, currentIndex, processedElements) {
|
|
1848
|
+
if (currentIndex < text.length) {
|
|
1849
|
+
const remainingText = text.substring(currentIndex);
|
|
1850
|
+
if (remainingText.trim()) {
|
|
1851
|
+
processedElements.push({ type: "text", text: remainingText });
|
|
1852
|
+
}
|
|
1853
|
+
}
|
|
1854
|
+
}
|
|
1855
|
+
function handleStreamingToolCallEndWithPipeline(params) {
|
|
1856
|
+
var _a;
|
|
1857
|
+
const {
|
|
1858
|
+
toolContent,
|
|
1859
|
+
currentToolCall,
|
|
1860
|
+
tools,
|
|
1861
|
+
options,
|
|
1862
|
+
ctrl,
|
|
1391
1863
|
flushText,
|
|
1392
|
-
|
|
1864
|
+
pipelineConfig = defaultPipelineConfig2,
|
|
1865
|
+
maxReparses
|
|
1393
1866
|
} = params;
|
|
1394
|
-
const
|
|
1395
|
-
const
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1867
|
+
const toolSchema = getToolSchema(tools, currentToolCall.name);
|
|
1868
|
+
const ctx = createIntermediateCall2(
|
|
1869
|
+
currentToolCall.name,
|
|
1870
|
+
toolContent,
|
|
1871
|
+
toolSchema
|
|
1872
|
+
);
|
|
1873
|
+
const result = applyHeuristicPipeline2(ctx, pipelineConfig, {
|
|
1874
|
+
parse: (xml, schema) => (0, import_rxml2.parse)(xml, schema, { onError: options == null ? void 0 : options.onError, noChildNodes: [] }),
|
|
1875
|
+
onError: options == null ? void 0 : options.onError,
|
|
1876
|
+
maxReparses
|
|
1877
|
+
});
|
|
1878
|
+
flushText(ctrl);
|
|
1879
|
+
if (result.parsed !== null) {
|
|
1880
|
+
ctrl.enqueue({
|
|
1881
|
+
type: "tool-call",
|
|
1882
|
+
toolCallId: (0, import_provider_utils2.generateId)(),
|
|
1883
|
+
toolName: currentToolCall.name,
|
|
1884
|
+
input: JSON.stringify(result.parsed)
|
|
1885
|
+
});
|
|
1886
|
+
} else {
|
|
1887
|
+
const endTag = `</${currentToolCall.name}>`;
|
|
1888
|
+
const originalCallText = `<${currentToolCall.name}>${toolContent}${endTag}`;
|
|
1889
|
+
const error = result.errors[0];
|
|
1890
|
+
let message = "Could not process streaming XML tool call; emitting original text.";
|
|
1891
|
+
if (error instanceof import_rxml2.RXMLDuplicateStringTagError) {
|
|
1892
|
+
message = `Duplicate string tags detected in streaming tool call '${currentToolCall.name}'; emitting original text.`;
|
|
1893
|
+
} else if (error instanceof import_rxml2.RXMLCoercionError) {
|
|
1894
|
+
message = `Failed to coerce arguments for streaming tool call '${currentToolCall.name}'; emitting original text.`;
|
|
1895
|
+
} else if (error instanceof import_rxml2.RXMLParseError) {
|
|
1896
|
+
message = `Failed to parse XML for streaming tool call '${currentToolCall.name}'; emitting original text.`;
|
|
1897
|
+
}
|
|
1898
|
+
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, message, {
|
|
1899
|
+
toolCall: originalCallText,
|
|
1900
|
+
toolName: currentToolCall.name,
|
|
1901
|
+
error
|
|
1902
|
+
});
|
|
1903
|
+
flushText(ctrl, originalCallText);
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1906
|
+
function handleStreamingToolCallEnd(params) {
|
|
1907
|
+
const { toolContent, currentToolCall, tools, options, ctrl, flushText } = params;
|
|
1908
|
+
const toolSchema = getToolSchema(tools, currentToolCall.name);
|
|
1909
|
+
try {
|
|
1910
|
+
const primary = escapeInvalidLt(normalizeCloseTags(toolContent));
|
|
1911
|
+
let parsed = (0, import_rxml2.parse)(primary, toolSchema, {
|
|
1912
|
+
onError: options == null ? void 0 : options.onError,
|
|
1913
|
+
noChildNodes: []
|
|
1914
|
+
});
|
|
1915
|
+
parsed = repairParsedAgainstSchema(parsed, toolSchema);
|
|
1916
|
+
flushText(ctrl);
|
|
1917
|
+
ctrl.enqueue({
|
|
1918
|
+
type: "tool-call",
|
|
1919
|
+
toolCallId: (0, import_provider_utils2.generateId)(),
|
|
1920
|
+
toolName: currentToolCall.name,
|
|
1921
|
+
input: JSON.stringify(parsed)
|
|
1922
|
+
});
|
|
1923
|
+
} catch (error) {
|
|
1924
|
+
const parsed = tryParseSecondaryXml(toolContent, toolSchema, options);
|
|
1925
|
+
if (parsed !== null) {
|
|
1926
|
+
flushText(ctrl);
|
|
1927
|
+
ctrl.enqueue({
|
|
1928
|
+
type: "tool-call",
|
|
1929
|
+
toolCallId: (0, import_provider_utils2.generateId)(),
|
|
1930
|
+
toolName: currentToolCall.name,
|
|
1931
|
+
input: JSON.stringify(parsed)
|
|
1932
|
+
});
|
|
1933
|
+
return;
|
|
1934
|
+
}
|
|
1935
|
+
handleStreamingToolCallError({
|
|
1936
|
+
error,
|
|
1402
1937
|
currentToolCall,
|
|
1403
|
-
|
|
1938
|
+
toolContent,
|
|
1404
1939
|
options,
|
|
1405
|
-
ctrl
|
|
1940
|
+
ctrl,
|
|
1406
1941
|
flushText
|
|
1407
1942
|
});
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
function handleStreamingToolCallError(params) {
|
|
1946
|
+
var _a;
|
|
1947
|
+
const { error, currentToolCall, toolContent, options, ctrl, flushText } = params;
|
|
1948
|
+
const endTag = `</${currentToolCall.name}>`;
|
|
1949
|
+
const originalCallText = `<${currentToolCall.name}>${toolContent}${endTag}`;
|
|
1950
|
+
let message = "Could not process streaming XML tool call; emitting original text.";
|
|
1951
|
+
if (error instanceof import_rxml2.RXMLDuplicateStringTagError) {
|
|
1952
|
+
message = `Duplicate string tags detected in streaming tool call '${currentToolCall.name}'; emitting original text.`;
|
|
1953
|
+
} else if (error instanceof import_rxml2.RXMLCoercionError) {
|
|
1954
|
+
message = `Failed to coerce arguments for streaming tool call '${currentToolCall.name}'; emitting original text.`;
|
|
1955
|
+
} else if (error instanceof import_rxml2.RXMLParseError) {
|
|
1956
|
+
message = `Failed to parse XML for streaming tool call '${currentToolCall.name}'; emitting original text.`;
|
|
1957
|
+
}
|
|
1958
|
+
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, message, {
|
|
1959
|
+
toolCall: originalCallText,
|
|
1960
|
+
toolName: currentToolCall.name,
|
|
1961
|
+
error
|
|
1962
|
+
});
|
|
1963
|
+
flushText(ctrl, originalCallText);
|
|
1964
|
+
}
|
|
1965
|
+
function findEarliestToolTag(buffer, toolNames) {
|
|
1966
|
+
let bestIndex = -1;
|
|
1967
|
+
let bestName = "";
|
|
1968
|
+
let bestSelfClosing = false;
|
|
1969
|
+
if (toolNames.length > 0) {
|
|
1970
|
+
for (const name of toolNames) {
|
|
1971
|
+
const openTag = `<${name}>`;
|
|
1972
|
+
const selfTag = `<${name}/>`;
|
|
1973
|
+
const idxOpen = buffer.indexOf(openTag);
|
|
1974
|
+
const idxSelf = buffer.indexOf(selfTag);
|
|
1975
|
+
if (idxOpen !== -1 && (bestIndex === -1 || idxOpen < bestIndex)) {
|
|
1976
|
+
bestIndex = idxOpen;
|
|
1977
|
+
bestName = name;
|
|
1978
|
+
bestSelfClosing = false;
|
|
1979
|
+
}
|
|
1980
|
+
if (idxSelf !== -1 && (bestIndex === -1 || idxSelf < bestIndex)) {
|
|
1981
|
+
bestIndex = idxSelf;
|
|
1982
|
+
bestName = name;
|
|
1983
|
+
bestSelfClosing = true;
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
1987
|
+
return { index: bestIndex, name: bestName, selfClosing: bestSelfClosing };
|
|
1988
|
+
}
|
|
1989
|
+
function handleNoToolTagInBuffer(buffer, maxStartTagLen, controller, flushText) {
|
|
1990
|
+
const tail = Math.max(0, maxStartTagLen - 1);
|
|
1991
|
+
const safeLen = Math.max(0, buffer.length - tail);
|
|
1992
|
+
if (safeLen > 0) {
|
|
1993
|
+
const textToFlush = buffer.slice(0, safeLen);
|
|
1994
|
+
flushText(controller, textToFlush);
|
|
1995
|
+
return { buffer: buffer.slice(safeLen), shouldContinue: true };
|
|
1996
|
+
}
|
|
1997
|
+
return { buffer, shouldContinue: false };
|
|
1998
|
+
}
|
|
1999
|
+
function processToolCallInBuffer(params) {
|
|
2000
|
+
const {
|
|
2001
|
+
buffer,
|
|
2002
|
+
currentToolCall,
|
|
2003
|
+
tools,
|
|
2004
|
+
options,
|
|
2005
|
+
controller,
|
|
2006
|
+
flushText,
|
|
2007
|
+
setBuffer,
|
|
2008
|
+
pipelineConfig,
|
|
2009
|
+
maxReparses
|
|
2010
|
+
} = params;
|
|
2011
|
+
const endTag = `</${currentToolCall.name}>`;
|
|
2012
|
+
const normalized = normalizeCloseTags(buffer);
|
|
2013
|
+
const effectiveBuffer = normalized;
|
|
2014
|
+
const endTagIndex = effectiveBuffer.indexOf(endTag);
|
|
2015
|
+
if (endTagIndex !== -1) {
|
|
2016
|
+
const toolContent = effectiveBuffer.substring(0, endTagIndex);
|
|
2017
|
+
const newBuffer = effectiveBuffer.substring(endTagIndex + endTag.length);
|
|
2018
|
+
setBuffer("");
|
|
2019
|
+
if (pipelineConfig) {
|
|
2020
|
+
handleStreamingToolCallEndWithPipeline({
|
|
2021
|
+
toolContent,
|
|
2022
|
+
currentToolCall,
|
|
2023
|
+
tools,
|
|
2024
|
+
options,
|
|
2025
|
+
ctrl: controller,
|
|
2026
|
+
flushText,
|
|
2027
|
+
pipelineConfig,
|
|
2028
|
+
maxReparses
|
|
2029
|
+
});
|
|
2030
|
+
} else {
|
|
2031
|
+
handleStreamingToolCallEnd({
|
|
2032
|
+
toolContent,
|
|
2033
|
+
currentToolCall,
|
|
2034
|
+
tools,
|
|
2035
|
+
options,
|
|
2036
|
+
ctrl: controller,
|
|
2037
|
+
flushText
|
|
2038
|
+
});
|
|
2039
|
+
}
|
|
1408
2040
|
setBuffer(newBuffer);
|
|
1409
2041
|
return { buffer: newBuffer, currentToolCall: null, shouldBreak: false };
|
|
1410
2042
|
}
|
|
1411
|
-
return { buffer, currentToolCall, shouldBreak: true };
|
|
2043
|
+
return { buffer: effectiveBuffer, currentToolCall, shouldBreak: true };
|
|
1412
2044
|
}
|
|
1413
2045
|
function processNoToolCallInBuffer(params) {
|
|
1414
|
-
const {
|
|
1415
|
-
|
|
2046
|
+
const {
|
|
2047
|
+
buffer,
|
|
2048
|
+
toolNames,
|
|
2049
|
+
maxStartTagLen,
|
|
2050
|
+
controller,
|
|
2051
|
+
flushText,
|
|
2052
|
+
tools,
|
|
2053
|
+
options,
|
|
2054
|
+
pipelineConfig,
|
|
2055
|
+
maxReparses
|
|
2056
|
+
} = params;
|
|
2057
|
+
const {
|
|
2058
|
+
index: earliestStartTagIndex,
|
|
2059
|
+
name: earliestToolName,
|
|
2060
|
+
selfClosing
|
|
2061
|
+
} = findEarliestToolTag(buffer, toolNames);
|
|
1416
2062
|
if (earliestStartTagIndex !== -1) {
|
|
1417
2063
|
const textBeforeTag = buffer.substring(0, earliestStartTagIndex);
|
|
1418
2064
|
flushText(controller, textBeforeTag);
|
|
2065
|
+
if (selfClosing) {
|
|
2066
|
+
const selfTag = `<${earliestToolName}/>`;
|
|
2067
|
+
const newBuffer2 = buffer.substring(
|
|
2068
|
+
earliestStartTagIndex + selfTag.length
|
|
2069
|
+
);
|
|
2070
|
+
if (pipelineConfig) {
|
|
2071
|
+
handleStreamingToolCallEndWithPipeline({
|
|
2072
|
+
toolContent: "",
|
|
2073
|
+
currentToolCall: { name: earliestToolName, content: "" },
|
|
2074
|
+
tools,
|
|
2075
|
+
options,
|
|
2076
|
+
ctrl: controller,
|
|
2077
|
+
flushText,
|
|
2078
|
+
pipelineConfig,
|
|
2079
|
+
maxReparses
|
|
2080
|
+
});
|
|
2081
|
+
} else {
|
|
2082
|
+
handleStreamingToolCallEnd({
|
|
2083
|
+
toolContent: "",
|
|
2084
|
+
currentToolCall: { name: earliestToolName, content: "" },
|
|
2085
|
+
tools,
|
|
2086
|
+
options,
|
|
2087
|
+
ctrl: controller,
|
|
2088
|
+
flushText
|
|
2089
|
+
});
|
|
2090
|
+
}
|
|
2091
|
+
return {
|
|
2092
|
+
buffer: newBuffer2,
|
|
2093
|
+
currentToolCall: null,
|
|
2094
|
+
shouldBreak: false,
|
|
2095
|
+
shouldContinue: false
|
|
2096
|
+
};
|
|
2097
|
+
}
|
|
1419
2098
|
const startTag = `<${earliestToolName}>`;
|
|
1420
2099
|
const newBuffer = buffer.substring(earliestStartTagIndex + startTag.length);
|
|
1421
2100
|
return {
|
|
@@ -1444,7 +2123,7 @@ function createFlushTextHandler(getBuffer, setBuffer, getCurrentTextId, setCurre
|
|
|
1444
2123
|
if (content) {
|
|
1445
2124
|
const currentTextId2 = getCurrentTextId();
|
|
1446
2125
|
if (!currentTextId2) {
|
|
1447
|
-
const newId = (0,
|
|
2126
|
+
const newId = (0, import_provider_utils2.generateId)();
|
|
1448
2127
|
setCurrentTextId(newId);
|
|
1449
2128
|
controller.enqueue({ type: "text-start", id: newId });
|
|
1450
2129
|
}
|
|
@@ -1472,7 +2151,9 @@ function processBufferWithToolCall(params, controller) {
|
|
|
1472
2151
|
setCurrentToolCall,
|
|
1473
2152
|
tools,
|
|
1474
2153
|
options,
|
|
1475
|
-
flushText
|
|
2154
|
+
flushText,
|
|
2155
|
+
pipelineConfig,
|
|
2156
|
+
maxReparses
|
|
1476
2157
|
} = params;
|
|
1477
2158
|
const currentToolCall = getCurrentToolCall();
|
|
1478
2159
|
if (!currentToolCall) {
|
|
@@ -1485,7 +2166,9 @@ function processBufferWithToolCall(params, controller) {
|
|
|
1485
2166
|
options,
|
|
1486
2167
|
controller,
|
|
1487
2168
|
flushText,
|
|
1488
|
-
setBuffer
|
|
2169
|
+
setBuffer,
|
|
2170
|
+
pipelineConfig,
|
|
2171
|
+
maxReparses
|
|
1489
2172
|
});
|
|
1490
2173
|
setBuffer(result.buffer);
|
|
1491
2174
|
setCurrentToolCall(result.currentToolCall);
|
|
@@ -1496,16 +2179,24 @@ function processBufferWithoutToolCall(params, controller) {
|
|
|
1496
2179
|
getBuffer,
|
|
1497
2180
|
setBuffer,
|
|
1498
2181
|
setCurrentToolCall,
|
|
2182
|
+
tools,
|
|
2183
|
+
options,
|
|
1499
2184
|
toolNames,
|
|
1500
2185
|
maxStartTagLen,
|
|
1501
|
-
flushText
|
|
2186
|
+
flushText,
|
|
2187
|
+
pipelineConfig,
|
|
2188
|
+
maxReparses
|
|
1502
2189
|
} = params;
|
|
1503
2190
|
const result = processNoToolCallInBuffer({
|
|
1504
2191
|
buffer: getBuffer(),
|
|
1505
2192
|
toolNames,
|
|
1506
2193
|
maxStartTagLen,
|
|
1507
2194
|
controller,
|
|
1508
|
-
flushText
|
|
2195
|
+
flushText,
|
|
2196
|
+
tools,
|
|
2197
|
+
options,
|
|
2198
|
+
pipelineConfig,
|
|
2199
|
+
maxReparses
|
|
1509
2200
|
});
|
|
1510
2201
|
setBuffer(result.buffer);
|
|
1511
2202
|
setCurrentToolCall(result.currentToolCall);
|
|
@@ -1525,196 +2216,427 @@ function processBufferLoop(params, controller) {
|
|
|
1525
2216
|
} else {
|
|
1526
2217
|
const { shouldBreak, shouldContinue } = processBufferWithoutToolCall(
|
|
1527
2218
|
params,
|
|
1528
|
-
controller
|
|
1529
|
-
);
|
|
1530
|
-
if (shouldContinue) {
|
|
1531
|
-
continue;
|
|
1532
|
-
}
|
|
1533
|
-
if (shouldBreak) {
|
|
1534
|
-
break;
|
|
1535
|
-
}
|
|
1536
|
-
}
|
|
1537
|
-
}
|
|
1538
|
-
}
|
|
1539
|
-
function createProcessBufferHandler(params) {
|
|
1540
|
-
return (controller) => {
|
|
1541
|
-
processBufferLoop(params, controller);
|
|
1542
|
-
};
|
|
1543
|
-
}
|
|
1544
|
-
var morphXmlProtocol = () => ({
|
|
1545
|
-
formatTools({ tools, toolSystemPromptTemplate }) {
|
|
1546
|
-
const toolsForPrompt = (tools || []).map((tool) => ({
|
|
1547
|
-
name: tool.name,
|
|
1548
|
-
description: tool.description,
|
|
1549
|
-
parameters: (0, import_rxml.unwrapJsonSchema)(tool.inputSchema)
|
|
1550
|
-
}));
|
|
1551
|
-
return toolSystemPromptTemplate(JSON.stringify(toolsForPrompt));
|
|
1552
|
-
},
|
|
1553
|
-
formatToolCall(toolCall) {
|
|
1554
|
-
let args = {};
|
|
1555
|
-
const inputValue = hasInputProperty(toolCall) ? toolCall.input : void 0;
|
|
1556
|
-
if (typeof inputValue === "string") {
|
|
1557
|
-
try {
|
|
1558
|
-
args = JSON.parse(inputValue);
|
|
1559
|
-
} catch (e) {
|
|
1560
|
-
args = inputValue;
|
|
1561
|
-
}
|
|
1562
|
-
} else {
|
|
1563
|
-
args = inputValue;
|
|
1564
|
-
}
|
|
1565
|
-
return (0, import_rxml.stringify)(toolCall.toolName, args, {
|
|
1566
|
-
suppressEmptyNode: false,
|
|
1567
|
-
format: false
|
|
1568
|
-
});
|
|
1569
|
-
},
|
|
1570
|
-
formatToolResponse(toolResult) {
|
|
1571
|
-
return (0, import_rxml.stringify)("tool_response", {
|
|
1572
|
-
tool_name: toolResult.toolName,
|
|
1573
|
-
result: toolResult.output
|
|
1574
|
-
});
|
|
1575
|
-
},
|
|
1576
|
-
parseGeneratedText({ text, tools, options }) {
|
|
1577
|
-
const toolNames = tools.map((t) => t.name).filter((name) => name != null);
|
|
1578
|
-
if (toolNames.length === 0) {
|
|
1579
|
-
return [{ type: "text", text }];
|
|
1580
|
-
}
|
|
1581
|
-
const processedElements = [];
|
|
1582
|
-
let currentIndex = 0;
|
|
1583
|
-
const toolCalls = findToolCalls(text, toolNames);
|
|
1584
|
-
for (const toolCall of toolCalls) {
|
|
1585
|
-
currentIndex = processTextBeforeToolCall(
|
|
1586
|
-
text,
|
|
1587
|
-
currentIndex,
|
|
1588
|
-
toolCall.startIndex,
|
|
1589
|
-
processedElements
|
|
1590
|
-
);
|
|
1591
|
-
processToolCall({ toolCall, tools, options, text, processedElements });
|
|
1592
|
-
currentIndex = toolCall.endIndex;
|
|
1593
|
-
}
|
|
1594
|
-
addRemainingText(text, currentIndex, processedElements);
|
|
1595
|
-
return processedElements;
|
|
1596
|
-
},
|
|
1597
|
-
createStreamParser({ tools, options }) {
|
|
1598
|
-
const toolNames = tools.map((t) => t.name).filter((name) => name != null);
|
|
1599
|
-
const maxStartTagLen = toolNames.length ? Math.max(...toolNames.map((n) => `<${n}>`.length)) : 0;
|
|
1600
|
-
let buffer = "";
|
|
1601
|
-
let currentToolCall = null;
|
|
1602
|
-
let currentTextId = null;
|
|
1603
|
-
const flushText = createFlushTextHandler(
|
|
1604
|
-
() => buffer,
|
|
1605
|
-
(newBuffer) => {
|
|
1606
|
-
buffer = newBuffer;
|
|
1607
|
-
},
|
|
1608
|
-
() => currentTextId,
|
|
1609
|
-
(newId) => {
|
|
1610
|
-
currentTextId = newId;
|
|
2219
|
+
controller
|
|
2220
|
+
);
|
|
2221
|
+
if (shouldContinue) {
|
|
2222
|
+
continue;
|
|
1611
2223
|
}
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
if (chunk.type !== "text-delta") {
|
|
1615
|
-
if (buffer) {
|
|
1616
|
-
flushText(controller);
|
|
1617
|
-
}
|
|
1618
|
-
controller.enqueue(chunk);
|
|
1619
|
-
return;
|
|
2224
|
+
if (shouldBreak) {
|
|
2225
|
+
break;
|
|
1620
2226
|
}
|
|
1621
|
-
|
|
1622
|
-
|
|
2227
|
+
}
|
|
2228
|
+
}
|
|
2229
|
+
}
|
|
2230
|
+
function createProcessBufferHandler(params) {
|
|
2231
|
+
return (controller) => {
|
|
2232
|
+
processBufferLoop(params, controller);
|
|
2233
|
+
};
|
|
2234
|
+
}
|
|
2235
|
+
function buildPipelineOptions(protocolOptions) {
|
|
2236
|
+
var _a, _b, _c;
|
|
2237
|
+
const maxReparses = protocolOptions == null ? void 0 : protocolOptions.maxReparses;
|
|
2238
|
+
if (protocolOptions == null ? void 0 : protocolOptions.pipeline) {
|
|
2239
|
+
return {
|
|
2240
|
+
pipelineConfig: mergePipelineConfigs2(
|
|
2241
|
+
defaultPipelineConfig2,
|
|
2242
|
+
protocolOptions.pipeline
|
|
2243
|
+
),
|
|
2244
|
+
maxReparses
|
|
1623
2245
|
};
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
2246
|
+
}
|
|
2247
|
+
if (protocolOptions == null ? void 0 : protocolOptions.heuristics) {
|
|
2248
|
+
return {
|
|
2249
|
+
pipelineConfig: {
|
|
2250
|
+
...defaultPipelineConfig2,
|
|
2251
|
+
preParse: [
|
|
2252
|
+
...(_a = defaultPipelineConfig2.preParse) != null ? _a : [],
|
|
2253
|
+
...protocolOptions.heuristics.filter((h) => h.phase === "pre-parse")
|
|
2254
|
+
],
|
|
2255
|
+
fallbackReparse: [
|
|
2256
|
+
...(_b = defaultPipelineConfig2.fallbackReparse) != null ? _b : [],
|
|
2257
|
+
...protocolOptions.heuristics.filter(
|
|
2258
|
+
(h) => h.phase === "fallback-reparse"
|
|
2259
|
+
)
|
|
2260
|
+
],
|
|
2261
|
+
postParse: [
|
|
2262
|
+
...(_c = defaultPipelineConfig2.postParse) != null ? _c : [],
|
|
2263
|
+
...protocolOptions.heuristics.filter((h) => h.phase === "post-parse")
|
|
2264
|
+
]
|
|
1632
2265
|
},
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
2266
|
+
maxReparses
|
|
2267
|
+
};
|
|
2268
|
+
}
|
|
2269
|
+
return { pipelineConfig: void 0, maxReparses };
|
|
2270
|
+
}
|
|
2271
|
+
var morphXmlProtocol = (protocolOptions) => {
|
|
2272
|
+
const { pipelineConfig, maxReparses } = buildPipelineOptions(protocolOptions);
|
|
2273
|
+
return {
|
|
2274
|
+
formatTools({ tools, toolSystemPromptTemplate }) {
|
|
2275
|
+
const toolsForPrompt = (tools || []).map((tool) => ({
|
|
2276
|
+
name: tool.name,
|
|
2277
|
+
description: tool.description,
|
|
2278
|
+
parameters: (0, import_rxml2.unwrapJsonSchema)(tool.inputSchema)
|
|
2279
|
+
}));
|
|
2280
|
+
return toolSystemPromptTemplate(JSON.stringify(toolsForPrompt));
|
|
2281
|
+
},
|
|
2282
|
+
formatToolCall(toolCall) {
|
|
2283
|
+
let args = {};
|
|
2284
|
+
const inputValue = hasInputProperty(toolCall) ? toolCall.input : void 0;
|
|
2285
|
+
if (typeof inputValue === "string") {
|
|
2286
|
+
try {
|
|
2287
|
+
args = JSON.parse(inputValue);
|
|
2288
|
+
} catch (e) {
|
|
2289
|
+
args = inputValue;
|
|
2290
|
+
}
|
|
2291
|
+
} else {
|
|
2292
|
+
args = inputValue;
|
|
1645
2293
|
}
|
|
1646
|
-
|
|
1647
|
-
|
|
2294
|
+
return (0, import_rxml2.stringify)(toolCall.toolName, args, {
|
|
2295
|
+
suppressEmptyNode: false,
|
|
2296
|
+
format: false
|
|
2297
|
+
});
|
|
2298
|
+
},
|
|
2299
|
+
formatToolResponse(toolResult) {
|
|
2300
|
+
return (0, import_rxml2.stringify)("tool_response", {
|
|
2301
|
+
tool_name: toolResult.toolName,
|
|
2302
|
+
result: toolResult.output
|
|
2303
|
+
});
|
|
2304
|
+
},
|
|
2305
|
+
parseGeneratedText({ text, tools, options }) {
|
|
2306
|
+
const toolNames = tools.map((t) => t.name).filter((name) => name != null);
|
|
2307
|
+
if (toolNames.length === 0) {
|
|
2308
|
+
return [{ type: "text", text }];
|
|
1648
2309
|
}
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
2310
|
+
const processedElements = [];
|
|
2311
|
+
let currentIndex = 0;
|
|
2312
|
+
const toolCallsRaw = findToolCalls(text, toolNames);
|
|
2313
|
+
const toolCallsNorm = collectToolCallsFromNormalizedText(text, toolNames);
|
|
2314
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2315
|
+
const toolCalls = [...toolCallsRaw, ...toolCallsNorm].filter((tc) => {
|
|
2316
|
+
const key = `${tc.toolName}:${tc.startIndex}:${tc.endIndex}`;
|
|
2317
|
+
if (seen.has(key)) {
|
|
2318
|
+
return false;
|
|
2319
|
+
}
|
|
2320
|
+
seen.add(key);
|
|
2321
|
+
return true;
|
|
2322
|
+
}).sort((a, b) => a.startIndex - b.startIndex);
|
|
2323
|
+
for (const toolCall of toolCalls) {
|
|
2324
|
+
currentIndex = processTextBeforeToolCall(
|
|
2325
|
+
text,
|
|
2326
|
+
currentIndex,
|
|
2327
|
+
toolCall.startIndex,
|
|
2328
|
+
processedElements
|
|
2329
|
+
);
|
|
2330
|
+
if (pipelineConfig) {
|
|
2331
|
+
processToolCallWithPipeline({
|
|
2332
|
+
toolCall,
|
|
2333
|
+
tools,
|
|
2334
|
+
options,
|
|
2335
|
+
text,
|
|
2336
|
+
processedElements,
|
|
2337
|
+
pipelineConfig,
|
|
2338
|
+
maxReparses
|
|
2339
|
+
});
|
|
2340
|
+
} else {
|
|
2341
|
+
processToolCall({
|
|
2342
|
+
toolCall,
|
|
2343
|
+
tools,
|
|
2344
|
+
options,
|
|
2345
|
+
text,
|
|
2346
|
+
processedElements
|
|
2347
|
+
});
|
|
2348
|
+
}
|
|
2349
|
+
currentIndex = toolCall.endIndex;
|
|
1656
2350
|
}
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
2351
|
+
addRemainingText(text, currentIndex, processedElements);
|
|
2352
|
+
return processedElements;
|
|
2353
|
+
},
|
|
2354
|
+
createStreamParser({ tools, options }) {
|
|
2355
|
+
const toolNames = tools.map((t) => t.name).filter((name) => name != null);
|
|
2356
|
+
const maxStartTagLen = toolNames.length ? Math.max(...toolNames.map((n) => `<${n}>`.length)) : 0;
|
|
2357
|
+
let buffer = "";
|
|
2358
|
+
let currentToolCall = null;
|
|
2359
|
+
let currentTextId = null;
|
|
2360
|
+
const flushText = createFlushTextHandler(
|
|
2361
|
+
() => buffer,
|
|
2362
|
+
(newBuffer) => {
|
|
2363
|
+
buffer = newBuffer;
|
|
2364
|
+
},
|
|
2365
|
+
() => currentTextId,
|
|
2366
|
+
(newId) => {
|
|
2367
|
+
currentTextId = newId;
|
|
2368
|
+
}
|
|
2369
|
+
);
|
|
2370
|
+
const processChunk = (chunk, controller) => {
|
|
2371
|
+
if (chunk.type !== "text-delta") {
|
|
2372
|
+
if (buffer) {
|
|
2373
|
+
flushText(controller);
|
|
2374
|
+
}
|
|
2375
|
+
controller.enqueue(chunk);
|
|
2376
|
+
return;
|
|
2377
|
+
}
|
|
2378
|
+
buffer += chunk.delta;
|
|
2379
|
+
processBuffer(controller);
|
|
2380
|
+
};
|
|
2381
|
+
const processBuffer = createProcessBufferHandler({
|
|
2382
|
+
getBuffer: () => buffer,
|
|
2383
|
+
setBuffer: (newBuffer) => {
|
|
2384
|
+
buffer = newBuffer;
|
|
2385
|
+
},
|
|
2386
|
+
getCurrentToolCall: () => currentToolCall,
|
|
2387
|
+
setCurrentToolCall: (newToolCall) => {
|
|
2388
|
+
currentToolCall = newToolCall;
|
|
2389
|
+
},
|
|
2390
|
+
tools,
|
|
2391
|
+
options,
|
|
2392
|
+
toolNames,
|
|
2393
|
+
maxStartTagLen,
|
|
2394
|
+
flushText,
|
|
2395
|
+
pipelineConfig,
|
|
2396
|
+
maxReparses
|
|
2397
|
+
});
|
|
2398
|
+
const flushBuffer2 = (controller) => {
|
|
2399
|
+
if (currentToolCall) {
|
|
2400
|
+
const unfinishedCall = `<${currentToolCall.name}>${buffer}`;
|
|
2401
|
+
flushText(controller, unfinishedCall);
|
|
2402
|
+
} else if (buffer) {
|
|
2403
|
+
flushText(controller);
|
|
2404
|
+
}
|
|
2405
|
+
if (currentTextId) {
|
|
2406
|
+
controller.enqueue({ type: "text-end", id: currentTextId });
|
|
2407
|
+
}
|
|
2408
|
+
};
|
|
2409
|
+
return new TransformStream({
|
|
2410
|
+
transform(chunk, controller) {
|
|
2411
|
+
processChunk(chunk, controller);
|
|
2412
|
+
},
|
|
2413
|
+
flush(controller) {
|
|
2414
|
+
flushBuffer2(controller);
|
|
2415
|
+
}
|
|
2416
|
+
});
|
|
2417
|
+
},
|
|
2418
|
+
extractToolCallSegments({ text, tools }) {
|
|
2419
|
+
const toolNames = tools.map((t) => t.name).filter(Boolean);
|
|
2420
|
+
if (toolNames.length === 0) {
|
|
2421
|
+
return [];
|
|
2422
|
+
}
|
|
2423
|
+
return findToolCalls(text, toolNames).map((tc) => tc.segment);
|
|
1663
2424
|
}
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
});
|
|
2425
|
+
};
|
|
2426
|
+
};
|
|
1667
2427
|
function getToolSchema(tools, toolName) {
|
|
1668
2428
|
var _a;
|
|
1669
2429
|
return (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
|
|
1670
2430
|
}
|
|
1671
|
-
function
|
|
1672
|
-
let
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
2431
|
+
function findClosingTagEndFlexible(text, contentStart, toolName) {
|
|
2432
|
+
let pos = contentStart;
|
|
2433
|
+
let depth = 1;
|
|
2434
|
+
while (pos < text.length) {
|
|
2435
|
+
const tok = nextTagToken(text, pos);
|
|
2436
|
+
if (tok.kind === "eof") {
|
|
2437
|
+
break;
|
|
2438
|
+
}
|
|
2439
|
+
const result = updateDepthWithToken(tok, toolName, depth);
|
|
2440
|
+
depth = result.depth;
|
|
2441
|
+
if (result.closedAt !== void 0) {
|
|
2442
|
+
return result.closedAt;
|
|
2443
|
+
}
|
|
2444
|
+
pos = tok.nextPos;
|
|
2445
|
+
}
|
|
2446
|
+
return -1;
|
|
2447
|
+
}
|
|
2448
|
+
function skipSpecialSegment(text, lt) {
|
|
2449
|
+
const next = text[lt + 1];
|
|
2450
|
+
if (next !== "!" && next !== "?") {
|
|
2451
|
+
return null;
|
|
2452
|
+
}
|
|
2453
|
+
const gt = text.indexOf(">", lt + 1);
|
|
2454
|
+
if (gt === -1) {
|
|
2455
|
+
return null;
|
|
2456
|
+
}
|
|
2457
|
+
return gt + 1;
|
|
2458
|
+
}
|
|
2459
|
+
function consumeClosingTag(text, lt, _toolName) {
|
|
2460
|
+
let p = lt + 2;
|
|
2461
|
+
while (p < text.length && WHITESPACE_REGEX3.test(text[p])) {
|
|
2462
|
+
p += 1;
|
|
2463
|
+
}
|
|
2464
|
+
const gt = text.indexOf(">", lt + 1);
|
|
2465
|
+
const endPos = gt === -1 ? text.length : gt + 1;
|
|
2466
|
+
return { matched: false, endPos };
|
|
2467
|
+
}
|
|
2468
|
+
function consumeOpenTag(text, lt) {
|
|
2469
|
+
let p = lt + 1;
|
|
2470
|
+
while (p < text.length && WHITESPACE_REGEX3.test(text[p])) {
|
|
2471
|
+
p += 1;
|
|
2472
|
+
}
|
|
2473
|
+
const nameStart = p;
|
|
2474
|
+
while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
|
|
2475
|
+
p += 1;
|
|
2476
|
+
}
|
|
2477
|
+
const name = text.slice(nameStart, p);
|
|
2478
|
+
const q = text.indexOf(">", p);
|
|
2479
|
+
if (q === -1) {
|
|
2480
|
+
return null;
|
|
2481
|
+
}
|
|
2482
|
+
let r = q - 1;
|
|
2483
|
+
while (r >= nameStart && WHITESPACE_REGEX3.test(text[r])) {
|
|
2484
|
+
r -= 1;
|
|
2485
|
+
}
|
|
2486
|
+
const selfClosing = text[r] === "/";
|
|
2487
|
+
return { name, selfClosing, nextPos: q + 1 };
|
|
2488
|
+
}
|
|
2489
|
+
function updateDepthWithToken(tok, toolName, depth) {
|
|
2490
|
+
if (tok.kind === "close" && tok.name === toolName) {
|
|
2491
|
+
const newDepth = depth - 1;
|
|
2492
|
+
return newDepth === 0 ? { depth: newDepth, closedAt: tok.nextPos } : { depth: newDepth };
|
|
2493
|
+
}
|
|
2494
|
+
if (tok.kind === "open" && tok.name === toolName && !tok.selfClosing) {
|
|
2495
|
+
return { depth: depth + 1 };
|
|
2496
|
+
}
|
|
2497
|
+
return { depth };
|
|
2498
|
+
}
|
|
2499
|
+
function nextTagToken(text, fromPos) {
|
|
2500
|
+
const lt = text.indexOf("<", fromPos);
|
|
2501
|
+
if (lt === -1 || lt + 1 >= text.length) {
|
|
2502
|
+
return { kind: "eof", nextPos: text.length };
|
|
2503
|
+
}
|
|
2504
|
+
const next = text[lt + 1];
|
|
2505
|
+
const specialEnd = skipSpecialSegment(text, lt);
|
|
2506
|
+
if (specialEnd !== null) {
|
|
2507
|
+
return { kind: "special", nextPos: specialEnd };
|
|
2508
|
+
}
|
|
2509
|
+
if (next === "/") {
|
|
2510
|
+
const closing = consumeClosingTag(text, lt, "");
|
|
2511
|
+
let p = lt + 2;
|
|
2512
|
+
while (p < text.length && WHITESPACE_REGEX3.test(text[p])) {
|
|
1677
2513
|
p += 1;
|
|
1678
2514
|
}
|
|
1679
|
-
|
|
1680
|
-
|
|
2515
|
+
const nameStart = p;
|
|
2516
|
+
while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
|
|
2517
|
+
p += 1;
|
|
1681
2518
|
}
|
|
2519
|
+
const name = text.slice(nameStart, p);
|
|
2520
|
+
return { kind: "close", name, nextPos: closing.endPos };
|
|
2521
|
+
}
|
|
2522
|
+
const open = consumeOpenTag(text, lt);
|
|
2523
|
+
if (open === null) {
|
|
2524
|
+
return { kind: "eof", nextPos: text.length };
|
|
1682
2525
|
}
|
|
1683
|
-
return
|
|
2526
|
+
return {
|
|
2527
|
+
kind: "open",
|
|
2528
|
+
name: open.name,
|
|
2529
|
+
selfClosing: open.selfClosing,
|
|
2530
|
+
nextPos: open.nextPos
|
|
2531
|
+
};
|
|
1684
2532
|
}
|
|
1685
|
-
function
|
|
2533
|
+
function collectToolCallsFromNormalizedText(text, toolNames) {
|
|
1686
2534
|
var _a;
|
|
2535
|
+
const normalizedText = normalizeCloseTags(text);
|
|
2536
|
+
const collected = [];
|
|
2537
|
+
for (const toolName of toolNames) {
|
|
2538
|
+
const startTag = `<${toolName}>`;
|
|
2539
|
+
let idx = 0;
|
|
2540
|
+
let lastOrigIdx = 0;
|
|
2541
|
+
while (idx < normalizedText.length) {
|
|
2542
|
+
const tagStartNorm = normalizedText.indexOf(startTag, idx);
|
|
2543
|
+
if (tagStartNorm === -1) {
|
|
2544
|
+
break;
|
|
2545
|
+
}
|
|
2546
|
+
const contentStartNorm = tagStartNorm + startTag.length;
|
|
2547
|
+
const endNorm = findClosingTagEndFlexible(
|
|
2548
|
+
normalizedText,
|
|
2549
|
+
contentStartNorm,
|
|
2550
|
+
toolName
|
|
2551
|
+
);
|
|
2552
|
+
if (endNorm > contentStartNorm) {
|
|
2553
|
+
const tagStartOrig = text.indexOf(startTag, lastOrigIdx);
|
|
2554
|
+
const contentStartOrig = tagStartOrig + startTag.length;
|
|
2555
|
+
let endOrig = findClosingTagEndFlexible(
|
|
2556
|
+
text,
|
|
2557
|
+
contentStartOrig,
|
|
2558
|
+
toolName
|
|
2559
|
+
);
|
|
2560
|
+
if (endOrig === -1) {
|
|
2561
|
+
const approxLen = endNorm - tagStartNorm;
|
|
2562
|
+
endOrig = Math.min(text.length, tagStartOrig + approxLen);
|
|
2563
|
+
}
|
|
2564
|
+
const segment = text.substring(tagStartOrig, endOrig);
|
|
2565
|
+
const inner = (_a = (0, import_rxml2.extractRawInner)(segment, toolName)) != null ? _a : segment.substring(startTag.length, segment.lastIndexOf("<"));
|
|
2566
|
+
collected.push({
|
|
2567
|
+
toolName,
|
|
2568
|
+
startIndex: tagStartOrig,
|
|
2569
|
+
endIndex: endOrig,
|
|
2570
|
+
content: inner,
|
|
2571
|
+
segment
|
|
2572
|
+
});
|
|
2573
|
+
lastOrigIdx = endOrig;
|
|
2574
|
+
idx = endNorm;
|
|
2575
|
+
} else {
|
|
2576
|
+
idx = contentStartNorm;
|
|
2577
|
+
}
|
|
2578
|
+
}
|
|
2579
|
+
}
|
|
2580
|
+
return collected.sort((a, b) => a.startIndex - b.startIndex);
|
|
2581
|
+
}
|
|
2582
|
+
function getNextTagInfo(text, toolName, fromIndex) {
|
|
1687
2583
|
const startTag = `<${toolName}>`;
|
|
1688
|
-
const
|
|
1689
|
-
const
|
|
1690
|
-
const
|
|
1691
|
-
const
|
|
1692
|
-
const
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
2584
|
+
const selfTag = `<${toolName}/>`;
|
|
2585
|
+
const openIdx = text.indexOf(startTag, fromIndex);
|
|
2586
|
+
const selfIdx = text.indexOf(selfTag, fromIndex);
|
|
2587
|
+
const hasOpen = openIdx !== -1;
|
|
2588
|
+
const hasSelf = selfIdx !== -1;
|
|
2589
|
+
if (!(hasOpen || hasSelf)) {
|
|
2590
|
+
return {
|
|
2591
|
+
found: false,
|
|
2592
|
+
tagStart: -1,
|
|
2593
|
+
selfClosing: false,
|
|
2594
|
+
startTag,
|
|
2595
|
+
selfTag
|
|
2596
|
+
};
|
|
2597
|
+
}
|
|
2598
|
+
const pickSelf = hasSelf && (!hasOpen || selfIdx < openIdx);
|
|
2599
|
+
const tagStart = pickSelf ? selfIdx : openIdx;
|
|
2600
|
+
return { found: true, tagStart, selfClosing: pickSelf, startTag, selfTag };
|
|
1700
2601
|
}
|
|
1701
2602
|
function findToolCallsForName(text, toolName) {
|
|
2603
|
+
var _a;
|
|
1702
2604
|
const toolCalls = [];
|
|
1703
|
-
const startTag = `<${toolName}>`;
|
|
1704
2605
|
let searchIndex = 0;
|
|
1705
2606
|
while (searchIndex < text.length) {
|
|
1706
|
-
const
|
|
1707
|
-
if (
|
|
2607
|
+
const info = getNextTagInfo(text, toolName, searchIndex);
|
|
2608
|
+
if (!info.found) {
|
|
1708
2609
|
break;
|
|
1709
2610
|
}
|
|
1710
|
-
const
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
const
|
|
1714
|
-
toolCalls.push(
|
|
1715
|
-
|
|
2611
|
+
const { tagStart, selfClosing, startTag, selfTag } = info;
|
|
2612
|
+
if (selfClosing) {
|
|
2613
|
+
const endIndex = tagStart + selfTag.length;
|
|
2614
|
+
const segment = text.substring(tagStart, endIndex);
|
|
2615
|
+
toolCalls.push({
|
|
2616
|
+
toolName,
|
|
2617
|
+
startIndex: tagStart,
|
|
2618
|
+
endIndex,
|
|
2619
|
+
content: "",
|
|
2620
|
+
segment
|
|
2621
|
+
});
|
|
2622
|
+
searchIndex = endIndex;
|
|
2623
|
+
continue;
|
|
2624
|
+
}
|
|
2625
|
+
const contentStart = tagStart + startTag.length;
|
|
2626
|
+
const fullTagEnd = findClosingTagEndFlexible(text, contentStart, toolName);
|
|
2627
|
+
if (fullTagEnd !== -1 && fullTagEnd > contentStart) {
|
|
2628
|
+
const segment = text.substring(tagStart, fullTagEnd);
|
|
2629
|
+
const inner = (_a = (0, import_rxml2.extractRawInner)(segment, toolName)) != null ? _a : segment.substring(startTag.length, segment.lastIndexOf("<"));
|
|
2630
|
+
toolCalls.push({
|
|
2631
|
+
toolName,
|
|
2632
|
+
startIndex: tagStart,
|
|
2633
|
+
endIndex: fullTagEnd,
|
|
2634
|
+
content: inner,
|
|
2635
|
+
segment
|
|
2636
|
+
});
|
|
2637
|
+
searchIndex = fullTagEnd;
|
|
1716
2638
|
} else {
|
|
1717
|
-
searchIndex =
|
|
2639
|
+
searchIndex = contentStart;
|
|
1718
2640
|
}
|
|
1719
2641
|
}
|
|
1720
2642
|
return toolCalls;
|
|
@@ -1728,14 +2650,53 @@ function findToolCalls(text, toolNames) {
|
|
|
1728
2650
|
return toolCalls.sort((a, b) => a.startIndex - b.startIndex);
|
|
1729
2651
|
}
|
|
1730
2652
|
|
|
1731
|
-
// src/
|
|
1732
|
-
|
|
1733
|
-
|
|
2653
|
+
// src/generate-handler.ts
|
|
2654
|
+
var import_provider_utils3 = require("@ai-sdk/provider-utils");
|
|
2655
|
+
var import_rxml3 = require("@ai-sdk-tool/rxml");
|
|
2656
|
+
|
|
2657
|
+
// src/utils/on-error.ts
|
|
2658
|
+
function extractOnErrorOption(providerOptions) {
|
|
2659
|
+
var _a;
|
|
2660
|
+
if (providerOptions && typeof providerOptions === "object") {
|
|
2661
|
+
const onError = (_a = providerOptions.toolCallMiddleware) == null ? void 0 : _a.onError;
|
|
2662
|
+
return onError ? { onError } : void 0;
|
|
2663
|
+
}
|
|
2664
|
+
return;
|
|
2665
|
+
}
|
|
2666
|
+
|
|
2667
|
+
// src/utils/provider-options.ts
|
|
2668
|
+
var originalToolsSchema = {
|
|
2669
|
+
encode: encodeOriginalTools,
|
|
2670
|
+
decode: decodeOriginalTools
|
|
2671
|
+
};
|
|
2672
|
+
function encodeOriginalTools(tools) {
|
|
2673
|
+
return (tools == null ? void 0 : tools.map((t) => ({
|
|
2674
|
+
name: t.name,
|
|
2675
|
+
inputSchema: JSON.stringify(t.inputSchema)
|
|
2676
|
+
}))) || [];
|
|
2677
|
+
}
|
|
2678
|
+
function decodeOriginalTools(originalTools) {
|
|
2679
|
+
if (!originalTools) {
|
|
2680
|
+
return [];
|
|
2681
|
+
}
|
|
2682
|
+
return originalTools.map(
|
|
2683
|
+
(t) => ({
|
|
2684
|
+
type: "function",
|
|
2685
|
+
name: t.name,
|
|
2686
|
+
inputSchema: JSON.parse(t.inputSchema)
|
|
2687
|
+
})
|
|
2688
|
+
);
|
|
2689
|
+
}
|
|
2690
|
+
function extractToolNamesFromOriginalTools(originalTools) {
|
|
2691
|
+
return (originalTools == null ? void 0 : originalTools.map((t) => t.name)) || [];
|
|
2692
|
+
}
|
|
2693
|
+
function isToolChoiceActive(params) {
|
|
2694
|
+
var _a, _b, _c;
|
|
2695
|
+
const toolChoice = (_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.toolChoice;
|
|
2696
|
+
return !!(typeof params.providerOptions === "object" && params.providerOptions !== null && typeof ((_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware) === "object" && toolChoice && typeof toolChoice === "object" && (toolChoice.type === "tool" || toolChoice.type === "required"));
|
|
1734
2697
|
}
|
|
1735
2698
|
|
|
1736
2699
|
// src/generate-handler.ts
|
|
1737
|
-
var import_provider_utils4 = require("@ai-sdk/provider-utils");
|
|
1738
|
-
var import_rxml2 = require("@ai-sdk-tool/rxml");
|
|
1739
2700
|
function parseToolChoiceJson(text, providerOptions) {
|
|
1740
2701
|
var _a;
|
|
1741
2702
|
try {
|
|
@@ -1779,7 +2740,7 @@ async function handleToolChoice(doGenerate, params) {
|
|
|
1779
2740
|
}
|
|
1780
2741
|
const toolCall = {
|
|
1781
2742
|
type: "tool-call",
|
|
1782
|
-
toolCallId: (0,
|
|
2743
|
+
toolCallId: (0, import_provider_utils3.generateId)(),
|
|
1783
2744
|
toolName: parsed.name || "unknown",
|
|
1784
2745
|
input: JSON.stringify(parsed.arguments || {})
|
|
1785
2746
|
};
|
|
@@ -1898,15 +2859,20 @@ function fixToolCallWithSchema(part, tools) {
|
|
|
1898
2859
|
args = tc.input;
|
|
1899
2860
|
}
|
|
1900
2861
|
const schema = (_a = tools.find((t) => t.name === tc.toolName)) == null ? void 0 : _a.inputSchema;
|
|
1901
|
-
const coerced = (0,
|
|
2862
|
+
const coerced = (0, import_rxml3.coerceBySchema)(args, schema);
|
|
1902
2863
|
return {
|
|
1903
2864
|
...part,
|
|
1904
2865
|
input: JSON.stringify(coerced != null ? coerced : {})
|
|
1905
2866
|
};
|
|
1906
2867
|
}
|
|
1907
2868
|
|
|
2869
|
+
// src/protocols/tool-call-protocol.ts
|
|
2870
|
+
function isProtocolFactory(protocol) {
|
|
2871
|
+
return typeof protocol === "function";
|
|
2872
|
+
}
|
|
2873
|
+
|
|
1908
2874
|
// src/stream-handler.ts
|
|
1909
|
-
var
|
|
2875
|
+
var import_provider_utils4 = require("@ai-sdk/provider-utils");
|
|
1910
2876
|
function extractToolCallSegments(protocol, fullRawText, tools) {
|
|
1911
2877
|
const segments = protocol.extractToolCallSegments ? protocol.extractToolCallSegments({
|
|
1912
2878
|
text: fullRawText,
|
|
@@ -1943,7 +2909,7 @@ function handleDebugSummary(parsedToolCalls, origin, params) {
|
|
|
1943
2909
|
}
|
|
1944
2910
|
function createDebugSummaryTransform({
|
|
1945
2911
|
protocol,
|
|
1946
|
-
|
|
2912
|
+
getFullRawText,
|
|
1947
2913
|
tools,
|
|
1948
2914
|
params
|
|
1949
2915
|
}) {
|
|
@@ -1956,11 +2922,9 @@ function createDebugSummaryTransform({
|
|
|
1956
2922
|
}
|
|
1957
2923
|
if (part.type === "finish") {
|
|
1958
2924
|
try {
|
|
1959
|
-
const
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
tools
|
|
1963
|
-
);
|
|
2925
|
+
const raw = getFullRawText();
|
|
2926
|
+
logRawChunk(raw);
|
|
2927
|
+
const origin = extractToolCallSegments(protocol, raw, tools);
|
|
1964
2928
|
handleDebugSummary(parsedToolCalls, origin, params);
|
|
1965
2929
|
} catch (e) {
|
|
1966
2930
|
}
|
|
@@ -2058,7 +3022,7 @@ async function wrapStream({
|
|
|
2058
3022
|
const withSummary = parsed.pipeThrough(
|
|
2059
3023
|
createDebugSummaryTransform({
|
|
2060
3024
|
protocol,
|
|
2061
|
-
fullRawText,
|
|
3025
|
+
getFullRawText: () => fullRawText,
|
|
2062
3026
|
tools,
|
|
2063
3027
|
params
|
|
2064
3028
|
})
|
|
@@ -2092,19 +3056,26 @@ async function toolChoiceStream({
|
|
|
2092
3056
|
}
|
|
2093
3057
|
const toolCallChunk = {
|
|
2094
3058
|
type: "tool-call",
|
|
2095
|
-
toolCallId: (0,
|
|
3059
|
+
toolCallId: (0, import_provider_utils4.generateId)(),
|
|
2096
3060
|
toolName: toolJson.name || "unknown",
|
|
2097
3061
|
input: JSON.stringify(toolJson.arguments || {})
|
|
2098
3062
|
};
|
|
2099
3063
|
const finishChunk = {
|
|
2100
3064
|
type: "finish",
|
|
2101
|
-
usage: (result == null ? void 0 : result.usage) ||
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
3065
|
+
usage: (result == null ? void 0 : result.usage) || {
|
|
3066
|
+
inputTokens: {
|
|
3067
|
+
total: 0,
|
|
3068
|
+
noCache: void 0,
|
|
3069
|
+
cacheRead: void 0,
|
|
3070
|
+
cacheWrite: void 0
|
|
3071
|
+
},
|
|
3072
|
+
outputTokens: {
|
|
3073
|
+
total: 0,
|
|
3074
|
+
text: void 0,
|
|
3075
|
+
reasoning: void 0
|
|
3076
|
+
}
|
|
2106
3077
|
},
|
|
2107
|
-
finishReason: "tool-calls"
|
|
3078
|
+
finishReason: { unified: "tool-calls", raw: void 0 }
|
|
2108
3079
|
};
|
|
2109
3080
|
const stream = new ReadableStream({
|
|
2110
3081
|
start(controller) {
|
|
@@ -2138,26 +3109,106 @@ async function toolChoiceStream({
|
|
|
2138
3109
|
};
|
|
2139
3110
|
}
|
|
2140
3111
|
|
|
3112
|
+
// src/utils/dynamic-tool-schema.ts
|
|
3113
|
+
function createDynamicIfThenElseSchema(tools) {
|
|
3114
|
+
let currentSchema = {};
|
|
3115
|
+
const toolNames = [];
|
|
3116
|
+
for (let i = tools.length - 1; i >= 0; i -= 1) {
|
|
3117
|
+
const tool = tools[i];
|
|
3118
|
+
if (tool.type === "provider") {
|
|
3119
|
+
throw new Error(
|
|
3120
|
+
"Provider tools are not supported by this middleware. Please use function tools."
|
|
3121
|
+
);
|
|
3122
|
+
}
|
|
3123
|
+
toolNames.unshift(tool.name);
|
|
3124
|
+
const toolCondition = {
|
|
3125
|
+
if: {
|
|
3126
|
+
properties: {
|
|
3127
|
+
name: {
|
|
3128
|
+
const: tool.name
|
|
3129
|
+
}
|
|
3130
|
+
},
|
|
3131
|
+
required: ["name"]
|
|
3132
|
+
},
|
|
3133
|
+
// biome-ignore lint/suspicious/noThenProperty: JSON Schema uses 'then' as a keyword
|
|
3134
|
+
then: {
|
|
3135
|
+
properties: {
|
|
3136
|
+
name: {
|
|
3137
|
+
const: tool.name
|
|
3138
|
+
},
|
|
3139
|
+
arguments: tool.inputSchema
|
|
3140
|
+
},
|
|
3141
|
+
required: ["name", "arguments"]
|
|
3142
|
+
}
|
|
3143
|
+
};
|
|
3144
|
+
if (Object.keys(currentSchema).length > 0) {
|
|
3145
|
+
toolCondition.else = currentSchema;
|
|
3146
|
+
}
|
|
3147
|
+
currentSchema = toolCondition;
|
|
3148
|
+
}
|
|
3149
|
+
return {
|
|
3150
|
+
type: "object",
|
|
3151
|
+
// Explicitly specify type as "object"
|
|
3152
|
+
properties: {
|
|
3153
|
+
name: {
|
|
3154
|
+
type: "string",
|
|
3155
|
+
description: "Name of the tool to call",
|
|
3156
|
+
enum: toolNames
|
|
3157
|
+
},
|
|
3158
|
+
arguments: {
|
|
3159
|
+
type: "object",
|
|
3160
|
+
// By default, arguments is also specified as object type
|
|
3161
|
+
description: "Argument object to be passed to the tool"
|
|
3162
|
+
}
|
|
3163
|
+
},
|
|
3164
|
+
required: ["name", "arguments"],
|
|
3165
|
+
...currentSchema
|
|
3166
|
+
};
|
|
3167
|
+
}
|
|
3168
|
+
|
|
2141
3169
|
// src/transform-handler.ts
|
|
2142
|
-
function buildFinalPrompt(systemPrompt, processedPrompt) {
|
|
2143
|
-
|
|
2144
|
-
if (
|
|
3170
|
+
function buildFinalPrompt(systemPrompt, processedPrompt, placement) {
|
|
3171
|
+
const systemIndex = processedPrompt.findIndex((m) => m.role === "system");
|
|
3172
|
+
if (systemIndex !== -1) {
|
|
3173
|
+
const existing = processedPrompt[systemIndex].content;
|
|
3174
|
+
let existingText = "";
|
|
3175
|
+
if (typeof existing === "string") {
|
|
3176
|
+
existingText = existing;
|
|
3177
|
+
} else if (Array.isArray(existing)) {
|
|
3178
|
+
existingText = existing.map((p) => {
|
|
3179
|
+
var _a;
|
|
3180
|
+
return (p == null ? void 0 : p.type) === "text" ? (_a = p.text) != null ? _a : "" : "";
|
|
3181
|
+
}).filter(Boolean).join("\n");
|
|
3182
|
+
} else {
|
|
3183
|
+
existingText = String(existing != null ? existing : "");
|
|
3184
|
+
}
|
|
3185
|
+
const mergedContent = placement === "first" ? `${systemPrompt}
|
|
3186
|
+
|
|
3187
|
+
${existingText}` : `${existingText}
|
|
3188
|
+
|
|
3189
|
+
${systemPrompt}`;
|
|
3190
|
+
return processedPrompt.map(
|
|
3191
|
+
(m, idx) => idx === systemIndex ? {
|
|
3192
|
+
...m,
|
|
3193
|
+
content: mergedContent
|
|
3194
|
+
} : m
|
|
3195
|
+
);
|
|
3196
|
+
}
|
|
3197
|
+
if (placement === "first") {
|
|
2145
3198
|
return [
|
|
2146
3199
|
{
|
|
2147
3200
|
role: "system",
|
|
2148
|
-
content:
|
|
2149
|
-
|
|
2150
|
-
${processedPrompt[0].content}`
|
|
3201
|
+
content: systemPrompt
|
|
2151
3202
|
},
|
|
2152
|
-
...processedPrompt
|
|
3203
|
+
...processedPrompt
|
|
2153
3204
|
];
|
|
2154
3205
|
}
|
|
2155
3206
|
return [
|
|
3207
|
+
...processedPrompt,
|
|
2156
3208
|
{
|
|
2157
3209
|
role: "system",
|
|
2158
3210
|
content: systemPrompt
|
|
2159
|
-
}
|
|
2160
|
-
...processedPrompt
|
|
3211
|
+
}
|
|
2161
3212
|
];
|
|
2162
3213
|
}
|
|
2163
3214
|
function buildBaseReturnParams(params, finalPrompt, functionTools) {
|
|
@@ -2257,7 +3308,8 @@ function handleToolChoiceRequired(params, baseReturnParams, functionTools) {
|
|
|
2257
3308
|
function transformParams({
|
|
2258
3309
|
params,
|
|
2259
3310
|
protocol,
|
|
2260
|
-
toolSystemPromptTemplate
|
|
3311
|
+
toolSystemPromptTemplate,
|
|
3312
|
+
placement = "first"
|
|
2261
3313
|
}) {
|
|
2262
3314
|
var _a, _b, _c, _d, _e;
|
|
2263
3315
|
const resolvedProtocol = isProtocolFactory(protocol) ? protocol() : protocol;
|
|
@@ -2273,7 +3325,11 @@ function transformParams({
|
|
|
2273
3325
|
resolvedProtocol,
|
|
2274
3326
|
extractOnErrorOption(params.providerOptions)
|
|
2275
3327
|
);
|
|
2276
|
-
const finalPrompt = buildFinalPrompt(
|
|
3328
|
+
const finalPrompt = buildFinalPrompt(
|
|
3329
|
+
systemPrompt,
|
|
3330
|
+
processedPrompt,
|
|
3331
|
+
placement
|
|
3332
|
+
);
|
|
2277
3333
|
const baseReturnParams = buildBaseReturnParams(
|
|
2278
3334
|
params,
|
|
2279
3335
|
finalPrompt,
|
|
@@ -2350,7 +3406,10 @@ function processMessage(message, resolvedProtocol, providerOptions) {
|
|
|
2350
3406
|
};
|
|
2351
3407
|
}
|
|
2352
3408
|
if (message.role === "tool") {
|
|
2353
|
-
|
|
3409
|
+
const toolResultParts = message.content.filter(
|
|
3410
|
+
(part) => part.type === "tool-result"
|
|
3411
|
+
);
|
|
3412
|
+
return processToolMessage(toolResultParts, resolvedProtocol);
|
|
2354
3413
|
}
|
|
2355
3414
|
return message;
|
|
2356
3415
|
}
|
|
@@ -2425,7 +3484,8 @@ function convertToolPrompt(prompt, resolvedProtocol, providerOptions) {
|
|
|
2425
3484
|
// src/tool-call-middleware.ts
|
|
2426
3485
|
function createToolMiddleware({
|
|
2427
3486
|
protocol,
|
|
2428
|
-
toolSystemPromptTemplate
|
|
3487
|
+
toolSystemPromptTemplate,
|
|
3488
|
+
placement = "last"
|
|
2429
3489
|
}) {
|
|
2430
3490
|
const resolvedProtocol = isProtocolFactory(protocol) ? protocol() : protocol;
|
|
2431
3491
|
return {
|
|
@@ -2452,6 +3512,7 @@ function createToolMiddleware({
|
|
|
2452
3512
|
transformParams: async ({ params }) => transformParams({
|
|
2453
3513
|
protocol: resolvedProtocol,
|
|
2454
3514
|
toolSystemPromptTemplate,
|
|
3515
|
+
placement,
|
|
2455
3516
|
params
|
|
2456
3517
|
})
|
|
2457
3518
|
};
|
|
@@ -2497,6 +3558,7 @@ For each function call return a json object with function name and arguments wit
|
|
|
2497
3558
|
});
|
|
2498
3559
|
var morphXmlToolMiddleware = createToolMiddleware({
|
|
2499
3560
|
protocol: morphXmlProtocol,
|
|
3561
|
+
placement: "last",
|
|
2500
3562
|
toolSystemPromptTemplate(tools) {
|
|
2501
3563
|
return `You are a function calling AI model.
|
|
2502
3564
|
|
|
@@ -2520,11 +3582,16 @@ Available functions are listed inside <tools></tools>.
|
|
|
2520
3582
|
});
|
|
2521
3583
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2522
3584
|
0 && (module.exports = {
|
|
2523
|
-
|
|
3585
|
+
applyHeuristicPipeline,
|
|
3586
|
+
balanceTagsHeuristic,
|
|
2524
3587
|
createDynamicIfThenElseSchema,
|
|
3588
|
+
createIntermediateCall,
|
|
2525
3589
|
createToolMiddleware,
|
|
2526
3590
|
decodeOriginalTools,
|
|
3591
|
+
dedupeShellStringTagsHeuristic,
|
|
3592
|
+
defaultPipelineConfig,
|
|
2527
3593
|
encodeOriginalTools,
|
|
3594
|
+
escapeInvalidLtHeuristic,
|
|
2528
3595
|
escapeRegExp,
|
|
2529
3596
|
extractOnErrorOption,
|
|
2530
3597
|
extractToolNamesFromOriginalTools,
|
|
@@ -2537,13 +3604,17 @@ Available functions are listed inside <tools></tools>.
|
|
|
2537
3604
|
isToolChoiceActive,
|
|
2538
3605
|
isToolResultPart,
|
|
2539
3606
|
jsonMixProtocol,
|
|
3607
|
+
logParseFailure,
|
|
2540
3608
|
logParsedChunk,
|
|
2541
3609
|
logParsedSummary,
|
|
2542
3610
|
logRawChunk,
|
|
3611
|
+
mergePipelineConfigs,
|
|
2543
3612
|
morphXmlProtocol,
|
|
2544
3613
|
morphXmlToolMiddleware,
|
|
3614
|
+
normalizeCloseTagsHeuristic,
|
|
2545
3615
|
originalToolsSchema,
|
|
2546
3616
|
parseRJSON,
|
|
3617
|
+
repairAgainstSchemaHeuristic,
|
|
2547
3618
|
stringifyRJSON,
|
|
2548
3619
|
transformRJSON
|
|
2549
3620
|
});
|