@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/community.cjs
CHANGED
|
@@ -25,11 +25,8 @@ __export(community_exports, {
|
|
|
25
25
|
});
|
|
26
26
|
module.exports = __toCommonJS(community_exports);
|
|
27
27
|
|
|
28
|
-
// src/protocols/dummy-protocol.ts
|
|
29
|
-
var import_provider_utils = require("@ai-sdk/provider-utils");
|
|
30
|
-
|
|
31
28
|
// src/protocols/json-mix-protocol.ts
|
|
32
|
-
var
|
|
29
|
+
var import_provider_utils = require("@ai-sdk/provider-utils");
|
|
33
30
|
|
|
34
31
|
// src/utils/debug.ts
|
|
35
32
|
var LINE_SPLIT_REGEX = /\r?\n/;
|
|
@@ -77,6 +74,7 @@ var cBgGreen = color(ANSI_BG_GREEN);
|
|
|
77
74
|
var cInverse = color(ANSI_INVERSE);
|
|
78
75
|
var cUnderline = color(ANSI_UNDERLINE);
|
|
79
76
|
var cBold = color(ANSI_BOLD);
|
|
77
|
+
var MAX_SNIPPET_LENGTH = 800;
|
|
80
78
|
function safeStringify(value) {
|
|
81
79
|
try {
|
|
82
80
|
return `
|
|
@@ -85,6 +83,41 @@ ${typeof value === "string" ? value : JSON.stringify(value, null, 2)}`;
|
|
|
85
83
|
return String(value);
|
|
86
84
|
}
|
|
87
85
|
}
|
|
86
|
+
function formatError(error) {
|
|
87
|
+
if (error instanceof Error) {
|
|
88
|
+
const stack = error.stack ? `
|
|
89
|
+
${error.stack}` : "";
|
|
90
|
+
return `
|
|
91
|
+
${error.name}: ${error.message}${stack}`;
|
|
92
|
+
}
|
|
93
|
+
return safeStringify(error);
|
|
94
|
+
}
|
|
95
|
+
function truncateSnippet(snippet) {
|
|
96
|
+
if (snippet.length <= MAX_SNIPPET_LENGTH) {
|
|
97
|
+
return snippet;
|
|
98
|
+
}
|
|
99
|
+
return `${snippet.slice(0, MAX_SNIPPET_LENGTH)}
|
|
100
|
+
\u2026[truncated ${snippet.length - MAX_SNIPPET_LENGTH} chars]`;
|
|
101
|
+
}
|
|
102
|
+
function logParseFailure({
|
|
103
|
+
phase,
|
|
104
|
+
reason,
|
|
105
|
+
snippet,
|
|
106
|
+
error
|
|
107
|
+
}) {
|
|
108
|
+
if (getDebugLevel() !== "parse") {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const label = cBgBlue(`[${phase}]`);
|
|
112
|
+
console.log(cGray("[debug:mw:fail]"), label, cYellow(reason));
|
|
113
|
+
if (snippet) {
|
|
114
|
+
const formatted = truncateSnippet(snippet);
|
|
115
|
+
console.log(cGray("[debug:mw:fail:snippet]"), formatted);
|
|
116
|
+
}
|
|
117
|
+
if (error) {
|
|
118
|
+
console.log(cGray("[debug:mw:fail:error]"), cCyan(formatError(error)));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
88
121
|
function logRawChunk(part) {
|
|
89
122
|
console.log(cGray("[debug:mw:raw]"), cYellow(safeStringify(part)));
|
|
90
123
|
}
|
|
@@ -150,63 +183,6 @@ ${rendered}`);
|
|
|
150
183
|
}
|
|
151
184
|
}
|
|
152
185
|
|
|
153
|
-
// src/utils/dynamic-tool-schema.ts
|
|
154
|
-
function createDynamicIfThenElseSchema(tools) {
|
|
155
|
-
let currentSchema = {};
|
|
156
|
-
const toolNames = [];
|
|
157
|
-
for (let i = tools.length - 1; i >= 0; i -= 1) {
|
|
158
|
-
const tool = tools[i];
|
|
159
|
-
if (tool.type === "provider-defined") {
|
|
160
|
-
throw new Error(
|
|
161
|
-
"Provider-defined tools are not supported by this middleware. Please use custom tools."
|
|
162
|
-
);
|
|
163
|
-
}
|
|
164
|
-
toolNames.unshift(tool.name);
|
|
165
|
-
const toolCondition = {
|
|
166
|
-
if: {
|
|
167
|
-
properties: {
|
|
168
|
-
name: {
|
|
169
|
-
const: tool.name
|
|
170
|
-
}
|
|
171
|
-
},
|
|
172
|
-
required: ["name"]
|
|
173
|
-
},
|
|
174
|
-
// biome-ignore lint/suspicious/noThenProperty: JSON Schema uses 'then' as a keyword
|
|
175
|
-
then: {
|
|
176
|
-
properties: {
|
|
177
|
-
name: {
|
|
178
|
-
const: tool.name
|
|
179
|
-
},
|
|
180
|
-
arguments: tool.inputSchema
|
|
181
|
-
},
|
|
182
|
-
required: ["name", "arguments"]
|
|
183
|
-
}
|
|
184
|
-
};
|
|
185
|
-
if (Object.keys(currentSchema).length > 0) {
|
|
186
|
-
toolCondition.else = currentSchema;
|
|
187
|
-
}
|
|
188
|
-
currentSchema = toolCondition;
|
|
189
|
-
}
|
|
190
|
-
return {
|
|
191
|
-
type: "object",
|
|
192
|
-
// Explicitly specify type as "object"
|
|
193
|
-
properties: {
|
|
194
|
-
name: {
|
|
195
|
-
type: "string",
|
|
196
|
-
description: "Name of the tool to call",
|
|
197
|
-
enum: toolNames
|
|
198
|
-
},
|
|
199
|
-
arguments: {
|
|
200
|
-
type: "object",
|
|
201
|
-
// By default, arguments is also specified as object type
|
|
202
|
-
description: "Argument object to be passed to the tool"
|
|
203
|
-
}
|
|
204
|
-
},
|
|
205
|
-
required: ["name", "arguments"],
|
|
206
|
-
...currentSchema
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
|
-
|
|
210
186
|
// src/utils/get-potential-start-index.ts
|
|
211
187
|
function getPotentialStartIndex(text, searchedText) {
|
|
212
188
|
if (searchedText.length === 0) {
|
|
@@ -225,57 +201,12 @@ function getPotentialStartIndex(text, searchedText) {
|
|
|
225
201
|
return null;
|
|
226
202
|
}
|
|
227
203
|
|
|
228
|
-
// src/utils/on-error.ts
|
|
229
|
-
function extractOnErrorOption(providerOptions) {
|
|
230
|
-
var _a;
|
|
231
|
-
if (providerOptions && typeof providerOptions === "object") {
|
|
232
|
-
const onError = (_a = providerOptions.toolCallMiddleware) == null ? void 0 : _a.onError;
|
|
233
|
-
return onError ? { onError } : void 0;
|
|
234
|
-
}
|
|
235
|
-
return;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// src/utils/provider-options.ts
|
|
239
|
-
var originalToolsSchema = {
|
|
240
|
-
encode: encodeOriginalTools,
|
|
241
|
-
decode: decodeOriginalTools
|
|
242
|
-
};
|
|
243
|
-
function encodeOriginalTools(tools) {
|
|
244
|
-
return (tools == null ? void 0 : tools.map((t) => ({
|
|
245
|
-
name: t.name,
|
|
246
|
-
inputSchema: JSON.stringify(t.inputSchema)
|
|
247
|
-
}))) || [];
|
|
248
|
-
}
|
|
249
|
-
function decodeOriginalTools(originalTools) {
|
|
250
|
-
if (!originalTools) {
|
|
251
|
-
return [];
|
|
252
|
-
}
|
|
253
|
-
return originalTools.map(
|
|
254
|
-
(t) => ({
|
|
255
|
-
type: "function",
|
|
256
|
-
name: t.name,
|
|
257
|
-
inputSchema: JSON.parse(t.inputSchema)
|
|
258
|
-
})
|
|
259
|
-
);
|
|
260
|
-
}
|
|
261
|
-
function isToolChoiceActive(params) {
|
|
262
|
-
var _a, _b, _c;
|
|
263
|
-
const toolChoice = (_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.toolChoice;
|
|
264
|
-
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"));
|
|
265
|
-
}
|
|
266
|
-
|
|
267
204
|
// src/utils/regex.ts
|
|
268
205
|
function escapeRegExp(literal) {
|
|
269
206
|
return literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
270
207
|
}
|
|
271
208
|
|
|
272
209
|
// src/utils/robust-json.ts
|
|
273
|
-
var robust_json_exports = {};
|
|
274
|
-
__export(robust_json_exports, {
|
|
275
|
-
parse: () => parse,
|
|
276
|
-
stringify: () => stringify,
|
|
277
|
-
transform: () => transform
|
|
278
|
-
});
|
|
279
210
|
var WHITESPACE_TEST_REGEX = /\s/;
|
|
280
211
|
var WHITESPACE_REGEX = /^\s+/;
|
|
281
212
|
var OBJECT_START_REGEX = /^\{/;
|
|
@@ -516,11 +447,6 @@ function stripTrailingComma(tokens) {
|
|
|
516
447
|
});
|
|
517
448
|
return res;
|
|
518
449
|
}
|
|
519
|
-
function transform(text) {
|
|
520
|
-
let tokens = lexer(text);
|
|
521
|
-
tokens = stripTrailingComma(tokens);
|
|
522
|
-
return tokens.reduce((str, token) => str + token.match, "");
|
|
523
|
-
}
|
|
524
450
|
function popToken(tokens, state) {
|
|
525
451
|
var _a, _b;
|
|
526
452
|
const token = tokens[state.pos];
|
|
@@ -916,38 +842,6 @@ function parse(text, optsOrReviver) {
|
|
|
916
842
|
}
|
|
917
843
|
return parseWithTransform(text, options);
|
|
918
844
|
}
|
|
919
|
-
function stringifyPair(obj, key) {
|
|
920
|
-
return `${JSON.stringify(key)}:${stringify(obj[key])}`;
|
|
921
|
-
}
|
|
922
|
-
function stringify(obj) {
|
|
923
|
-
const type = typeof obj;
|
|
924
|
-
if (type === "string" || type === "number" || type === "boolean" || obj === null) {
|
|
925
|
-
return JSON.stringify(obj);
|
|
926
|
-
}
|
|
927
|
-
if (type === "undefined") {
|
|
928
|
-
return "null";
|
|
929
|
-
}
|
|
930
|
-
if (Array.isArray(obj)) {
|
|
931
|
-
const elements = obj.map(stringify).join(",");
|
|
932
|
-
return `[${elements}]`;
|
|
933
|
-
}
|
|
934
|
-
if (type === "object") {
|
|
935
|
-
const keys = Object.keys(obj);
|
|
936
|
-
keys.sort();
|
|
937
|
-
const pairs = keys.map((key) => stringifyPair(obj, key)).join(",");
|
|
938
|
-
return `{${pairs}}`;
|
|
939
|
-
}
|
|
940
|
-
return "null";
|
|
941
|
-
}
|
|
942
|
-
|
|
943
|
-
// src/utils/type-guards.ts
|
|
944
|
-
function isToolCallContent(content) {
|
|
945
|
-
return content.type === "tool-call" && typeof content.toolName === "string" && // input may be a JSON string or an already-parsed object depending on provider/runtime
|
|
946
|
-
(typeof content.input === "string" || typeof content.input === "object");
|
|
947
|
-
}
|
|
948
|
-
function hasInputProperty(obj) {
|
|
949
|
-
return typeof obj === "object" && obj !== null && "input" in obj;
|
|
950
|
-
}
|
|
951
845
|
|
|
952
846
|
// src/protocols/json-mix-protocol.ts
|
|
953
847
|
function processToolCallJson(toolCallJson, fullMatch, processedElements, options) {
|
|
@@ -956,11 +850,17 @@ function processToolCallJson(toolCallJson, fullMatch, processedElements, options
|
|
|
956
850
|
const parsedToolCall = parse(toolCallJson);
|
|
957
851
|
processedElements.push({
|
|
958
852
|
type: "tool-call",
|
|
959
|
-
toolCallId: (0,
|
|
853
|
+
toolCallId: (0, import_provider_utils.generateId)(),
|
|
960
854
|
toolName: parsedToolCall.name,
|
|
961
855
|
input: JSON.stringify((_a = parsedToolCall.arguments) != null ? _a : {})
|
|
962
856
|
});
|
|
963
857
|
} catch (error) {
|
|
858
|
+
logParseFailure({
|
|
859
|
+
phase: "generated-text",
|
|
860
|
+
reason: "Failed to parse tool call JSON segment",
|
|
861
|
+
snippet: fullMatch,
|
|
862
|
+
error
|
|
863
|
+
});
|
|
964
864
|
if (options == null ? void 0 : options.onError) {
|
|
965
865
|
options.onError(
|
|
966
866
|
"Could not process JSON tool call, keeping original text.",
|
|
@@ -993,7 +893,7 @@ function flushBuffer(state, controller, toolCallStart) {
|
|
|
993
893
|
return;
|
|
994
894
|
}
|
|
995
895
|
if (!state.currentTextId) {
|
|
996
|
-
state.currentTextId = (0,
|
|
896
|
+
state.currentTextId = (0, import_provider_utils.generateId)();
|
|
997
897
|
controller.enqueue({ type: "text-start", id: state.currentTextId });
|
|
998
898
|
state.hasEmittedTextStart = true;
|
|
999
899
|
}
|
|
@@ -1016,7 +916,12 @@ function emitIncompleteToolCall(state, controller, toolCallStart) {
|
|
|
1016
916
|
if (!state.currentToolCallJson) {
|
|
1017
917
|
return;
|
|
1018
918
|
}
|
|
1019
|
-
|
|
919
|
+
logParseFailure({
|
|
920
|
+
phase: "stream",
|
|
921
|
+
reason: "Incomplete streaming tool call segment emitted as text",
|
|
922
|
+
snippet: `${toolCallStart}${state.currentToolCallJson}`
|
|
923
|
+
});
|
|
924
|
+
const errorId = (0, import_provider_utils.generateId)();
|
|
1020
925
|
controller.enqueue({ type: "text-start", id: errorId });
|
|
1021
926
|
controller.enqueue({
|
|
1022
927
|
type: "text-delta",
|
|
@@ -1040,7 +945,7 @@ function publishText(text, state, controller) {
|
|
|
1040
945
|
state.currentToolCallJson += text;
|
|
1041
946
|
} else if (text.length > 0) {
|
|
1042
947
|
if (!state.currentTextId) {
|
|
1043
|
-
state.currentTextId = (0,
|
|
948
|
+
state.currentTextId = (0, import_provider_utils.generateId)();
|
|
1044
949
|
controller.enqueue({ type: "text-start", id: state.currentTextId });
|
|
1045
950
|
state.hasEmittedTextStart = true;
|
|
1046
951
|
}
|
|
@@ -1055,16 +960,22 @@ function emitToolCall(context) {
|
|
|
1055
960
|
var _a;
|
|
1056
961
|
const { state, controller, toolCallStart, toolCallEnd, options } = context;
|
|
1057
962
|
try {
|
|
1058
|
-
const parsedToolCall =
|
|
963
|
+
const parsedToolCall = parse(state.currentToolCallJson);
|
|
1059
964
|
closeTextBlock(state, controller);
|
|
1060
965
|
controller.enqueue({
|
|
1061
966
|
type: "tool-call",
|
|
1062
|
-
toolCallId: (0,
|
|
967
|
+
toolCallId: (0, import_provider_utils.generateId)(),
|
|
1063
968
|
toolName: parsedToolCall.name,
|
|
1064
969
|
input: JSON.stringify((_a = parsedToolCall.arguments) != null ? _a : {})
|
|
1065
970
|
});
|
|
1066
|
-
} catch (
|
|
1067
|
-
|
|
971
|
+
} catch (error) {
|
|
972
|
+
logParseFailure({
|
|
973
|
+
phase: "stream",
|
|
974
|
+
reason: "Failed to parse streaming tool call JSON segment",
|
|
975
|
+
snippet: `${toolCallStart}${state.currentToolCallJson}${toolCallEnd}`,
|
|
976
|
+
error
|
|
977
|
+
});
|
|
978
|
+
const errorId = (0, import_provider_utils.generateId)();
|
|
1068
979
|
controller.enqueue({ type: "text-start", id: errorId });
|
|
1069
980
|
controller.enqueue({
|
|
1070
981
|
type: "text-delta",
|
|
@@ -1229,162 +1140,896 @@ var jsonMixProtocol = ({
|
|
|
1229
1140
|
});
|
|
1230
1141
|
|
|
1231
1142
|
// src/protocols/morph-xml-protocol.ts
|
|
1232
|
-
var
|
|
1233
|
-
var
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
processedElements.push({ type: "text", text: textSegment });
|
|
1240
|
-
}
|
|
1143
|
+
var import_provider_utils2 = require("@ai-sdk/provider-utils");
|
|
1144
|
+
var import_rxml2 = require("@ai-sdk-tool/rxml");
|
|
1145
|
+
|
|
1146
|
+
// src/heuristics/engine.ts
|
|
1147
|
+
function applyRawSegmentUpdate(current, result) {
|
|
1148
|
+
if (result.rawSegment !== void 0) {
|
|
1149
|
+
return { ...current, rawSegment: result.rawSegment };
|
|
1241
1150
|
}
|
|
1242
|
-
return
|
|
1151
|
+
return current;
|
|
1243
1152
|
}
|
|
1244
|
-
function
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
try {
|
|
1248
|
-
const toolSchema = getToolSchema(tools, toolCall.toolName);
|
|
1249
|
-
const parsed = (0, import_rxml.parse)(toolCall.content, toolSchema, {
|
|
1250
|
-
onError: options == null ? void 0 : options.onError,
|
|
1251
|
-
// Disable HTML self-closing tag behavior to allow base, meta, link etc. as regular tags
|
|
1252
|
-
noChildNodes: []
|
|
1253
|
-
});
|
|
1254
|
-
processedElements.push({
|
|
1255
|
-
type: "tool-call",
|
|
1256
|
-
toolCallId: (0, import_provider_utils3.generateId)(),
|
|
1257
|
-
toolName: toolCall.toolName,
|
|
1258
|
-
input: JSON.stringify(parsed)
|
|
1259
|
-
});
|
|
1260
|
-
} catch (error) {
|
|
1261
|
-
const originalCallText = text.substring(
|
|
1262
|
-
toolCall.startIndex,
|
|
1263
|
-
toolCall.endIndex
|
|
1264
|
-
);
|
|
1265
|
-
const message = `Could not process XML tool call, keeping original text: ${originalCallText}`;
|
|
1266
|
-
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, message, {
|
|
1267
|
-
toolCall: originalCallText,
|
|
1268
|
-
toolName: toolCall.toolName,
|
|
1269
|
-
error
|
|
1270
|
-
});
|
|
1271
|
-
processedElements.push({ type: "text", text: originalCallText });
|
|
1153
|
+
function applyParsedUpdate(current, result) {
|
|
1154
|
+
if (result.parsed !== void 0) {
|
|
1155
|
+
return { ...current, parsed: result.parsed };
|
|
1272
1156
|
}
|
|
1157
|
+
return current;
|
|
1273
1158
|
}
|
|
1274
|
-
function
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
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
|
+
};
|
|
1280
1168
|
}
|
|
1169
|
+
return current;
|
|
1281
1170
|
}
|
|
1282
|
-
function
|
|
1283
|
-
|
|
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
|
+
}
|
|
1284
1175
|
try {
|
|
1285
|
-
const
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
}
|
|
1290
|
-
flushText(ctrl);
|
|
1291
|
-
ctrl.enqueue({
|
|
1292
|
-
type: "tool-call",
|
|
1293
|
-
toolCallId: (0, import_provider_utils3.generateId)(),
|
|
1294
|
-
toolName: currentToolCall.name,
|
|
1295
|
-
input: JSON.stringify(parsed)
|
|
1296
|
-
});
|
|
1176
|
+
const reparsed = parse4(result.rawSegment, current.schema);
|
|
1177
|
+
return {
|
|
1178
|
+
state: { ...current, parsed: reparsed, errors: [] },
|
|
1179
|
+
newCount: reparseCount + 1
|
|
1180
|
+
};
|
|
1297
1181
|
} catch (error) {
|
|
1298
|
-
|
|
1299
|
-
error,
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
options,
|
|
1303
|
-
ctrl,
|
|
1304
|
-
flushText
|
|
1305
|
-
});
|
|
1182
|
+
return {
|
|
1183
|
+
state: { ...current, errors: [...current.errors, error] },
|
|
1184
|
+
newCount: reparseCount + 1
|
|
1185
|
+
};
|
|
1306
1186
|
}
|
|
1307
1187
|
}
|
|
1308
|
-
function
|
|
1188
|
+
function executePhase(ctx, heuristics, options) {
|
|
1309
1189
|
var _a;
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
const
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
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
|
+
}
|
|
1320
1213
|
}
|
|
1321
|
-
|
|
1322
|
-
toolCall: originalCallText,
|
|
1323
|
-
toolName: currentToolCall.name,
|
|
1324
|
-
error
|
|
1325
|
-
});
|
|
1326
|
-
flushText(ctrl, originalCallText);
|
|
1214
|
+
return current;
|
|
1327
1215
|
}
|
|
1328
|
-
function
|
|
1329
|
-
let
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
}
|
|
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] };
|
|
1339
1227
|
}
|
|
1340
1228
|
}
|
|
1341
|
-
|
|
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;
|
|
1342
1236
|
}
|
|
1343
|
-
function
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
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
|
+
}
|
|
1350
1267
|
}
|
|
1351
|
-
return
|
|
1268
|
+
return result;
|
|
1352
1269
|
}
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1270
|
+
|
|
1271
|
+
// src/heuristics/xml-defaults.ts
|
|
1272
|
+
var import_rxml = require("@ai-sdk-tool/rxml");
|
|
1273
|
+
var MALFORMED_CLOSE_RE_G = /<\/\s+([A-Za-z0-9_:-]+)\s*>/g;
|
|
1274
|
+
var MALFORMED_CLOSE_RE = /<\/\s+([A-Za-z0-9_:-]+)\s*>/;
|
|
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_:]/;
|
|
1279
|
+
var STEP_TAG_RE = /<step>([\s\S]*?)<\/step>/i;
|
|
1280
|
+
var STATUS_TAG_RE = /<status>([\s\S]*?)<\/status>/i;
|
|
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);
|
|
1364
|
+
}
|
|
1365
|
+
function escapeInvalidLt(xml) {
|
|
1366
|
+
const len = xml.length;
|
|
1367
|
+
let out = "";
|
|
1368
|
+
for (let i = 0; i < len; i += 1) {
|
|
1369
|
+
const ch = xml[i];
|
|
1370
|
+
if (ch === "<") {
|
|
1371
|
+
const next = i + 1 < len ? xml[i + 1] : "";
|
|
1372
|
+
const isValidStart = NAME_START_CHAR_RE.test(next) || next === "/" || next === "!" || next === "?";
|
|
1373
|
+
const isIndexTag = !isValidStart && isIndexTagAt(xml, i);
|
|
1374
|
+
if (!(isValidStart || isIndexTag)) {
|
|
1375
|
+
out += "<";
|
|
1376
|
+
continue;
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
out += ch;
|
|
1380
|
+
}
|
|
1381
|
+
return out;
|
|
1382
|
+
}
|
|
1383
|
+
function balanceTags(xml) {
|
|
1384
|
+
const src = xml.replace(MALFORMED_CLOSE_RE_G, "</$1>").replace(STATUS_TO_STEP_BOUNDARY_RE, "</status></step><step>");
|
|
1385
|
+
let i = 0;
|
|
1386
|
+
const len = src.length;
|
|
1387
|
+
const out = [];
|
|
1388
|
+
const stack = [];
|
|
1389
|
+
while (i < len) {
|
|
1390
|
+
const lt = src.indexOf("<", i);
|
|
1391
|
+
if (lt === -1) {
|
|
1392
|
+
out.push(src.slice(i));
|
|
1393
|
+
break;
|
|
1394
|
+
}
|
|
1395
|
+
out.push(src.slice(i, lt));
|
|
1396
|
+
if (lt + 1 >= len) {
|
|
1397
|
+
break;
|
|
1398
|
+
}
|
|
1399
|
+
const next = src[lt + 1];
|
|
1400
|
+
if (next === "!" || next === "?") {
|
|
1401
|
+
i = handleSpecialTagSegment(src, lt, out);
|
|
1402
|
+
continue;
|
|
1403
|
+
}
|
|
1404
|
+
if (next === "/") {
|
|
1405
|
+
i = handleClosingTagSegment(src, lt, out, stack);
|
|
1406
|
+
continue;
|
|
1407
|
+
}
|
|
1408
|
+
i = handleOpeningTagSegment(src, lt, out, stack);
|
|
1409
|
+
}
|
|
1410
|
+
for (let k = stack.length - 1; k >= 0; k -= 1) {
|
|
1411
|
+
out.push(`</${stack[k]}>`);
|
|
1412
|
+
}
|
|
1413
|
+
return out.join("");
|
|
1414
|
+
}
|
|
1415
|
+
function skipWs(s, p, len) {
|
|
1416
|
+
let idx = p;
|
|
1417
|
+
while (idx < len && WHITESPACE_REGEX2.test(s[idx])) {
|
|
1418
|
+
idx += 1;
|
|
1419
|
+
}
|
|
1420
|
+
return idx;
|
|
1421
|
+
}
|
|
1422
|
+
function parseTagNameAt(s, p, len) {
|
|
1423
|
+
let idx = p;
|
|
1424
|
+
const start = idx;
|
|
1425
|
+
while (idx < len && NAME_CHAR_RE.test(s[idx])) {
|
|
1426
|
+
idx += 1;
|
|
1427
|
+
}
|
|
1428
|
+
return { name: s.slice(start, idx), pos: idx };
|
|
1429
|
+
}
|
|
1430
|
+
function handleSpecialTagSegment(src, lt, out) {
|
|
1431
|
+
const gt = src.indexOf(">", lt + 1);
|
|
1432
|
+
if (gt === -1) {
|
|
1433
|
+
out.push(src.slice(lt));
|
|
1434
|
+
return src.length;
|
|
1435
|
+
}
|
|
1436
|
+
out.push(src.slice(lt, gt + 1));
|
|
1437
|
+
return gt + 1;
|
|
1438
|
+
}
|
|
1439
|
+
function handleClosingTagSegment(src, lt, out, stack) {
|
|
1440
|
+
const len = src.length;
|
|
1441
|
+
let p = skipWs(src, lt + 2, len);
|
|
1442
|
+
const { name, pos } = parseTagNameAt(src, p, len);
|
|
1443
|
+
p = pos;
|
|
1444
|
+
const gt = src.indexOf(">", p);
|
|
1445
|
+
const closingText = gt === -1 ? src.slice(lt) : src.slice(lt, gt + 1);
|
|
1446
|
+
const idx = stack.lastIndexOf(name);
|
|
1447
|
+
if (idx !== -1) {
|
|
1448
|
+
for (let k = stack.length - 1; k > idx; k -= 1) {
|
|
1449
|
+
out.push(`</${stack[k]}>`);
|
|
1450
|
+
stack.pop();
|
|
1451
|
+
}
|
|
1452
|
+
out.push(closingText);
|
|
1453
|
+
stack.pop();
|
|
1454
|
+
}
|
|
1455
|
+
return gt === -1 ? len : gt + 1;
|
|
1456
|
+
}
|
|
1457
|
+
function handleOpeningTagSegment(src, lt, out, stack) {
|
|
1458
|
+
const len = src.length;
|
|
1459
|
+
let p = skipWs(src, lt + 1, len);
|
|
1460
|
+
const nameStart = p;
|
|
1461
|
+
const parsed = parseTagNameAt(src, p, len);
|
|
1462
|
+
p = parsed.pos;
|
|
1463
|
+
const name = src.slice(nameStart, p);
|
|
1464
|
+
const q = src.indexOf(">", p);
|
|
1465
|
+
if (q === -1) {
|
|
1466
|
+
out.push(src.slice(lt));
|
|
1467
|
+
return len;
|
|
1468
|
+
}
|
|
1469
|
+
let r = q - 1;
|
|
1470
|
+
while (r >= nameStart && WHITESPACE_REGEX2.test(src[r])) {
|
|
1471
|
+
r -= 1;
|
|
1472
|
+
}
|
|
1473
|
+
const selfClosing = src[r] === "/";
|
|
1474
|
+
out.push(src.slice(lt, q + 1));
|
|
1475
|
+
if (!selfClosing && name) {
|
|
1476
|
+
stack.push(name);
|
|
1477
|
+
}
|
|
1478
|
+
return q + 1;
|
|
1479
|
+
}
|
|
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) {
|
|
1543
|
+
if (!input || typeof input !== "object") {
|
|
1544
|
+
return input;
|
|
1545
|
+
}
|
|
1546
|
+
const unwrapped = (0, import_rxml.unwrapJsonSchema)(schema);
|
|
1547
|
+
if (!unwrapped || typeof unwrapped !== "object") {
|
|
1548
|
+
return input;
|
|
1549
|
+
}
|
|
1550
|
+
const properties = unwrapped.properties;
|
|
1551
|
+
if (!properties) {
|
|
1552
|
+
return input;
|
|
1553
|
+
}
|
|
1554
|
+
applySchemaProps(input, properties);
|
|
1555
|
+
return input;
|
|
1556
|
+
}
|
|
1557
|
+
function applySchemaProps(obj, properties) {
|
|
1558
|
+
for (const key of Object.keys(obj)) {
|
|
1559
|
+
const propSchema = properties[key];
|
|
1560
|
+
if (!propSchema) {
|
|
1561
|
+
continue;
|
|
1562
|
+
}
|
|
1563
|
+
const prop = (0, import_rxml.unwrapJsonSchema)(propSchema);
|
|
1564
|
+
const propType = prop.type;
|
|
1565
|
+
if (propType === "array" && prop.items) {
|
|
1566
|
+
const itemSchemaRaw = prop.items;
|
|
1567
|
+
const itemSchema = (0, import_rxml.unwrapJsonSchema)(itemSchemaRaw);
|
|
1568
|
+
obj[key] = coerceArrayItems(obj[key], itemSchema);
|
|
1569
|
+
continue;
|
|
1570
|
+
}
|
|
1571
|
+
if (propType === "object") {
|
|
1572
|
+
const val = obj[key];
|
|
1573
|
+
if (val && typeof val === "object") {
|
|
1574
|
+
obj[key] = repairParsedAgainstSchema(val, prop);
|
|
1575
|
+
}
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
function coerceArrayItems(val, itemSchema) {
|
|
1580
|
+
if (!Array.isArray(val)) {
|
|
1581
|
+
return val;
|
|
1582
|
+
}
|
|
1583
|
+
return val.map((v) => coerceArrayItem(v, itemSchema));
|
|
1584
|
+
}
|
|
1585
|
+
function coerceArrayItem(v, itemSchema) {
|
|
1586
|
+
const itemType = itemSchema == null ? void 0 : itemSchema.type;
|
|
1587
|
+
if (typeof v === "string" && itemType === "object") {
|
|
1588
|
+
const parsed = tryParseStringToSchemaObject(v, itemSchema);
|
|
1589
|
+
if (parsed !== null) {
|
|
1590
|
+
return parsed;
|
|
1591
|
+
}
|
|
1592
|
+
const fallback = extractStepStatusFromString(
|
|
1593
|
+
v.replace(MALFORMED_CLOSE_RE_G, "</$1>")
|
|
1594
|
+
);
|
|
1595
|
+
if (fallback) {
|
|
1596
|
+
return fallback;
|
|
1597
|
+
}
|
|
1598
|
+
return v;
|
|
1599
|
+
}
|
|
1600
|
+
if (v && typeof v === "object" && itemType === "object") {
|
|
1601
|
+
return repairParsedAgainstSchema(v, itemSchema);
|
|
1602
|
+
}
|
|
1603
|
+
return v;
|
|
1604
|
+
}
|
|
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;
|
|
1612
|
+
}
|
|
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] };
|
|
1619
|
+
}
|
|
1620
|
+
return null;
|
|
1621
|
+
}
|
|
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");
|
|
1627
|
+
}
|
|
1628
|
+
function hasInputProperty(obj) {
|
|
1629
|
+
return typeof obj === "object" && obj !== null && "input" in obj;
|
|
1630
|
+
}
|
|
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>");
|
|
1643
|
+
}
|
|
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
|
+
}
|
|
1651
|
+
try {
|
|
1652
|
+
let parsed = (0, import_rxml2.parse)(balanced, toolSchema, {
|
|
1653
|
+
onError: options == null ? void 0 : options.onError,
|
|
1654
|
+
noChildNodes: []
|
|
1655
|
+
});
|
|
1656
|
+
parsed = repairParsedAgainstSchema(parsed, toolSchema);
|
|
1657
|
+
return parsed;
|
|
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
|
+
}
|
|
1674
|
+
return null;
|
|
1675
|
+
}
|
|
1676
|
+
}
|
|
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);
|
|
1682
|
+
}
|
|
1683
|
+
return out;
|
|
1684
|
+
}
|
|
1685
|
+
function processTextBeforeToolCall(text, currentIndex, toolCallStartIndex, processedElements) {
|
|
1686
|
+
if (toolCallStartIndex > currentIndex) {
|
|
1687
|
+
const textSegment = text.substring(currentIndex, toolCallStartIndex);
|
|
1688
|
+
if (textSegment.trim()) {
|
|
1689
|
+
processedElements.push({ type: "text", text: textSegment });
|
|
1690
|
+
}
|
|
1691
|
+
}
|
|
1692
|
+
return currentIndex;
|
|
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
|
+
}
|
|
1737
|
+
function processToolCall(params) {
|
|
1738
|
+
var _a;
|
|
1739
|
+
const { toolCall, tools, options, text, processedElements } = params;
|
|
1740
|
+
const toolSchema = getToolSchema(tools, toolCall.toolName);
|
|
1741
|
+
try {
|
|
1742
|
+
const primary = escapeInvalidLt(normalizeCloseTags(toolCall.content));
|
|
1743
|
+
let parsed = (0, import_rxml2.parse)(primary, toolSchema, {
|
|
1744
|
+
onError: options == null ? void 0 : options.onError,
|
|
1745
|
+
noChildNodes: []
|
|
1746
|
+
});
|
|
1747
|
+
parsed = repairParsedAgainstSchema(parsed, toolSchema);
|
|
1748
|
+
processedElements.push({
|
|
1749
|
+
type: "tool-call",
|
|
1750
|
+
toolCallId: (0, import_provider_utils2.generateId)(),
|
|
1751
|
+
toolName: toolCall.toolName,
|
|
1752
|
+
input: JSON.stringify(parsed)
|
|
1753
|
+
});
|
|
1754
|
+
} catch (error) {
|
|
1755
|
+
const reparsed = tryParseSecondaryXml(
|
|
1756
|
+
toolCall.content,
|
|
1757
|
+
toolSchema,
|
|
1758
|
+
options
|
|
1759
|
+
);
|
|
1760
|
+
if (reparsed !== null) {
|
|
1761
|
+
processedElements.push({
|
|
1762
|
+
type: "tool-call",
|
|
1763
|
+
toolCallId: (0, import_provider_utils2.generateId)(),
|
|
1764
|
+
toolName: toolCall.toolName,
|
|
1765
|
+
input: JSON.stringify(reparsed)
|
|
1766
|
+
});
|
|
1767
|
+
return;
|
|
1768
|
+
}
|
|
1769
|
+
const originalCallText = text.substring(
|
|
1770
|
+
toolCall.startIndex,
|
|
1771
|
+
toolCall.endIndex
|
|
1772
|
+
);
|
|
1773
|
+
const message = `Could not process XML tool call, keeping original text: ${originalCallText}`;
|
|
1774
|
+
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, message, {
|
|
1775
|
+
toolCall: originalCallText,
|
|
1776
|
+
toolName: toolCall.toolName,
|
|
1777
|
+
error
|
|
1778
|
+
});
|
|
1779
|
+
processedElements.push({ type: "text", text: originalCallText });
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1782
|
+
function addRemainingText(text, currentIndex, processedElements) {
|
|
1783
|
+
if (currentIndex < text.length) {
|
|
1784
|
+
const remainingText = text.substring(currentIndex);
|
|
1785
|
+
if (remainingText.trim()) {
|
|
1786
|
+
processedElements.push({ type: "text", text: remainingText });
|
|
1787
|
+
}
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1790
|
+
function handleStreamingToolCallEndWithPipeline(params) {
|
|
1791
|
+
var _a;
|
|
1792
|
+
const {
|
|
1793
|
+
toolContent,
|
|
1356
1794
|
currentToolCall,
|
|
1357
1795
|
tools,
|
|
1358
1796
|
options,
|
|
1359
|
-
|
|
1797
|
+
ctrl,
|
|
1360
1798
|
flushText,
|
|
1361
|
-
|
|
1799
|
+
pipelineConfig = defaultPipelineConfig2,
|
|
1800
|
+
maxReparses
|
|
1362
1801
|
} = params;
|
|
1363
|
-
const
|
|
1364
|
-
const
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
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
|
+
}
|
|
1841
|
+
function handleStreamingToolCallEnd(params) {
|
|
1842
|
+
const { toolContent, currentToolCall, tools, options, ctrl, flushText } = params;
|
|
1843
|
+
const toolSchema = getToolSchema(tools, currentToolCall.name);
|
|
1844
|
+
try {
|
|
1845
|
+
const primary = escapeInvalidLt(normalizeCloseTags(toolContent));
|
|
1846
|
+
let parsed = (0, import_rxml2.parse)(primary, toolSchema, {
|
|
1847
|
+
onError: options == null ? void 0 : options.onError,
|
|
1848
|
+
noChildNodes: []
|
|
1849
|
+
});
|
|
1850
|
+
parsed = repairParsedAgainstSchema(parsed, toolSchema);
|
|
1851
|
+
flushText(ctrl);
|
|
1852
|
+
ctrl.enqueue({
|
|
1853
|
+
type: "tool-call",
|
|
1854
|
+
toolCallId: (0, import_provider_utils2.generateId)(),
|
|
1855
|
+
toolName: currentToolCall.name,
|
|
1856
|
+
input: JSON.stringify(parsed)
|
|
1857
|
+
});
|
|
1858
|
+
} catch (error) {
|
|
1859
|
+
const parsed = tryParseSecondaryXml(toolContent, toolSchema, options);
|
|
1860
|
+
if (parsed !== null) {
|
|
1861
|
+
flushText(ctrl);
|
|
1862
|
+
ctrl.enqueue({
|
|
1863
|
+
type: "tool-call",
|
|
1864
|
+
toolCallId: (0, import_provider_utils2.generateId)(),
|
|
1865
|
+
toolName: currentToolCall.name,
|
|
1866
|
+
input: JSON.stringify(parsed)
|
|
1867
|
+
});
|
|
1868
|
+
return;
|
|
1869
|
+
}
|
|
1870
|
+
handleStreamingToolCallError({
|
|
1871
|
+
error,
|
|
1371
1872
|
currentToolCall,
|
|
1372
|
-
|
|
1873
|
+
toolContent,
|
|
1373
1874
|
options,
|
|
1374
|
-
ctrl
|
|
1875
|
+
ctrl,
|
|
1375
1876
|
flushText
|
|
1376
1877
|
});
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
function handleStreamingToolCallError(params) {
|
|
1881
|
+
var _a;
|
|
1882
|
+
const { error, currentToolCall, toolContent, options, ctrl, flushText } = params;
|
|
1883
|
+
const endTag = `</${currentToolCall.name}>`;
|
|
1884
|
+
const originalCallText = `<${currentToolCall.name}>${toolContent}${endTag}`;
|
|
1885
|
+
let message = "Could not process streaming XML tool call; emitting original text.";
|
|
1886
|
+
if (error instanceof import_rxml2.RXMLDuplicateStringTagError) {
|
|
1887
|
+
message = `Duplicate string tags detected in streaming tool call '${currentToolCall.name}'; emitting original text.`;
|
|
1888
|
+
} else if (error instanceof import_rxml2.RXMLCoercionError) {
|
|
1889
|
+
message = `Failed to coerce arguments for streaming tool call '${currentToolCall.name}'; emitting original text.`;
|
|
1890
|
+
} else if (error instanceof import_rxml2.RXMLParseError) {
|
|
1891
|
+
message = `Failed to parse XML for streaming tool call '${currentToolCall.name}'; emitting original text.`;
|
|
1892
|
+
}
|
|
1893
|
+
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, message, {
|
|
1894
|
+
toolCall: originalCallText,
|
|
1895
|
+
toolName: currentToolCall.name,
|
|
1896
|
+
error
|
|
1897
|
+
});
|
|
1898
|
+
flushText(ctrl, originalCallText);
|
|
1899
|
+
}
|
|
1900
|
+
function findEarliestToolTag(buffer, toolNames) {
|
|
1901
|
+
let bestIndex = -1;
|
|
1902
|
+
let bestName = "";
|
|
1903
|
+
let bestSelfClosing = false;
|
|
1904
|
+
if (toolNames.length > 0) {
|
|
1905
|
+
for (const name of toolNames) {
|
|
1906
|
+
const openTag = `<${name}>`;
|
|
1907
|
+
const selfTag = `<${name}/>`;
|
|
1908
|
+
const idxOpen = buffer.indexOf(openTag);
|
|
1909
|
+
const idxSelf = buffer.indexOf(selfTag);
|
|
1910
|
+
if (idxOpen !== -1 && (bestIndex === -1 || idxOpen < bestIndex)) {
|
|
1911
|
+
bestIndex = idxOpen;
|
|
1912
|
+
bestName = name;
|
|
1913
|
+
bestSelfClosing = false;
|
|
1914
|
+
}
|
|
1915
|
+
if (idxSelf !== -1 && (bestIndex === -1 || idxSelf < bestIndex)) {
|
|
1916
|
+
bestIndex = idxSelf;
|
|
1917
|
+
bestName = name;
|
|
1918
|
+
bestSelfClosing = true;
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1921
|
+
}
|
|
1922
|
+
return { index: bestIndex, name: bestName, selfClosing: bestSelfClosing };
|
|
1923
|
+
}
|
|
1924
|
+
function handleNoToolTagInBuffer(buffer, maxStartTagLen, controller, flushText) {
|
|
1925
|
+
const tail = Math.max(0, maxStartTagLen - 1);
|
|
1926
|
+
const safeLen = Math.max(0, buffer.length - tail);
|
|
1927
|
+
if (safeLen > 0) {
|
|
1928
|
+
const textToFlush = buffer.slice(0, safeLen);
|
|
1929
|
+
flushText(controller, textToFlush);
|
|
1930
|
+
return { buffer: buffer.slice(safeLen), shouldContinue: true };
|
|
1931
|
+
}
|
|
1932
|
+
return { buffer, shouldContinue: false };
|
|
1933
|
+
}
|
|
1934
|
+
function processToolCallInBuffer(params) {
|
|
1935
|
+
const {
|
|
1936
|
+
buffer,
|
|
1937
|
+
currentToolCall,
|
|
1938
|
+
tools,
|
|
1939
|
+
options,
|
|
1940
|
+
controller,
|
|
1941
|
+
flushText,
|
|
1942
|
+
setBuffer,
|
|
1943
|
+
pipelineConfig,
|
|
1944
|
+
maxReparses
|
|
1945
|
+
} = params;
|
|
1946
|
+
const endTag = `</${currentToolCall.name}>`;
|
|
1947
|
+
const normalized = normalizeCloseTags(buffer);
|
|
1948
|
+
const effectiveBuffer = normalized;
|
|
1949
|
+
const endTagIndex = effectiveBuffer.indexOf(endTag);
|
|
1950
|
+
if (endTagIndex !== -1) {
|
|
1951
|
+
const toolContent = effectiveBuffer.substring(0, endTagIndex);
|
|
1952
|
+
const newBuffer = effectiveBuffer.substring(endTagIndex + endTag.length);
|
|
1953
|
+
setBuffer("");
|
|
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
|
+
}
|
|
1377
1975
|
setBuffer(newBuffer);
|
|
1378
1976
|
return { buffer: newBuffer, currentToolCall: null, shouldBreak: false };
|
|
1379
1977
|
}
|
|
1380
|
-
return { buffer, currentToolCall, shouldBreak: true };
|
|
1978
|
+
return { buffer: effectiveBuffer, currentToolCall, shouldBreak: true };
|
|
1381
1979
|
}
|
|
1382
1980
|
function processNoToolCallInBuffer(params) {
|
|
1383
|
-
const {
|
|
1384
|
-
|
|
1981
|
+
const {
|
|
1982
|
+
buffer,
|
|
1983
|
+
toolNames,
|
|
1984
|
+
maxStartTagLen,
|
|
1985
|
+
controller,
|
|
1986
|
+
flushText,
|
|
1987
|
+
tools,
|
|
1988
|
+
options,
|
|
1989
|
+
pipelineConfig,
|
|
1990
|
+
maxReparses
|
|
1991
|
+
} = params;
|
|
1992
|
+
const {
|
|
1993
|
+
index: earliestStartTagIndex,
|
|
1994
|
+
name: earliestToolName,
|
|
1995
|
+
selfClosing
|
|
1996
|
+
} = findEarliestToolTag(buffer, toolNames);
|
|
1385
1997
|
if (earliestStartTagIndex !== -1) {
|
|
1386
1998
|
const textBeforeTag = buffer.substring(0, earliestStartTagIndex);
|
|
1387
1999
|
flushText(controller, textBeforeTag);
|
|
2000
|
+
if (selfClosing) {
|
|
2001
|
+
const selfTag = `<${earliestToolName}/>`;
|
|
2002
|
+
const newBuffer2 = buffer.substring(
|
|
2003
|
+
earliestStartTagIndex + selfTag.length
|
|
2004
|
+
);
|
|
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
|
+
}
|
|
2026
|
+
return {
|
|
2027
|
+
buffer: newBuffer2,
|
|
2028
|
+
currentToolCall: null,
|
|
2029
|
+
shouldBreak: false,
|
|
2030
|
+
shouldContinue: false
|
|
2031
|
+
};
|
|
2032
|
+
}
|
|
1388
2033
|
const startTag = `<${earliestToolName}>`;
|
|
1389
2034
|
const newBuffer = buffer.substring(earliestStartTagIndex + startTag.length);
|
|
1390
2035
|
return {
|
|
@@ -1413,7 +2058,7 @@ function createFlushTextHandler(getBuffer, setBuffer, getCurrentTextId, setCurre
|
|
|
1413
2058
|
if (content) {
|
|
1414
2059
|
const currentTextId2 = getCurrentTextId();
|
|
1415
2060
|
if (!currentTextId2) {
|
|
1416
|
-
const newId = (0,
|
|
2061
|
+
const newId = (0, import_provider_utils2.generateId)();
|
|
1417
2062
|
setCurrentTextId(newId);
|
|
1418
2063
|
controller.enqueue({ type: "text-start", id: newId });
|
|
1419
2064
|
}
|
|
@@ -1441,7 +2086,9 @@ function processBufferWithToolCall(params, controller) {
|
|
|
1441
2086
|
setCurrentToolCall,
|
|
1442
2087
|
tools,
|
|
1443
2088
|
options,
|
|
1444
|
-
flushText
|
|
2089
|
+
flushText,
|
|
2090
|
+
pipelineConfig,
|
|
2091
|
+
maxReparses
|
|
1445
2092
|
} = params;
|
|
1446
2093
|
const currentToolCall = getCurrentToolCall();
|
|
1447
2094
|
if (!currentToolCall) {
|
|
@@ -1454,7 +2101,9 @@ function processBufferWithToolCall(params, controller) {
|
|
|
1454
2101
|
options,
|
|
1455
2102
|
controller,
|
|
1456
2103
|
flushText,
|
|
1457
|
-
setBuffer
|
|
2104
|
+
setBuffer,
|
|
2105
|
+
pipelineConfig,
|
|
2106
|
+
maxReparses
|
|
1458
2107
|
});
|
|
1459
2108
|
setBuffer(result.buffer);
|
|
1460
2109
|
setCurrentToolCall(result.currentToolCall);
|
|
@@ -1465,16 +2114,24 @@ function processBufferWithoutToolCall(params, controller) {
|
|
|
1465
2114
|
getBuffer,
|
|
1466
2115
|
setBuffer,
|
|
1467
2116
|
setCurrentToolCall,
|
|
2117
|
+
tools,
|
|
2118
|
+
options,
|
|
1468
2119
|
toolNames,
|
|
1469
2120
|
maxStartTagLen,
|
|
1470
|
-
flushText
|
|
2121
|
+
flushText,
|
|
2122
|
+
pipelineConfig,
|
|
2123
|
+
maxReparses
|
|
1471
2124
|
} = params;
|
|
1472
2125
|
const result = processNoToolCallInBuffer({
|
|
1473
2126
|
buffer: getBuffer(),
|
|
1474
2127
|
toolNames,
|
|
1475
2128
|
maxStartTagLen,
|
|
1476
2129
|
controller,
|
|
1477
|
-
flushText
|
|
2130
|
+
flushText,
|
|
2131
|
+
tools,
|
|
2132
|
+
options,
|
|
2133
|
+
pipelineConfig,
|
|
2134
|
+
maxReparses
|
|
1478
2135
|
});
|
|
1479
2136
|
setBuffer(result.buffer);
|
|
1480
2137
|
setCurrentToolCall(result.currentToolCall);
|
|
@@ -1496,194 +2153,425 @@ function processBufferLoop(params, controller) {
|
|
|
1496
2153
|
params,
|
|
1497
2154
|
controller
|
|
1498
2155
|
);
|
|
1499
|
-
if (shouldContinue) {
|
|
1500
|
-
continue;
|
|
1501
|
-
}
|
|
1502
|
-
if (shouldBreak) {
|
|
1503
|
-
break;
|
|
1504
|
-
}
|
|
1505
|
-
}
|
|
1506
|
-
}
|
|
1507
|
-
}
|
|
1508
|
-
function createProcessBufferHandler(params) {
|
|
1509
|
-
return (controller) => {
|
|
1510
|
-
processBufferLoop(params, controller);
|
|
1511
|
-
};
|
|
1512
|
-
}
|
|
1513
|
-
var morphXmlProtocol = () => ({
|
|
1514
|
-
formatTools({ tools, toolSystemPromptTemplate }) {
|
|
1515
|
-
const toolsForPrompt = (tools || []).map((tool) => ({
|
|
1516
|
-
name: tool.name,
|
|
1517
|
-
description: tool.description,
|
|
1518
|
-
parameters: (0, import_rxml.unwrapJsonSchema)(tool.inputSchema)
|
|
1519
|
-
}));
|
|
1520
|
-
return toolSystemPromptTemplate(JSON.stringify(toolsForPrompt));
|
|
1521
|
-
},
|
|
1522
|
-
formatToolCall(toolCall) {
|
|
1523
|
-
let args = {};
|
|
1524
|
-
const inputValue = hasInputProperty(toolCall) ? toolCall.input : void 0;
|
|
1525
|
-
if (typeof inputValue === "string") {
|
|
1526
|
-
try {
|
|
1527
|
-
args = JSON.parse(inputValue);
|
|
1528
|
-
} catch (e) {
|
|
1529
|
-
args = inputValue;
|
|
1530
|
-
}
|
|
1531
|
-
} else {
|
|
1532
|
-
args = inputValue;
|
|
1533
|
-
}
|
|
1534
|
-
return (0, import_rxml.stringify)(toolCall.toolName, args, {
|
|
1535
|
-
suppressEmptyNode: false,
|
|
1536
|
-
format: false
|
|
1537
|
-
});
|
|
1538
|
-
},
|
|
1539
|
-
formatToolResponse(toolResult) {
|
|
1540
|
-
return (0, import_rxml.stringify)("tool_response", {
|
|
1541
|
-
tool_name: toolResult.toolName,
|
|
1542
|
-
result: toolResult.output
|
|
1543
|
-
});
|
|
1544
|
-
},
|
|
1545
|
-
parseGeneratedText({ text, tools, options }) {
|
|
1546
|
-
const toolNames = tools.map((t) => t.name).filter((name) => name != null);
|
|
1547
|
-
if (toolNames.length === 0) {
|
|
1548
|
-
return [{ type: "text", text }];
|
|
1549
|
-
}
|
|
1550
|
-
const processedElements = [];
|
|
1551
|
-
let currentIndex = 0;
|
|
1552
|
-
const toolCalls = findToolCalls(text, toolNames);
|
|
1553
|
-
for (const toolCall of toolCalls) {
|
|
1554
|
-
currentIndex = processTextBeforeToolCall(
|
|
1555
|
-
text,
|
|
1556
|
-
currentIndex,
|
|
1557
|
-
toolCall.startIndex,
|
|
1558
|
-
processedElements
|
|
1559
|
-
);
|
|
1560
|
-
processToolCall({ toolCall, tools, options, text, processedElements });
|
|
1561
|
-
currentIndex = toolCall.endIndex;
|
|
1562
|
-
}
|
|
1563
|
-
addRemainingText(text, currentIndex, processedElements);
|
|
1564
|
-
return processedElements;
|
|
1565
|
-
},
|
|
1566
|
-
createStreamParser({ tools, options }) {
|
|
1567
|
-
const toolNames = tools.map((t) => t.name).filter((name) => name != null);
|
|
1568
|
-
const maxStartTagLen = toolNames.length ? Math.max(...toolNames.map((n) => `<${n}>`.length)) : 0;
|
|
1569
|
-
let buffer = "";
|
|
1570
|
-
let currentToolCall = null;
|
|
1571
|
-
let currentTextId = null;
|
|
1572
|
-
const flushText = createFlushTextHandler(
|
|
1573
|
-
() => buffer,
|
|
1574
|
-
(newBuffer) => {
|
|
1575
|
-
buffer = newBuffer;
|
|
1576
|
-
},
|
|
1577
|
-
() => currentTextId,
|
|
1578
|
-
(newId) => {
|
|
1579
|
-
currentTextId = newId;
|
|
2156
|
+
if (shouldContinue) {
|
|
2157
|
+
continue;
|
|
1580
2158
|
}
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
if (chunk.type !== "text-delta") {
|
|
1584
|
-
if (buffer) {
|
|
1585
|
-
flushText(controller);
|
|
1586
|
-
}
|
|
1587
|
-
controller.enqueue(chunk);
|
|
1588
|
-
return;
|
|
2159
|
+
if (shouldBreak) {
|
|
2160
|
+
break;
|
|
1589
2161
|
}
|
|
1590
|
-
|
|
1591
|
-
|
|
2162
|
+
}
|
|
2163
|
+
}
|
|
2164
|
+
}
|
|
2165
|
+
function createProcessBufferHandler(params) {
|
|
2166
|
+
return (controller) => {
|
|
2167
|
+
processBufferLoop(params, controller);
|
|
2168
|
+
};
|
|
2169
|
+
}
|
|
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
|
|
1592
2180
|
};
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
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
|
+
]
|
|
1601
2200
|
},
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
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 {
|
|
2227
|
+
args = inputValue;
|
|
1614
2228
|
}
|
|
1615
|
-
|
|
1616
|
-
|
|
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 }];
|
|
1617
2244
|
}
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
2245
|
+
const processedElements = [];
|
|
2246
|
+
let currentIndex = 0;
|
|
2247
|
+
const toolCallsRaw = findToolCalls(text, toolNames);
|
|
2248
|
+
const toolCallsNorm = collectToolCallsFromNormalizedText(text, toolNames);
|
|
2249
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2250
|
+
const toolCalls = [...toolCallsRaw, ...toolCallsNorm].filter((tc) => {
|
|
2251
|
+
const key = `${tc.toolName}:${tc.startIndex}:${tc.endIndex}`;
|
|
2252
|
+
if (seen.has(key)) {
|
|
2253
|
+
return false;
|
|
2254
|
+
}
|
|
2255
|
+
seen.add(key);
|
|
2256
|
+
return true;
|
|
2257
|
+
}).sort((a, b) => a.startIndex - b.startIndex);
|
|
2258
|
+
for (const toolCall of toolCalls) {
|
|
2259
|
+
currentIndex = processTextBeforeToolCall(
|
|
2260
|
+
text,
|
|
2261
|
+
currentIndex,
|
|
2262
|
+
toolCall.startIndex,
|
|
2263
|
+
processedElements
|
|
2264
|
+
);
|
|
2265
|
+
if (pipelineConfig) {
|
|
2266
|
+
processToolCallWithPipeline({
|
|
2267
|
+
toolCall,
|
|
2268
|
+
tools,
|
|
2269
|
+
options,
|
|
2270
|
+
text,
|
|
2271
|
+
processedElements,
|
|
2272
|
+
pipelineConfig,
|
|
2273
|
+
maxReparses
|
|
2274
|
+
});
|
|
2275
|
+
} else {
|
|
2276
|
+
processToolCall({
|
|
2277
|
+
toolCall,
|
|
2278
|
+
tools,
|
|
2279
|
+
options,
|
|
2280
|
+
text,
|
|
2281
|
+
processedElements
|
|
2282
|
+
});
|
|
2283
|
+
}
|
|
2284
|
+
currentIndex = toolCall.endIndex;
|
|
1625
2285
|
}
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
2286
|
+
addRemainingText(text, currentIndex, processedElements);
|
|
2287
|
+
return processedElements;
|
|
2288
|
+
},
|
|
2289
|
+
createStreamParser({ tools, options }) {
|
|
2290
|
+
const toolNames = tools.map((t) => t.name).filter((name) => name != null);
|
|
2291
|
+
const maxStartTagLen = toolNames.length ? Math.max(...toolNames.map((n) => `<${n}>`.length)) : 0;
|
|
2292
|
+
let buffer = "";
|
|
2293
|
+
let currentToolCall = null;
|
|
2294
|
+
let currentTextId = null;
|
|
2295
|
+
const flushText = createFlushTextHandler(
|
|
2296
|
+
() => buffer,
|
|
2297
|
+
(newBuffer) => {
|
|
2298
|
+
buffer = newBuffer;
|
|
2299
|
+
},
|
|
2300
|
+
() => currentTextId,
|
|
2301
|
+
(newId) => {
|
|
2302
|
+
currentTextId = newId;
|
|
2303
|
+
}
|
|
2304
|
+
);
|
|
2305
|
+
const processChunk = (chunk, controller) => {
|
|
2306
|
+
if (chunk.type !== "text-delta") {
|
|
2307
|
+
if (buffer) {
|
|
2308
|
+
flushText(controller);
|
|
2309
|
+
}
|
|
2310
|
+
controller.enqueue(chunk);
|
|
2311
|
+
return;
|
|
2312
|
+
}
|
|
2313
|
+
buffer += chunk.delta;
|
|
2314
|
+
processBuffer(controller);
|
|
2315
|
+
};
|
|
2316
|
+
const processBuffer = createProcessBufferHandler({
|
|
2317
|
+
getBuffer: () => buffer,
|
|
2318
|
+
setBuffer: (newBuffer) => {
|
|
2319
|
+
buffer = newBuffer;
|
|
2320
|
+
},
|
|
2321
|
+
getCurrentToolCall: () => currentToolCall,
|
|
2322
|
+
setCurrentToolCall: (newToolCall) => {
|
|
2323
|
+
currentToolCall = newToolCall;
|
|
2324
|
+
},
|
|
2325
|
+
tools,
|
|
2326
|
+
options,
|
|
2327
|
+
toolNames,
|
|
2328
|
+
maxStartTagLen,
|
|
2329
|
+
flushText,
|
|
2330
|
+
pipelineConfig,
|
|
2331
|
+
maxReparses
|
|
2332
|
+
});
|
|
2333
|
+
const flushBuffer2 = (controller) => {
|
|
2334
|
+
if (currentToolCall) {
|
|
2335
|
+
const unfinishedCall = `<${currentToolCall.name}>${buffer}`;
|
|
2336
|
+
flushText(controller, unfinishedCall);
|
|
2337
|
+
} else if (buffer) {
|
|
2338
|
+
flushText(controller);
|
|
2339
|
+
}
|
|
2340
|
+
if (currentTextId) {
|
|
2341
|
+
controller.enqueue({ type: "text-end", id: currentTextId });
|
|
2342
|
+
}
|
|
2343
|
+
};
|
|
2344
|
+
return new TransformStream({
|
|
2345
|
+
transform(chunk, controller) {
|
|
2346
|
+
processChunk(chunk, controller);
|
|
2347
|
+
},
|
|
2348
|
+
flush(controller) {
|
|
2349
|
+
flushBuffer2(controller);
|
|
2350
|
+
}
|
|
2351
|
+
});
|
|
2352
|
+
},
|
|
2353
|
+
extractToolCallSegments({ text, tools }) {
|
|
2354
|
+
const toolNames = tools.map((t) => t.name).filter(Boolean);
|
|
2355
|
+
if (toolNames.length === 0) {
|
|
2356
|
+
return [];
|
|
2357
|
+
}
|
|
2358
|
+
return findToolCalls(text, toolNames).map((tc) => tc.segment);
|
|
1632
2359
|
}
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
});
|
|
2360
|
+
};
|
|
2361
|
+
};
|
|
1636
2362
|
function getToolSchema(tools, toolName) {
|
|
1637
2363
|
var _a;
|
|
1638
2364
|
return (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
|
|
1639
2365
|
}
|
|
1640
|
-
function
|
|
1641
|
-
let
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
2366
|
+
function findClosingTagEndFlexible(text, contentStart, toolName) {
|
|
2367
|
+
let pos = contentStart;
|
|
2368
|
+
let depth = 1;
|
|
2369
|
+
while (pos < text.length) {
|
|
2370
|
+
const tok = nextTagToken(text, pos);
|
|
2371
|
+
if (tok.kind === "eof") {
|
|
2372
|
+
break;
|
|
2373
|
+
}
|
|
2374
|
+
const result = updateDepthWithToken(tok, toolName, depth);
|
|
2375
|
+
depth = result.depth;
|
|
2376
|
+
if (result.closedAt !== void 0) {
|
|
2377
|
+
return result.closedAt;
|
|
2378
|
+
}
|
|
2379
|
+
pos = tok.nextPos;
|
|
2380
|
+
}
|
|
2381
|
+
return -1;
|
|
2382
|
+
}
|
|
2383
|
+
function skipSpecialSegment(text, lt) {
|
|
2384
|
+
const next = text[lt + 1];
|
|
2385
|
+
if (next !== "!" && next !== "?") {
|
|
2386
|
+
return null;
|
|
2387
|
+
}
|
|
2388
|
+
const gt = text.indexOf(">", lt + 1);
|
|
2389
|
+
if (gt === -1) {
|
|
2390
|
+
return null;
|
|
2391
|
+
}
|
|
2392
|
+
return gt + 1;
|
|
2393
|
+
}
|
|
2394
|
+
function consumeClosingTag(text, lt, _toolName) {
|
|
2395
|
+
let p = lt + 2;
|
|
2396
|
+
while (p < text.length && WHITESPACE_REGEX3.test(text[p])) {
|
|
2397
|
+
p += 1;
|
|
2398
|
+
}
|
|
2399
|
+
const gt = text.indexOf(">", lt + 1);
|
|
2400
|
+
const endPos = gt === -1 ? text.length : gt + 1;
|
|
2401
|
+
return { matched: false, endPos };
|
|
2402
|
+
}
|
|
2403
|
+
function consumeOpenTag(text, lt) {
|
|
2404
|
+
let p = lt + 1;
|
|
2405
|
+
while (p < text.length && WHITESPACE_REGEX3.test(text[p])) {
|
|
2406
|
+
p += 1;
|
|
2407
|
+
}
|
|
2408
|
+
const nameStart = p;
|
|
2409
|
+
while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
|
|
2410
|
+
p += 1;
|
|
2411
|
+
}
|
|
2412
|
+
const name = text.slice(nameStart, p);
|
|
2413
|
+
const q = text.indexOf(">", p);
|
|
2414
|
+
if (q === -1) {
|
|
2415
|
+
return null;
|
|
2416
|
+
}
|
|
2417
|
+
let r = q - 1;
|
|
2418
|
+
while (r >= nameStart && WHITESPACE_REGEX3.test(text[r])) {
|
|
2419
|
+
r -= 1;
|
|
2420
|
+
}
|
|
2421
|
+
const selfClosing = text[r] === "/";
|
|
2422
|
+
return { name, selfClosing, nextPos: q + 1 };
|
|
2423
|
+
}
|
|
2424
|
+
function updateDepthWithToken(tok, toolName, depth) {
|
|
2425
|
+
if (tok.kind === "close" && tok.name === toolName) {
|
|
2426
|
+
const newDepth = depth - 1;
|
|
2427
|
+
return newDepth === 0 ? { depth: newDepth, closedAt: tok.nextPos } : { depth: newDepth };
|
|
2428
|
+
}
|
|
2429
|
+
if (tok.kind === "open" && tok.name === toolName && !tok.selfClosing) {
|
|
2430
|
+
return { depth: depth + 1 };
|
|
2431
|
+
}
|
|
2432
|
+
return { depth };
|
|
2433
|
+
}
|
|
2434
|
+
function nextTagToken(text, fromPos) {
|
|
2435
|
+
const lt = text.indexOf("<", fromPos);
|
|
2436
|
+
if (lt === -1 || lt + 1 >= text.length) {
|
|
2437
|
+
return { kind: "eof", nextPos: text.length };
|
|
2438
|
+
}
|
|
2439
|
+
const next = text[lt + 1];
|
|
2440
|
+
const specialEnd = skipSpecialSegment(text, lt);
|
|
2441
|
+
if (specialEnd !== null) {
|
|
2442
|
+
return { kind: "special", nextPos: specialEnd };
|
|
2443
|
+
}
|
|
2444
|
+
if (next === "/") {
|
|
2445
|
+
const closing = consumeClosingTag(text, lt, "");
|
|
2446
|
+
let p = lt + 2;
|
|
2447
|
+
while (p < text.length && WHITESPACE_REGEX3.test(text[p])) {
|
|
1646
2448
|
p += 1;
|
|
1647
2449
|
}
|
|
1648
|
-
|
|
1649
|
-
|
|
2450
|
+
const nameStart = p;
|
|
2451
|
+
while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
|
|
2452
|
+
p += 1;
|
|
1650
2453
|
}
|
|
2454
|
+
const name = text.slice(nameStart, p);
|
|
2455
|
+
return { kind: "close", name, nextPos: closing.endPos };
|
|
2456
|
+
}
|
|
2457
|
+
const open = consumeOpenTag(text, lt);
|
|
2458
|
+
if (open === null) {
|
|
2459
|
+
return { kind: "eof", nextPos: text.length };
|
|
1651
2460
|
}
|
|
1652
|
-
return
|
|
2461
|
+
return {
|
|
2462
|
+
kind: "open",
|
|
2463
|
+
name: open.name,
|
|
2464
|
+
selfClosing: open.selfClosing,
|
|
2465
|
+
nextPos: open.nextPos
|
|
2466
|
+
};
|
|
1653
2467
|
}
|
|
1654
|
-
function
|
|
2468
|
+
function collectToolCallsFromNormalizedText(text, toolNames) {
|
|
1655
2469
|
var _a;
|
|
2470
|
+
const normalizedText = normalizeCloseTags(text);
|
|
2471
|
+
const collected = [];
|
|
2472
|
+
for (const toolName of toolNames) {
|
|
2473
|
+
const startTag = `<${toolName}>`;
|
|
2474
|
+
let idx = 0;
|
|
2475
|
+
let lastOrigIdx = 0;
|
|
2476
|
+
while (idx < normalizedText.length) {
|
|
2477
|
+
const tagStartNorm = normalizedText.indexOf(startTag, idx);
|
|
2478
|
+
if (tagStartNorm === -1) {
|
|
2479
|
+
break;
|
|
2480
|
+
}
|
|
2481
|
+
const contentStartNorm = tagStartNorm + startTag.length;
|
|
2482
|
+
const endNorm = findClosingTagEndFlexible(
|
|
2483
|
+
normalizedText,
|
|
2484
|
+
contentStartNorm,
|
|
2485
|
+
toolName
|
|
2486
|
+
);
|
|
2487
|
+
if (endNorm > contentStartNorm) {
|
|
2488
|
+
const tagStartOrig = text.indexOf(startTag, lastOrigIdx);
|
|
2489
|
+
const contentStartOrig = tagStartOrig + startTag.length;
|
|
2490
|
+
let endOrig = findClosingTagEndFlexible(
|
|
2491
|
+
text,
|
|
2492
|
+
contentStartOrig,
|
|
2493
|
+
toolName
|
|
2494
|
+
);
|
|
2495
|
+
if (endOrig === -1) {
|
|
2496
|
+
const approxLen = endNorm - tagStartNorm;
|
|
2497
|
+
endOrig = Math.min(text.length, tagStartOrig + approxLen);
|
|
2498
|
+
}
|
|
2499
|
+
const segment = text.substring(tagStartOrig, endOrig);
|
|
2500
|
+
const inner = (_a = (0, import_rxml2.extractRawInner)(segment, toolName)) != null ? _a : segment.substring(startTag.length, segment.lastIndexOf("<"));
|
|
2501
|
+
collected.push({
|
|
2502
|
+
toolName,
|
|
2503
|
+
startIndex: tagStartOrig,
|
|
2504
|
+
endIndex: endOrig,
|
|
2505
|
+
content: inner,
|
|
2506
|
+
segment
|
|
2507
|
+
});
|
|
2508
|
+
lastOrigIdx = endOrig;
|
|
2509
|
+
idx = endNorm;
|
|
2510
|
+
} else {
|
|
2511
|
+
idx = contentStartNorm;
|
|
2512
|
+
}
|
|
2513
|
+
}
|
|
2514
|
+
}
|
|
2515
|
+
return collected.sort((a, b) => a.startIndex - b.startIndex);
|
|
2516
|
+
}
|
|
2517
|
+
function getNextTagInfo(text, toolName, fromIndex) {
|
|
1656
2518
|
const startTag = `<${toolName}>`;
|
|
1657
|
-
const
|
|
1658
|
-
const
|
|
1659
|
-
const
|
|
1660
|
-
const
|
|
1661
|
-
const
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
2519
|
+
const selfTag = `<${toolName}/>`;
|
|
2520
|
+
const openIdx = text.indexOf(startTag, fromIndex);
|
|
2521
|
+
const selfIdx = text.indexOf(selfTag, fromIndex);
|
|
2522
|
+
const hasOpen = openIdx !== -1;
|
|
2523
|
+
const hasSelf = selfIdx !== -1;
|
|
2524
|
+
if (!(hasOpen || hasSelf)) {
|
|
2525
|
+
return {
|
|
2526
|
+
found: false,
|
|
2527
|
+
tagStart: -1,
|
|
2528
|
+
selfClosing: false,
|
|
2529
|
+
startTag,
|
|
2530
|
+
selfTag
|
|
2531
|
+
};
|
|
2532
|
+
}
|
|
2533
|
+
const pickSelf = hasSelf && (!hasOpen || selfIdx < openIdx);
|
|
2534
|
+
const tagStart = pickSelf ? selfIdx : openIdx;
|
|
2535
|
+
return { found: true, tagStart, selfClosing: pickSelf, startTag, selfTag };
|
|
1669
2536
|
}
|
|
1670
2537
|
function findToolCallsForName(text, toolName) {
|
|
2538
|
+
var _a;
|
|
1671
2539
|
const toolCalls = [];
|
|
1672
|
-
const startTag = `<${toolName}>`;
|
|
1673
2540
|
let searchIndex = 0;
|
|
1674
2541
|
while (searchIndex < text.length) {
|
|
1675
|
-
const
|
|
1676
|
-
if (
|
|
2542
|
+
const info = getNextTagInfo(text, toolName, searchIndex);
|
|
2543
|
+
if (!info.found) {
|
|
1677
2544
|
break;
|
|
1678
2545
|
}
|
|
1679
|
-
const
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
const
|
|
1683
|
-
toolCalls.push(
|
|
1684
|
-
|
|
2546
|
+
const { tagStart, selfClosing, startTag, selfTag } = info;
|
|
2547
|
+
if (selfClosing) {
|
|
2548
|
+
const endIndex = tagStart + selfTag.length;
|
|
2549
|
+
const segment = text.substring(tagStart, endIndex);
|
|
2550
|
+
toolCalls.push({
|
|
2551
|
+
toolName,
|
|
2552
|
+
startIndex: tagStart,
|
|
2553
|
+
endIndex,
|
|
2554
|
+
content: "",
|
|
2555
|
+
segment
|
|
2556
|
+
});
|
|
2557
|
+
searchIndex = endIndex;
|
|
2558
|
+
continue;
|
|
2559
|
+
}
|
|
2560
|
+
const contentStart = tagStart + startTag.length;
|
|
2561
|
+
const fullTagEnd = findClosingTagEndFlexible(text, contentStart, toolName);
|
|
2562
|
+
if (fullTagEnd !== -1 && fullTagEnd > contentStart) {
|
|
2563
|
+
const segment = text.substring(tagStart, fullTagEnd);
|
|
2564
|
+
const inner = (_a = (0, import_rxml2.extractRawInner)(segment, toolName)) != null ? _a : segment.substring(startTag.length, segment.lastIndexOf("<"));
|
|
2565
|
+
toolCalls.push({
|
|
2566
|
+
toolName,
|
|
2567
|
+
startIndex: tagStart,
|
|
2568
|
+
endIndex: fullTagEnd,
|
|
2569
|
+
content: inner,
|
|
2570
|
+
segment
|
|
2571
|
+
});
|
|
2572
|
+
searchIndex = fullTagEnd;
|
|
1685
2573
|
} else {
|
|
1686
|
-
searchIndex =
|
|
2574
|
+
searchIndex = contentStart;
|
|
1687
2575
|
}
|
|
1688
2576
|
}
|
|
1689
2577
|
return toolCalls;
|
|
@@ -1697,14 +2585,50 @@ function findToolCalls(text, toolNames) {
|
|
|
1697
2585
|
return toolCalls.sort((a, b) => a.startIndex - b.startIndex);
|
|
1698
2586
|
}
|
|
1699
2587
|
|
|
1700
|
-
// src/
|
|
1701
|
-
|
|
1702
|
-
|
|
2588
|
+
// src/generate-handler.ts
|
|
2589
|
+
var import_provider_utils3 = require("@ai-sdk/provider-utils");
|
|
2590
|
+
var import_rxml3 = require("@ai-sdk-tool/rxml");
|
|
2591
|
+
|
|
2592
|
+
// src/utils/on-error.ts
|
|
2593
|
+
function extractOnErrorOption(providerOptions) {
|
|
2594
|
+
var _a;
|
|
2595
|
+
if (providerOptions && typeof providerOptions === "object") {
|
|
2596
|
+
const onError = (_a = providerOptions.toolCallMiddleware) == null ? void 0 : _a.onError;
|
|
2597
|
+
return onError ? { onError } : void 0;
|
|
2598
|
+
}
|
|
2599
|
+
return;
|
|
2600
|
+
}
|
|
2601
|
+
|
|
2602
|
+
// src/utils/provider-options.ts
|
|
2603
|
+
var originalToolsSchema = {
|
|
2604
|
+
encode: encodeOriginalTools,
|
|
2605
|
+
decode: decodeOriginalTools
|
|
2606
|
+
};
|
|
2607
|
+
function encodeOriginalTools(tools) {
|
|
2608
|
+
return (tools == null ? void 0 : tools.map((t) => ({
|
|
2609
|
+
name: t.name,
|
|
2610
|
+
inputSchema: JSON.stringify(t.inputSchema)
|
|
2611
|
+
}))) || [];
|
|
2612
|
+
}
|
|
2613
|
+
function decodeOriginalTools(originalTools) {
|
|
2614
|
+
if (!originalTools) {
|
|
2615
|
+
return [];
|
|
2616
|
+
}
|
|
2617
|
+
return originalTools.map(
|
|
2618
|
+
(t) => ({
|
|
2619
|
+
type: "function",
|
|
2620
|
+
name: t.name,
|
|
2621
|
+
inputSchema: JSON.parse(t.inputSchema)
|
|
2622
|
+
})
|
|
2623
|
+
);
|
|
2624
|
+
}
|
|
2625
|
+
function isToolChoiceActive(params) {
|
|
2626
|
+
var _a, _b, _c;
|
|
2627
|
+
const toolChoice = (_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.toolChoice;
|
|
2628
|
+
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"));
|
|
1703
2629
|
}
|
|
1704
2630
|
|
|
1705
2631
|
// src/generate-handler.ts
|
|
1706
|
-
var import_provider_utils4 = require("@ai-sdk/provider-utils");
|
|
1707
|
-
var import_rxml2 = require("@ai-sdk-tool/rxml");
|
|
1708
2632
|
function parseToolChoiceJson(text, providerOptions) {
|
|
1709
2633
|
var _a;
|
|
1710
2634
|
try {
|
|
@@ -1748,7 +2672,7 @@ async function handleToolChoice(doGenerate, params) {
|
|
|
1748
2672
|
}
|
|
1749
2673
|
const toolCall = {
|
|
1750
2674
|
type: "tool-call",
|
|
1751
|
-
toolCallId: (0,
|
|
2675
|
+
toolCallId: (0, import_provider_utils3.generateId)(),
|
|
1752
2676
|
toolName: parsed.name || "unknown",
|
|
1753
2677
|
input: JSON.stringify(parsed.arguments || {})
|
|
1754
2678
|
};
|
|
@@ -1867,15 +2791,20 @@ function fixToolCallWithSchema(part, tools) {
|
|
|
1867
2791
|
args = tc.input;
|
|
1868
2792
|
}
|
|
1869
2793
|
const schema = (_a = tools.find((t) => t.name === tc.toolName)) == null ? void 0 : _a.inputSchema;
|
|
1870
|
-
const coerced = (0,
|
|
2794
|
+
const coerced = (0, import_rxml3.coerceBySchema)(args, schema);
|
|
1871
2795
|
return {
|
|
1872
2796
|
...part,
|
|
1873
2797
|
input: JSON.stringify(coerced != null ? coerced : {})
|
|
1874
2798
|
};
|
|
1875
2799
|
}
|
|
1876
2800
|
|
|
2801
|
+
// src/protocols/tool-call-protocol.ts
|
|
2802
|
+
function isProtocolFactory(protocol) {
|
|
2803
|
+
return typeof protocol === "function";
|
|
2804
|
+
}
|
|
2805
|
+
|
|
1877
2806
|
// src/stream-handler.ts
|
|
1878
|
-
var
|
|
2807
|
+
var import_provider_utils4 = require("@ai-sdk/provider-utils");
|
|
1879
2808
|
function extractToolCallSegments(protocol, fullRawText, tools) {
|
|
1880
2809
|
const segments = protocol.extractToolCallSegments ? protocol.extractToolCallSegments({
|
|
1881
2810
|
text: fullRawText,
|
|
@@ -1912,7 +2841,7 @@ function handleDebugSummary(parsedToolCalls, origin, params) {
|
|
|
1912
2841
|
}
|
|
1913
2842
|
function createDebugSummaryTransform({
|
|
1914
2843
|
protocol,
|
|
1915
|
-
|
|
2844
|
+
getFullRawText,
|
|
1916
2845
|
tools,
|
|
1917
2846
|
params
|
|
1918
2847
|
}) {
|
|
@@ -1925,11 +2854,9 @@ function createDebugSummaryTransform({
|
|
|
1925
2854
|
}
|
|
1926
2855
|
if (part.type === "finish") {
|
|
1927
2856
|
try {
|
|
1928
|
-
const
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
tools
|
|
1932
|
-
);
|
|
2857
|
+
const raw = getFullRawText();
|
|
2858
|
+
logRawChunk(raw);
|
|
2859
|
+
const origin = extractToolCallSegments(protocol, raw, tools);
|
|
1933
2860
|
handleDebugSummary(parsedToolCalls, origin, params);
|
|
1934
2861
|
} catch (e) {
|
|
1935
2862
|
}
|
|
@@ -2027,7 +2954,7 @@ async function wrapStream({
|
|
|
2027
2954
|
const withSummary = parsed.pipeThrough(
|
|
2028
2955
|
createDebugSummaryTransform({
|
|
2029
2956
|
protocol,
|
|
2030
|
-
fullRawText,
|
|
2957
|
+
getFullRawText: () => fullRawText,
|
|
2031
2958
|
tools,
|
|
2032
2959
|
params
|
|
2033
2960
|
})
|
|
@@ -2061,19 +2988,26 @@ async function toolChoiceStream({
|
|
|
2061
2988
|
}
|
|
2062
2989
|
const toolCallChunk = {
|
|
2063
2990
|
type: "tool-call",
|
|
2064
|
-
toolCallId: (0,
|
|
2991
|
+
toolCallId: (0, import_provider_utils4.generateId)(),
|
|
2065
2992
|
toolName: toolJson.name || "unknown",
|
|
2066
2993
|
input: JSON.stringify(toolJson.arguments || {})
|
|
2067
2994
|
};
|
|
2068
2995
|
const finishChunk = {
|
|
2069
2996
|
type: "finish",
|
|
2070
|
-
usage: (result == null ? void 0 : result.usage) ||
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2997
|
+
usage: (result == null ? void 0 : result.usage) || {
|
|
2998
|
+
inputTokens: {
|
|
2999
|
+
total: 0,
|
|
3000
|
+
noCache: void 0,
|
|
3001
|
+
cacheRead: void 0,
|
|
3002
|
+
cacheWrite: void 0
|
|
3003
|
+
},
|
|
3004
|
+
outputTokens: {
|
|
3005
|
+
total: 0,
|
|
3006
|
+
text: void 0,
|
|
3007
|
+
reasoning: void 0
|
|
3008
|
+
}
|
|
2075
3009
|
},
|
|
2076
|
-
finishReason: "tool-calls"
|
|
3010
|
+
finishReason: { unified: "tool-calls", raw: void 0 }
|
|
2077
3011
|
};
|
|
2078
3012
|
const stream = new ReadableStream({
|
|
2079
3013
|
start(controller) {
|
|
@@ -2107,26 +3041,106 @@ async function toolChoiceStream({
|
|
|
2107
3041
|
};
|
|
2108
3042
|
}
|
|
2109
3043
|
|
|
3044
|
+
// src/utils/dynamic-tool-schema.ts
|
|
3045
|
+
function createDynamicIfThenElseSchema(tools) {
|
|
3046
|
+
let currentSchema = {};
|
|
3047
|
+
const toolNames = [];
|
|
3048
|
+
for (let i = tools.length - 1; i >= 0; i -= 1) {
|
|
3049
|
+
const tool = tools[i];
|
|
3050
|
+
if (tool.type === "provider") {
|
|
3051
|
+
throw new Error(
|
|
3052
|
+
"Provider tools are not supported by this middleware. Please use function tools."
|
|
3053
|
+
);
|
|
3054
|
+
}
|
|
3055
|
+
toolNames.unshift(tool.name);
|
|
3056
|
+
const toolCondition = {
|
|
3057
|
+
if: {
|
|
3058
|
+
properties: {
|
|
3059
|
+
name: {
|
|
3060
|
+
const: tool.name
|
|
3061
|
+
}
|
|
3062
|
+
},
|
|
3063
|
+
required: ["name"]
|
|
3064
|
+
},
|
|
3065
|
+
// biome-ignore lint/suspicious/noThenProperty: JSON Schema uses 'then' as a keyword
|
|
3066
|
+
then: {
|
|
3067
|
+
properties: {
|
|
3068
|
+
name: {
|
|
3069
|
+
const: tool.name
|
|
3070
|
+
},
|
|
3071
|
+
arguments: tool.inputSchema
|
|
3072
|
+
},
|
|
3073
|
+
required: ["name", "arguments"]
|
|
3074
|
+
}
|
|
3075
|
+
};
|
|
3076
|
+
if (Object.keys(currentSchema).length > 0) {
|
|
3077
|
+
toolCondition.else = currentSchema;
|
|
3078
|
+
}
|
|
3079
|
+
currentSchema = toolCondition;
|
|
3080
|
+
}
|
|
3081
|
+
return {
|
|
3082
|
+
type: "object",
|
|
3083
|
+
// Explicitly specify type as "object"
|
|
3084
|
+
properties: {
|
|
3085
|
+
name: {
|
|
3086
|
+
type: "string",
|
|
3087
|
+
description: "Name of the tool to call",
|
|
3088
|
+
enum: toolNames
|
|
3089
|
+
},
|
|
3090
|
+
arguments: {
|
|
3091
|
+
type: "object",
|
|
3092
|
+
// By default, arguments is also specified as object type
|
|
3093
|
+
description: "Argument object to be passed to the tool"
|
|
3094
|
+
}
|
|
3095
|
+
},
|
|
3096
|
+
required: ["name", "arguments"],
|
|
3097
|
+
...currentSchema
|
|
3098
|
+
};
|
|
3099
|
+
}
|
|
3100
|
+
|
|
2110
3101
|
// src/transform-handler.ts
|
|
2111
|
-
function buildFinalPrompt(systemPrompt, processedPrompt) {
|
|
2112
|
-
|
|
2113
|
-
if (
|
|
3102
|
+
function buildFinalPrompt(systemPrompt, processedPrompt, placement) {
|
|
3103
|
+
const systemIndex = processedPrompt.findIndex((m) => m.role === "system");
|
|
3104
|
+
if (systemIndex !== -1) {
|
|
3105
|
+
const existing = processedPrompt[systemIndex].content;
|
|
3106
|
+
let existingText = "";
|
|
3107
|
+
if (typeof existing === "string") {
|
|
3108
|
+
existingText = existing;
|
|
3109
|
+
} else if (Array.isArray(existing)) {
|
|
3110
|
+
existingText = existing.map((p) => {
|
|
3111
|
+
var _a;
|
|
3112
|
+
return (p == null ? void 0 : p.type) === "text" ? (_a = p.text) != null ? _a : "" : "";
|
|
3113
|
+
}).filter(Boolean).join("\n");
|
|
3114
|
+
} else {
|
|
3115
|
+
existingText = String(existing != null ? existing : "");
|
|
3116
|
+
}
|
|
3117
|
+
const mergedContent = placement === "first" ? `${systemPrompt}
|
|
3118
|
+
|
|
3119
|
+
${existingText}` : `${existingText}
|
|
3120
|
+
|
|
3121
|
+
${systemPrompt}`;
|
|
3122
|
+
return processedPrompt.map(
|
|
3123
|
+
(m, idx) => idx === systemIndex ? {
|
|
3124
|
+
...m,
|
|
3125
|
+
content: mergedContent
|
|
3126
|
+
} : m
|
|
3127
|
+
);
|
|
3128
|
+
}
|
|
3129
|
+
if (placement === "first") {
|
|
2114
3130
|
return [
|
|
2115
3131
|
{
|
|
2116
3132
|
role: "system",
|
|
2117
|
-
content:
|
|
2118
|
-
|
|
2119
|
-
${processedPrompt[0].content}`
|
|
3133
|
+
content: systemPrompt
|
|
2120
3134
|
},
|
|
2121
|
-
...processedPrompt
|
|
3135
|
+
...processedPrompt
|
|
2122
3136
|
];
|
|
2123
3137
|
}
|
|
2124
3138
|
return [
|
|
3139
|
+
...processedPrompt,
|
|
2125
3140
|
{
|
|
2126
3141
|
role: "system",
|
|
2127
3142
|
content: systemPrompt
|
|
2128
|
-
}
|
|
2129
|
-
...processedPrompt
|
|
3143
|
+
}
|
|
2130
3144
|
];
|
|
2131
3145
|
}
|
|
2132
3146
|
function buildBaseReturnParams(params, finalPrompt, functionTools) {
|
|
@@ -2226,7 +3240,8 @@ function handleToolChoiceRequired(params, baseReturnParams, functionTools) {
|
|
|
2226
3240
|
function transformParams({
|
|
2227
3241
|
params,
|
|
2228
3242
|
protocol,
|
|
2229
|
-
toolSystemPromptTemplate
|
|
3243
|
+
toolSystemPromptTemplate,
|
|
3244
|
+
placement = "first"
|
|
2230
3245
|
}) {
|
|
2231
3246
|
var _a, _b, _c, _d, _e;
|
|
2232
3247
|
const resolvedProtocol = isProtocolFactory(protocol) ? protocol() : protocol;
|
|
@@ -2242,7 +3257,11 @@ function transformParams({
|
|
|
2242
3257
|
resolvedProtocol,
|
|
2243
3258
|
extractOnErrorOption(params.providerOptions)
|
|
2244
3259
|
);
|
|
2245
|
-
const finalPrompt = buildFinalPrompt(
|
|
3260
|
+
const finalPrompt = buildFinalPrompt(
|
|
3261
|
+
systemPrompt,
|
|
3262
|
+
processedPrompt,
|
|
3263
|
+
placement
|
|
3264
|
+
);
|
|
2246
3265
|
const baseReturnParams = buildBaseReturnParams(
|
|
2247
3266
|
params,
|
|
2248
3267
|
finalPrompt,
|
|
@@ -2319,7 +3338,10 @@ function processMessage(message, resolvedProtocol, providerOptions) {
|
|
|
2319
3338
|
};
|
|
2320
3339
|
}
|
|
2321
3340
|
if (message.role === "tool") {
|
|
2322
|
-
|
|
3341
|
+
const toolResultParts = message.content.filter(
|
|
3342
|
+
(part) => part.type === "tool-result"
|
|
3343
|
+
);
|
|
3344
|
+
return processToolMessage(toolResultParts, resolvedProtocol);
|
|
2323
3345
|
}
|
|
2324
3346
|
return message;
|
|
2325
3347
|
}
|
|
@@ -2394,7 +3416,8 @@ function convertToolPrompt(prompt, resolvedProtocol, providerOptions) {
|
|
|
2394
3416
|
// src/tool-call-middleware.ts
|
|
2395
3417
|
function createToolMiddleware({
|
|
2396
3418
|
protocol,
|
|
2397
|
-
toolSystemPromptTemplate
|
|
3419
|
+
toolSystemPromptTemplate,
|
|
3420
|
+
placement = "last"
|
|
2398
3421
|
}) {
|
|
2399
3422
|
const resolvedProtocol = isProtocolFactory(protocol) ? protocol() : protocol;
|
|
2400
3423
|
return {
|
|
@@ -2421,6 +3444,7 @@ function createToolMiddleware({
|
|
|
2421
3444
|
transformParams: async ({ params }) => transformParams({
|
|
2422
3445
|
protocol: resolvedProtocol,
|
|
2423
3446
|
toolSystemPromptTemplate,
|
|
3447
|
+
placement,
|
|
2424
3448
|
params
|
|
2425
3449
|
})
|
|
2426
3450
|
};
|
|
@@ -2466,6 +3490,7 @@ For each function call return a json object with function name and arguments wit
|
|
|
2466
3490
|
});
|
|
2467
3491
|
var morphXmlToolMiddleware = createToolMiddleware({
|
|
2468
3492
|
protocol: morphXmlProtocol,
|
|
3493
|
+
placement: "last",
|
|
2469
3494
|
toolSystemPromptTemplate(tools) {
|
|
2470
3495
|
return `You are a function calling AI model.
|
|
2471
3496
|
|
|
@@ -2488,7 +3513,7 @@ Available functions are listed inside <tools></tools>.
|
|
|
2488
3513
|
}
|
|
2489
3514
|
});
|
|
2490
3515
|
|
|
2491
|
-
// src/community/
|
|
3516
|
+
// src/community/sijawara.ts
|
|
2492
3517
|
var sijawaraDetailedXmlToolMiddleware = createToolMiddleware({
|
|
2493
3518
|
protocol: morphXmlProtocol,
|
|
2494
3519
|
toolSystemPromptTemplate(tools) {
|