@ai-sdk-tool/parser 3.0.0-canary.0 → 3.0.0-canary.1
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-L4X363EL.js} +889 -235
- package/dist/chunk-L4X363EL.js.map +1 -0
- package/dist/community.cjs +873 -240
- package/dist/community.cjs.map +1 -1
- package/dist/community.js +2 -2
- package/dist/community.js.map +1 -1
- package/dist/index.cjs +881 -220
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -22
- package/dist/index.d.ts +21 -22
- package/dist/index.js +3 -3
- package/package.json +23 -16
- package/dist/chunk-FOANBZRH.js.map +0 -1
|
@@ -1,14 +1,5 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __export = (target, all) => {
|
|
3
|
-
for (var name in all)
|
|
4
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
// src/protocols/dummy-protocol.ts
|
|
8
|
-
import { generateId } from "@ai-sdk/provider-utils";
|
|
9
|
-
|
|
10
1
|
// src/protocols/json-mix-protocol.ts
|
|
11
|
-
import { generateId
|
|
2
|
+
import { generateId } from "@ai-sdk/provider-utils";
|
|
12
3
|
|
|
13
4
|
// src/utils/debug.ts
|
|
14
5
|
var LINE_SPLIT_REGEX = /\r?\n/;
|
|
@@ -56,6 +47,7 @@ var cBgGreen = color(ANSI_BG_GREEN);
|
|
|
56
47
|
var cInverse = color(ANSI_INVERSE);
|
|
57
48
|
var cUnderline = color(ANSI_UNDERLINE);
|
|
58
49
|
var cBold = color(ANSI_BOLD);
|
|
50
|
+
var MAX_SNIPPET_LENGTH = 800;
|
|
59
51
|
function safeStringify(value) {
|
|
60
52
|
try {
|
|
61
53
|
return `
|
|
@@ -64,6 +56,41 @@ ${typeof value === "string" ? value : JSON.stringify(value, null, 2)}`;
|
|
|
64
56
|
return String(value);
|
|
65
57
|
}
|
|
66
58
|
}
|
|
59
|
+
function formatError(error) {
|
|
60
|
+
if (error instanceof Error) {
|
|
61
|
+
const stack = error.stack ? `
|
|
62
|
+
${error.stack}` : "";
|
|
63
|
+
return `
|
|
64
|
+
${error.name}: ${error.message}${stack}`;
|
|
65
|
+
}
|
|
66
|
+
return safeStringify(error);
|
|
67
|
+
}
|
|
68
|
+
function truncateSnippet(snippet) {
|
|
69
|
+
if (snippet.length <= MAX_SNIPPET_LENGTH) {
|
|
70
|
+
return snippet;
|
|
71
|
+
}
|
|
72
|
+
return `${snippet.slice(0, MAX_SNIPPET_LENGTH)}
|
|
73
|
+
\u2026[truncated ${snippet.length - MAX_SNIPPET_LENGTH} chars]`;
|
|
74
|
+
}
|
|
75
|
+
function logParseFailure({
|
|
76
|
+
phase,
|
|
77
|
+
reason,
|
|
78
|
+
snippet,
|
|
79
|
+
error
|
|
80
|
+
}) {
|
|
81
|
+
if (getDebugLevel() !== "parse") {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const label = cBgBlue(`[${phase}]`);
|
|
85
|
+
console.log(cGray("[debug:mw:fail]"), label, cYellow(reason));
|
|
86
|
+
if (snippet) {
|
|
87
|
+
const formatted = truncateSnippet(snippet);
|
|
88
|
+
console.log(cGray("[debug:mw:fail:snippet]"), formatted);
|
|
89
|
+
}
|
|
90
|
+
if (error) {
|
|
91
|
+
console.log(cGray("[debug:mw:fail:error]"), cCyan(formatError(error)));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
67
94
|
function logRawChunk(part) {
|
|
68
95
|
console.log(cGray("[debug:mw:raw]"), cYellow(safeStringify(part)));
|
|
69
96
|
}
|
|
@@ -129,63 +156,6 @@ ${rendered}`);
|
|
|
129
156
|
}
|
|
130
157
|
}
|
|
131
158
|
|
|
132
|
-
// src/utils/dynamic-tool-schema.ts
|
|
133
|
-
function createDynamicIfThenElseSchema(tools) {
|
|
134
|
-
let currentSchema = {};
|
|
135
|
-
const toolNames = [];
|
|
136
|
-
for (let i = tools.length - 1; i >= 0; i -= 1) {
|
|
137
|
-
const tool = tools[i];
|
|
138
|
-
if (tool.type === "provider-defined") {
|
|
139
|
-
throw new Error(
|
|
140
|
-
"Provider-defined tools are not supported by this middleware. Please use custom tools."
|
|
141
|
-
);
|
|
142
|
-
}
|
|
143
|
-
toolNames.unshift(tool.name);
|
|
144
|
-
const toolCondition = {
|
|
145
|
-
if: {
|
|
146
|
-
properties: {
|
|
147
|
-
name: {
|
|
148
|
-
const: tool.name
|
|
149
|
-
}
|
|
150
|
-
},
|
|
151
|
-
required: ["name"]
|
|
152
|
-
},
|
|
153
|
-
// biome-ignore lint/suspicious/noThenProperty: JSON Schema uses 'then' as a keyword
|
|
154
|
-
then: {
|
|
155
|
-
properties: {
|
|
156
|
-
name: {
|
|
157
|
-
const: tool.name
|
|
158
|
-
},
|
|
159
|
-
arguments: tool.inputSchema
|
|
160
|
-
},
|
|
161
|
-
required: ["name", "arguments"]
|
|
162
|
-
}
|
|
163
|
-
};
|
|
164
|
-
if (Object.keys(currentSchema).length > 0) {
|
|
165
|
-
toolCondition.else = currentSchema;
|
|
166
|
-
}
|
|
167
|
-
currentSchema = toolCondition;
|
|
168
|
-
}
|
|
169
|
-
return {
|
|
170
|
-
type: "object",
|
|
171
|
-
// Explicitly specify type as "object"
|
|
172
|
-
properties: {
|
|
173
|
-
name: {
|
|
174
|
-
type: "string",
|
|
175
|
-
description: "Name of the tool to call",
|
|
176
|
-
enum: toolNames
|
|
177
|
-
},
|
|
178
|
-
arguments: {
|
|
179
|
-
type: "object",
|
|
180
|
-
// By default, arguments is also specified as object type
|
|
181
|
-
description: "Argument object to be passed to the tool"
|
|
182
|
-
}
|
|
183
|
-
},
|
|
184
|
-
required: ["name", "arguments"],
|
|
185
|
-
...currentSchema
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
|
|
189
159
|
// src/utils/get-potential-start-index.ts
|
|
190
160
|
function getPotentialStartIndex(text, searchedText) {
|
|
191
161
|
if (searchedText.length === 0) {
|
|
@@ -204,60 +174,12 @@ function getPotentialStartIndex(text, searchedText) {
|
|
|
204
174
|
return null;
|
|
205
175
|
}
|
|
206
176
|
|
|
207
|
-
// src/utils/on-error.ts
|
|
208
|
-
function extractOnErrorOption(providerOptions) {
|
|
209
|
-
var _a;
|
|
210
|
-
if (providerOptions && typeof providerOptions === "object") {
|
|
211
|
-
const onError = (_a = providerOptions.toolCallMiddleware) == null ? void 0 : _a.onError;
|
|
212
|
-
return onError ? { onError } : void 0;
|
|
213
|
-
}
|
|
214
|
-
return;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// src/utils/provider-options.ts
|
|
218
|
-
var originalToolsSchema = {
|
|
219
|
-
encode: encodeOriginalTools,
|
|
220
|
-
decode: decodeOriginalTools
|
|
221
|
-
};
|
|
222
|
-
function encodeOriginalTools(tools) {
|
|
223
|
-
return (tools == null ? void 0 : tools.map((t) => ({
|
|
224
|
-
name: t.name,
|
|
225
|
-
inputSchema: JSON.stringify(t.inputSchema)
|
|
226
|
-
}))) || [];
|
|
227
|
-
}
|
|
228
|
-
function decodeOriginalTools(originalTools) {
|
|
229
|
-
if (!originalTools) {
|
|
230
|
-
return [];
|
|
231
|
-
}
|
|
232
|
-
return originalTools.map(
|
|
233
|
-
(t) => ({
|
|
234
|
-
type: "function",
|
|
235
|
-
name: t.name,
|
|
236
|
-
inputSchema: JSON.parse(t.inputSchema)
|
|
237
|
-
})
|
|
238
|
-
);
|
|
239
|
-
}
|
|
240
|
-
function extractToolNamesFromOriginalTools(originalTools) {
|
|
241
|
-
return (originalTools == null ? void 0 : originalTools.map((t) => t.name)) || [];
|
|
242
|
-
}
|
|
243
|
-
function isToolChoiceActive(params) {
|
|
244
|
-
var _a, _b, _c;
|
|
245
|
-
const toolChoice = (_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.toolChoice;
|
|
246
|
-
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"));
|
|
247
|
-
}
|
|
248
|
-
|
|
249
177
|
// src/utils/regex.ts
|
|
250
178
|
function escapeRegExp(literal) {
|
|
251
179
|
return literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
252
180
|
}
|
|
253
181
|
|
|
254
182
|
// src/utils/robust-json.ts
|
|
255
|
-
var robust_json_exports = {};
|
|
256
|
-
__export(robust_json_exports, {
|
|
257
|
-
parse: () => parse,
|
|
258
|
-
stringify: () => stringify,
|
|
259
|
-
transform: () => transform
|
|
260
|
-
});
|
|
261
183
|
var WHITESPACE_TEST_REGEX = /\s/;
|
|
262
184
|
var WHITESPACE_REGEX = /^\s+/;
|
|
263
185
|
var OBJECT_START_REGEX = /^\{/;
|
|
@@ -922,19 +844,6 @@ function stringify(obj) {
|
|
|
922
844
|
return "null";
|
|
923
845
|
}
|
|
924
846
|
|
|
925
|
-
// src/utils/type-guards.ts
|
|
926
|
-
function isToolCallContent(content) {
|
|
927
|
-
return content.type === "tool-call" && typeof content.toolName === "string" && // input may be a JSON string or an already-parsed object depending on provider/runtime
|
|
928
|
-
(typeof content.input === "string" || typeof content.input === "object");
|
|
929
|
-
}
|
|
930
|
-
function isToolResultPart(content) {
|
|
931
|
-
const c = content;
|
|
932
|
-
return !!c && c.type === "tool-result" && typeof c.toolName === "string" && typeof c.toolCallId === "string" && "output" in c;
|
|
933
|
-
}
|
|
934
|
-
function hasInputProperty(obj) {
|
|
935
|
-
return typeof obj === "object" && obj !== null && "input" in obj;
|
|
936
|
-
}
|
|
937
|
-
|
|
938
847
|
// src/protocols/json-mix-protocol.ts
|
|
939
848
|
function processToolCallJson(toolCallJson, fullMatch, processedElements, options) {
|
|
940
849
|
var _a;
|
|
@@ -942,11 +851,17 @@ function processToolCallJson(toolCallJson, fullMatch, processedElements, options
|
|
|
942
851
|
const parsedToolCall = parse(toolCallJson);
|
|
943
852
|
processedElements.push({
|
|
944
853
|
type: "tool-call",
|
|
945
|
-
toolCallId:
|
|
854
|
+
toolCallId: generateId(),
|
|
946
855
|
toolName: parsedToolCall.name,
|
|
947
856
|
input: JSON.stringify((_a = parsedToolCall.arguments) != null ? _a : {})
|
|
948
857
|
});
|
|
949
858
|
} catch (error) {
|
|
859
|
+
logParseFailure({
|
|
860
|
+
phase: "generated-text",
|
|
861
|
+
reason: "Failed to parse tool call JSON segment",
|
|
862
|
+
snippet: fullMatch,
|
|
863
|
+
error
|
|
864
|
+
});
|
|
950
865
|
if (options == null ? void 0 : options.onError) {
|
|
951
866
|
options.onError(
|
|
952
867
|
"Could not process JSON tool call, keeping original text.",
|
|
@@ -979,7 +894,7 @@ function flushBuffer(state, controller, toolCallStart) {
|
|
|
979
894
|
return;
|
|
980
895
|
}
|
|
981
896
|
if (!state.currentTextId) {
|
|
982
|
-
state.currentTextId =
|
|
897
|
+
state.currentTextId = generateId();
|
|
983
898
|
controller.enqueue({ type: "text-start", id: state.currentTextId });
|
|
984
899
|
state.hasEmittedTextStart = true;
|
|
985
900
|
}
|
|
@@ -1002,7 +917,12 @@ function emitIncompleteToolCall(state, controller, toolCallStart) {
|
|
|
1002
917
|
if (!state.currentToolCallJson) {
|
|
1003
918
|
return;
|
|
1004
919
|
}
|
|
1005
|
-
|
|
920
|
+
logParseFailure({
|
|
921
|
+
phase: "stream",
|
|
922
|
+
reason: "Incomplete streaming tool call segment emitted as text",
|
|
923
|
+
snippet: `${toolCallStart}${state.currentToolCallJson}`
|
|
924
|
+
});
|
|
925
|
+
const errorId = generateId();
|
|
1006
926
|
controller.enqueue({ type: "text-start", id: errorId });
|
|
1007
927
|
controller.enqueue({
|
|
1008
928
|
type: "text-delta",
|
|
@@ -1026,7 +946,7 @@ function publishText(text, state, controller) {
|
|
|
1026
946
|
state.currentToolCallJson += text;
|
|
1027
947
|
} else if (text.length > 0) {
|
|
1028
948
|
if (!state.currentTextId) {
|
|
1029
|
-
state.currentTextId =
|
|
949
|
+
state.currentTextId = generateId();
|
|
1030
950
|
controller.enqueue({ type: "text-start", id: state.currentTextId });
|
|
1031
951
|
state.hasEmittedTextStart = true;
|
|
1032
952
|
}
|
|
@@ -1041,16 +961,22 @@ function emitToolCall(context) {
|
|
|
1041
961
|
var _a;
|
|
1042
962
|
const { state, controller, toolCallStart, toolCallEnd, options } = context;
|
|
1043
963
|
try {
|
|
1044
|
-
const parsedToolCall =
|
|
964
|
+
const parsedToolCall = parse(state.currentToolCallJson);
|
|
1045
965
|
closeTextBlock(state, controller);
|
|
1046
966
|
controller.enqueue({
|
|
1047
967
|
type: "tool-call",
|
|
1048
|
-
toolCallId:
|
|
968
|
+
toolCallId: generateId(),
|
|
1049
969
|
toolName: parsedToolCall.name,
|
|
1050
970
|
input: JSON.stringify((_a = parsedToolCall.arguments) != null ? _a : {})
|
|
1051
971
|
});
|
|
1052
|
-
} catch (
|
|
1053
|
-
|
|
972
|
+
} catch (error) {
|
|
973
|
+
logParseFailure({
|
|
974
|
+
phase: "stream",
|
|
975
|
+
reason: "Failed to parse streaming tool call JSON segment",
|
|
976
|
+
snippet: `${toolCallStart}${state.currentToolCallJson}${toolCallEnd}`,
|
|
977
|
+
error
|
|
978
|
+
});
|
|
979
|
+
const errorId = generateId();
|
|
1054
980
|
controller.enqueue({ type: "text-start", id: errorId });
|
|
1055
981
|
controller.enqueue({
|
|
1056
982
|
type: "text-delta",
|
|
@@ -1215,10 +1141,9 @@ var jsonMixProtocol = ({
|
|
|
1215
1141
|
});
|
|
1216
1142
|
|
|
1217
1143
|
// src/protocols/morph-xml-protocol.ts
|
|
1218
|
-
import { generateId as
|
|
1144
|
+
import { generateId as generateId2 } from "@ai-sdk/provider-utils";
|
|
1219
1145
|
import {
|
|
1220
1146
|
extractRawInner,
|
|
1221
|
-
findFirstTopLevelRange,
|
|
1222
1147
|
parse as parse2,
|
|
1223
1148
|
RXMLCoercionError,
|
|
1224
1149
|
RXMLDuplicateStringTagError,
|
|
@@ -1226,7 +1151,338 @@ import {
|
|
|
1226
1151
|
stringify as stringify2,
|
|
1227
1152
|
unwrapJsonSchema
|
|
1228
1153
|
} from "@ai-sdk-tool/rxml";
|
|
1154
|
+
|
|
1155
|
+
// src/utils/type-guards.ts
|
|
1156
|
+
function isToolCallContent(content) {
|
|
1157
|
+
return content.type === "tool-call" && typeof content.toolName === "string" && // input may be a JSON string or an already-parsed object depending on provider/runtime
|
|
1158
|
+
(typeof content.input === "string" || typeof content.input === "object");
|
|
1159
|
+
}
|
|
1160
|
+
function isToolResultPart(content) {
|
|
1161
|
+
const c = content;
|
|
1162
|
+
return !!c && c.type === "tool-result" && typeof c.toolName === "string" && typeof c.toolCallId === "string" && "output" in c;
|
|
1163
|
+
}
|
|
1164
|
+
function hasInputProperty(obj) {
|
|
1165
|
+
return typeof obj === "object" && obj !== null && "input" in obj;
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
// src/protocols/morph-xml-protocol.ts
|
|
1229
1169
|
var WHITESPACE_REGEX2 = /\s/;
|
|
1170
|
+
var MALFORMED_CLOSE_RE = /<\/\s+([A-Za-z0-9_:-]+)\s*>/;
|
|
1171
|
+
var MALFORMED_CLOSE_RE_G = /<\/\s+([A-Za-z0-9_:-]+)\s*>/g;
|
|
1172
|
+
var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
|
|
1173
|
+
var STATUS_TO_STEP_BOUNDARY_RE = /<\/status>\s*<step>/g;
|
|
1174
|
+
var STEP_TAG_RE = /<step>([\s\S]*?)<\/step>/i;
|
|
1175
|
+
var STATUS_TAG_RE = /<status>([\s\S]*?)<\/status>/i;
|
|
1176
|
+
function normalizeCloseTags(xml) {
|
|
1177
|
+
return xml.replace(MALFORMED_CLOSE_RE_G, "</$1>");
|
|
1178
|
+
}
|
|
1179
|
+
function escapeInvalidLt(xml) {
|
|
1180
|
+
const len = xml.length;
|
|
1181
|
+
let out = "";
|
|
1182
|
+
for (let i = 0; i < len; i += 1) {
|
|
1183
|
+
const ch = xml[i];
|
|
1184
|
+
if (ch === "<") {
|
|
1185
|
+
const next = i + 1 < len ? xml[i + 1] : "";
|
|
1186
|
+
if (!(NAME_CHAR_RE.test(next) || next === "/" || next === "!" || next === "?")) {
|
|
1187
|
+
out += "<";
|
|
1188
|
+
continue;
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
out += ch;
|
|
1192
|
+
}
|
|
1193
|
+
return out;
|
|
1194
|
+
}
|
|
1195
|
+
function shouldDeduplicateStringTags(schema) {
|
|
1196
|
+
const unwrapped = unwrapJsonSchema(schema);
|
|
1197
|
+
if (!unwrapped || typeof unwrapped !== "object") {
|
|
1198
|
+
return false;
|
|
1199
|
+
}
|
|
1200
|
+
const props = unwrapped.properties;
|
|
1201
|
+
if (!props) {
|
|
1202
|
+
return false;
|
|
1203
|
+
}
|
|
1204
|
+
const commandRaw = props.command;
|
|
1205
|
+
if (!commandRaw) {
|
|
1206
|
+
return false;
|
|
1207
|
+
}
|
|
1208
|
+
const command = unwrapJsonSchema(commandRaw);
|
|
1209
|
+
return (command == null ? void 0 : command.type) === "array";
|
|
1210
|
+
}
|
|
1211
|
+
function tryParseSecondaryXml(content, toolSchema, options) {
|
|
1212
|
+
const normalized = normalizeCloseTags(content);
|
|
1213
|
+
const balanced = balanceTags(content);
|
|
1214
|
+
const hasMalformedClose = MALFORMED_CLOSE_RE.test(content);
|
|
1215
|
+
if (!hasMalformedClose && balanced.length > normalized.length) {
|
|
1216
|
+
return null;
|
|
1217
|
+
}
|
|
1218
|
+
try {
|
|
1219
|
+
let parsed = parse2(balanced, toolSchema, {
|
|
1220
|
+
onError: options == null ? void 0 : options.onError,
|
|
1221
|
+
noChildNodes: []
|
|
1222
|
+
});
|
|
1223
|
+
parsed = repairParsedAgainstSchema(parsed, toolSchema, options);
|
|
1224
|
+
return parsed;
|
|
1225
|
+
} catch (_e) {
|
|
1226
|
+
if (shouldDeduplicateStringTags(toolSchema)) {
|
|
1227
|
+
const deduped = dedupeStringTagsAgainstSchema(balanced, toolSchema);
|
|
1228
|
+
if (deduped !== balanced) {
|
|
1229
|
+
try {
|
|
1230
|
+
let reparsed = parse2(deduped, toolSchema, {
|
|
1231
|
+
onError: options == null ? void 0 : options.onError,
|
|
1232
|
+
noChildNodes: []
|
|
1233
|
+
});
|
|
1234
|
+
reparsed = repairParsedAgainstSchema(reparsed, toolSchema, options);
|
|
1235
|
+
return reparsed;
|
|
1236
|
+
} catch (_) {
|
|
1237
|
+
return null;
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
return null;
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
function balanceTags(xml) {
|
|
1245
|
+
const src = normalizeCloseTags(xml).replace(
|
|
1246
|
+
STATUS_TO_STEP_BOUNDARY_RE,
|
|
1247
|
+
"</status></step><step>"
|
|
1248
|
+
);
|
|
1249
|
+
let i = 0;
|
|
1250
|
+
const len = src.length;
|
|
1251
|
+
const out = [];
|
|
1252
|
+
const stack = [];
|
|
1253
|
+
while (i < len) {
|
|
1254
|
+
const lt = src.indexOf("<", i);
|
|
1255
|
+
if (lt === -1) {
|
|
1256
|
+
out.push(src.slice(i));
|
|
1257
|
+
break;
|
|
1258
|
+
}
|
|
1259
|
+
out.push(src.slice(i, lt));
|
|
1260
|
+
if (lt + 1 >= len) {
|
|
1261
|
+
break;
|
|
1262
|
+
}
|
|
1263
|
+
const next = src[lt + 1];
|
|
1264
|
+
if (next === "!" || next === "?") {
|
|
1265
|
+
i = handleSpecialTagSegment(src, lt, out);
|
|
1266
|
+
continue;
|
|
1267
|
+
}
|
|
1268
|
+
if (next === "/") {
|
|
1269
|
+
i = handleClosingTagSegment(src, lt, out, stack);
|
|
1270
|
+
continue;
|
|
1271
|
+
}
|
|
1272
|
+
i = handleOpeningTagSegment(src, lt, out, stack);
|
|
1273
|
+
}
|
|
1274
|
+
for (let k = stack.length - 1; k >= 0; k -= 1) {
|
|
1275
|
+
out.push(`</${stack[k]}>`);
|
|
1276
|
+
}
|
|
1277
|
+
return out.join("");
|
|
1278
|
+
}
|
|
1279
|
+
function skipWs(s, p, len) {
|
|
1280
|
+
let idx = p;
|
|
1281
|
+
while (idx < len && WHITESPACE_REGEX2.test(s[idx])) {
|
|
1282
|
+
idx += 1;
|
|
1283
|
+
}
|
|
1284
|
+
return idx;
|
|
1285
|
+
}
|
|
1286
|
+
function parseTagNameAt(s, p, len) {
|
|
1287
|
+
let idx = p;
|
|
1288
|
+
const start = idx;
|
|
1289
|
+
while (idx < len && NAME_CHAR_RE.test(s[idx])) {
|
|
1290
|
+
idx += 1;
|
|
1291
|
+
}
|
|
1292
|
+
return { name: s.slice(start, idx), pos: idx };
|
|
1293
|
+
}
|
|
1294
|
+
function handleSpecialTagSegment(src, lt, out) {
|
|
1295
|
+
const gt = src.indexOf(">", lt + 1);
|
|
1296
|
+
if (gt === -1) {
|
|
1297
|
+
out.push(src.slice(lt));
|
|
1298
|
+
return src.length;
|
|
1299
|
+
}
|
|
1300
|
+
out.push(src.slice(lt, gt + 1));
|
|
1301
|
+
return gt + 1;
|
|
1302
|
+
}
|
|
1303
|
+
function handleClosingTagSegment(src, lt, out, stack) {
|
|
1304
|
+
const len = src.length;
|
|
1305
|
+
let p = skipWs(src, lt + 2, len);
|
|
1306
|
+
const { name, pos } = parseTagNameAt(src, p, len);
|
|
1307
|
+
p = pos;
|
|
1308
|
+
const gt = src.indexOf(">", p);
|
|
1309
|
+
const closingText = gt === -1 ? src.slice(lt) : src.slice(lt, gt + 1);
|
|
1310
|
+
const idx = stack.lastIndexOf(name);
|
|
1311
|
+
if (idx !== -1) {
|
|
1312
|
+
for (let k = stack.length - 1; k > idx; k -= 1) {
|
|
1313
|
+
out.push(`</${stack[k]}>`);
|
|
1314
|
+
stack.pop();
|
|
1315
|
+
}
|
|
1316
|
+
out.push(closingText);
|
|
1317
|
+
stack.pop();
|
|
1318
|
+
}
|
|
1319
|
+
return gt === -1 ? len : gt + 1;
|
|
1320
|
+
}
|
|
1321
|
+
function handleOpeningTagSegment(src, lt, out, stack) {
|
|
1322
|
+
const len = src.length;
|
|
1323
|
+
let p = skipWs(src, lt + 1, len);
|
|
1324
|
+
const nameStart = p;
|
|
1325
|
+
const parsed = parseTagNameAt(src, p, len);
|
|
1326
|
+
p = parsed.pos;
|
|
1327
|
+
const name = src.slice(nameStart, p);
|
|
1328
|
+
const q = src.indexOf(">", p);
|
|
1329
|
+
if (q === -1) {
|
|
1330
|
+
out.push(src.slice(lt));
|
|
1331
|
+
return len;
|
|
1332
|
+
}
|
|
1333
|
+
let r = q - 1;
|
|
1334
|
+
while (r >= nameStart && WHITESPACE_REGEX2.test(src[r])) {
|
|
1335
|
+
r -= 1;
|
|
1336
|
+
}
|
|
1337
|
+
const selfClosing = src[r] === "/";
|
|
1338
|
+
out.push(src.slice(lt, q + 1));
|
|
1339
|
+
if (!selfClosing && name) {
|
|
1340
|
+
stack.push(name);
|
|
1341
|
+
}
|
|
1342
|
+
return q + 1;
|
|
1343
|
+
}
|
|
1344
|
+
function repairParsedAgainstSchema(input, schema, options) {
|
|
1345
|
+
if (!input || typeof input !== "object") {
|
|
1346
|
+
return input;
|
|
1347
|
+
}
|
|
1348
|
+
const unwrapped = unwrapJsonSchema(schema);
|
|
1349
|
+
if (!unwrapped || typeof unwrapped !== "object") {
|
|
1350
|
+
return input;
|
|
1351
|
+
}
|
|
1352
|
+
const properties = unwrapped.properties;
|
|
1353
|
+
if (!properties) {
|
|
1354
|
+
return input;
|
|
1355
|
+
}
|
|
1356
|
+
applySchemaProps(input, properties, options);
|
|
1357
|
+
return input;
|
|
1358
|
+
}
|
|
1359
|
+
function applySchemaProps(obj, properties, options) {
|
|
1360
|
+
for (const key of Object.keys(obj)) {
|
|
1361
|
+
const propSchema = properties[key];
|
|
1362
|
+
if (!propSchema) {
|
|
1363
|
+
continue;
|
|
1364
|
+
}
|
|
1365
|
+
const prop = unwrapJsonSchema(propSchema);
|
|
1366
|
+
const propType = prop.type;
|
|
1367
|
+
if (propType === "array" && prop.items) {
|
|
1368
|
+
const itemSchemaRaw = prop.items;
|
|
1369
|
+
const itemSchema = unwrapJsonSchema(itemSchemaRaw);
|
|
1370
|
+
obj[key] = coerceArrayItems(obj[key], itemSchema, options);
|
|
1371
|
+
continue;
|
|
1372
|
+
}
|
|
1373
|
+
if (propType === "object") {
|
|
1374
|
+
const val = obj[key];
|
|
1375
|
+
if (val && typeof val === "object") {
|
|
1376
|
+
obj[key] = repairParsedAgainstSchema(
|
|
1377
|
+
val,
|
|
1378
|
+
prop,
|
|
1379
|
+
options
|
|
1380
|
+
);
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
function coerceArrayItems(val, itemSchema, options) {
|
|
1386
|
+
if (!Array.isArray(val)) {
|
|
1387
|
+
return val;
|
|
1388
|
+
}
|
|
1389
|
+
return val.map((v) => coerceArrayItem(v, itemSchema, options));
|
|
1390
|
+
}
|
|
1391
|
+
function coerceArrayItem(v, itemSchema, options) {
|
|
1392
|
+
const itemType = itemSchema == null ? void 0 : itemSchema.type;
|
|
1393
|
+
if (typeof v === "string" && itemType === "object") {
|
|
1394
|
+
const parsed = tryParseStringToSchemaObject(v, itemSchema, options);
|
|
1395
|
+
if (parsed !== null) {
|
|
1396
|
+
return parsed;
|
|
1397
|
+
}
|
|
1398
|
+
const fallback = extractStepStatusFromString(normalizeCloseTags(v));
|
|
1399
|
+
if (fallback) {
|
|
1400
|
+
return fallback;
|
|
1401
|
+
}
|
|
1402
|
+
return v;
|
|
1403
|
+
}
|
|
1404
|
+
if (v && typeof v === "object" && itemType === "object") {
|
|
1405
|
+
return repairParsedAgainstSchema(
|
|
1406
|
+
v,
|
|
1407
|
+
itemSchema,
|
|
1408
|
+
options
|
|
1409
|
+
);
|
|
1410
|
+
}
|
|
1411
|
+
return v;
|
|
1412
|
+
}
|
|
1413
|
+
function getStringPropertyNames(schema) {
|
|
1414
|
+
const unwrapped = unwrapJsonSchema(schema);
|
|
1415
|
+
if (!unwrapped || typeof unwrapped !== "object") {
|
|
1416
|
+
return [];
|
|
1417
|
+
}
|
|
1418
|
+
const props = unwrapped.properties;
|
|
1419
|
+
if (!props) {
|
|
1420
|
+
return [];
|
|
1421
|
+
}
|
|
1422
|
+
const names = [];
|
|
1423
|
+
for (const key of Object.keys(props)) {
|
|
1424
|
+
const prop = unwrapJsonSchema(
|
|
1425
|
+
props[key]
|
|
1426
|
+
);
|
|
1427
|
+
const type = prop.type;
|
|
1428
|
+
if (type === "string") {
|
|
1429
|
+
names.push(key);
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
return names;
|
|
1433
|
+
}
|
|
1434
|
+
function escapeRegExp2(s) {
|
|
1435
|
+
return s.replace(/[.*+?^${}()|[\\]\\]/g, "\\$&");
|
|
1436
|
+
}
|
|
1437
|
+
function dedupeStringTagsAgainstSchema(xml, schema) {
|
|
1438
|
+
const names = getStringPropertyNames(schema);
|
|
1439
|
+
let out = xml;
|
|
1440
|
+
for (const key of names) {
|
|
1441
|
+
out = dedupeSingleTag(out, key);
|
|
1442
|
+
}
|
|
1443
|
+
return out;
|
|
1444
|
+
}
|
|
1445
|
+
function dedupeSingleTag(xml, key) {
|
|
1446
|
+
var _a, _b;
|
|
1447
|
+
const escaped = escapeRegExp2(key);
|
|
1448
|
+
const re = new RegExp(`<${escaped}>([\\s\\S]*?)<\\/${escaped}>`, "g");
|
|
1449
|
+
const matches = Array.from(xml.matchAll(re));
|
|
1450
|
+
if (matches.length <= 1) {
|
|
1451
|
+
return xml;
|
|
1452
|
+
}
|
|
1453
|
+
const last = matches.at(-1);
|
|
1454
|
+
let result = "";
|
|
1455
|
+
let cursor = 0;
|
|
1456
|
+
for (const m of matches) {
|
|
1457
|
+
const idx = (_a = m.index) != null ? _a : 0;
|
|
1458
|
+
result += xml.slice(cursor, idx);
|
|
1459
|
+
if (last && idx === ((_b = last.index) != null ? _b : -1)) {
|
|
1460
|
+
result += m[0];
|
|
1461
|
+
}
|
|
1462
|
+
cursor = idx + m[0].length;
|
|
1463
|
+
}
|
|
1464
|
+
result += xml.slice(cursor);
|
|
1465
|
+
return result;
|
|
1466
|
+
}
|
|
1467
|
+
function tryParseStringToSchemaObject(xml, itemSchema, options) {
|
|
1468
|
+
try {
|
|
1469
|
+
const fixed = parse2(normalizeCloseTags(xml), itemSchema, {
|
|
1470
|
+
onError: options == null ? void 0 : options.onError,
|
|
1471
|
+
noChildNodes: []
|
|
1472
|
+
});
|
|
1473
|
+
return typeof fixed === "string" ? null : fixed;
|
|
1474
|
+
} catch (e) {
|
|
1475
|
+
return null;
|
|
1476
|
+
}
|
|
1477
|
+
}
|
|
1478
|
+
function extractStepStatusFromString(normXml) {
|
|
1479
|
+
const stepMatch = normXml.match(STEP_TAG_RE);
|
|
1480
|
+
const statusMatch = normXml.match(STATUS_TAG_RE);
|
|
1481
|
+
if (stepMatch && statusMatch) {
|
|
1482
|
+
return { step: stepMatch[1], status: statusMatch[1] };
|
|
1483
|
+
}
|
|
1484
|
+
return null;
|
|
1485
|
+
}
|
|
1230
1486
|
function processTextBeforeToolCall(text, currentIndex, toolCallStartIndex, processedElements) {
|
|
1231
1487
|
if (toolCallStartIndex > currentIndex) {
|
|
1232
1488
|
const textSegment = text.substring(currentIndex, toolCallStartIndex);
|
|
@@ -1239,20 +1495,36 @@ function processTextBeforeToolCall(text, currentIndex, toolCallStartIndex, proce
|
|
|
1239
1495
|
function processToolCall(params) {
|
|
1240
1496
|
var _a;
|
|
1241
1497
|
const { toolCall, tools, options, text, processedElements } = params;
|
|
1498
|
+
const toolSchema = getToolSchema(tools, toolCall.toolName);
|
|
1242
1499
|
try {
|
|
1243
|
-
const
|
|
1244
|
-
|
|
1500
|
+
const primary = escapeInvalidLt(normalizeCloseTags(toolCall.content));
|
|
1501
|
+
let parsed = parse2(primary, toolSchema, {
|
|
1245
1502
|
onError: options == null ? void 0 : options.onError,
|
|
1246
1503
|
// Disable HTML self-closing tag behavior to allow base, meta, link etc. as regular tags
|
|
1247
1504
|
noChildNodes: []
|
|
1248
1505
|
});
|
|
1506
|
+
parsed = repairParsedAgainstSchema(parsed, toolSchema, options);
|
|
1249
1507
|
processedElements.push({
|
|
1250
1508
|
type: "tool-call",
|
|
1251
|
-
toolCallId:
|
|
1509
|
+
toolCallId: generateId2(),
|
|
1252
1510
|
toolName: toolCall.toolName,
|
|
1253
1511
|
input: JSON.stringify(parsed)
|
|
1254
1512
|
});
|
|
1255
1513
|
} catch (error) {
|
|
1514
|
+
const reparsed = tryParseSecondaryXml(
|
|
1515
|
+
toolCall.content,
|
|
1516
|
+
toolSchema,
|
|
1517
|
+
options
|
|
1518
|
+
);
|
|
1519
|
+
if (reparsed !== null) {
|
|
1520
|
+
processedElements.push({
|
|
1521
|
+
type: "tool-call",
|
|
1522
|
+
toolCallId: generateId2(),
|
|
1523
|
+
toolName: toolCall.toolName,
|
|
1524
|
+
input: JSON.stringify(reparsed)
|
|
1525
|
+
});
|
|
1526
|
+
return;
|
|
1527
|
+
}
|
|
1256
1528
|
const originalCallText = text.substring(
|
|
1257
1529
|
toolCall.startIndex,
|
|
1258
1530
|
toolCall.endIndex
|
|
@@ -1276,20 +1548,33 @@ function addRemainingText(text, currentIndex, processedElements) {
|
|
|
1276
1548
|
}
|
|
1277
1549
|
function handleStreamingToolCallEnd(params) {
|
|
1278
1550
|
const { toolContent, currentToolCall, tools, options, ctrl, flushText } = params;
|
|
1551
|
+
const toolSchema = getToolSchema(tools, currentToolCall.name);
|
|
1279
1552
|
try {
|
|
1280
|
-
const
|
|
1281
|
-
|
|
1553
|
+
const primary = escapeInvalidLt(normalizeCloseTags(toolContent));
|
|
1554
|
+
let parsed = parse2(primary, toolSchema, {
|
|
1282
1555
|
onError: options == null ? void 0 : options.onError,
|
|
1283
1556
|
noChildNodes: []
|
|
1284
1557
|
});
|
|
1558
|
+
parsed = repairParsedAgainstSchema(parsed, toolSchema, options);
|
|
1285
1559
|
flushText(ctrl);
|
|
1286
1560
|
ctrl.enqueue({
|
|
1287
1561
|
type: "tool-call",
|
|
1288
|
-
toolCallId:
|
|
1562
|
+
toolCallId: generateId2(),
|
|
1289
1563
|
toolName: currentToolCall.name,
|
|
1290
1564
|
input: JSON.stringify(parsed)
|
|
1291
1565
|
});
|
|
1292
1566
|
} catch (error) {
|
|
1567
|
+
const parsed = tryParseSecondaryXml(toolContent, toolSchema, options);
|
|
1568
|
+
if (parsed !== null) {
|
|
1569
|
+
flushText(ctrl);
|
|
1570
|
+
ctrl.enqueue({
|
|
1571
|
+
type: "tool-call",
|
|
1572
|
+
toolCallId: generateId2(),
|
|
1573
|
+
toolName: currentToolCall.name,
|
|
1574
|
+
input: JSON.stringify(parsed)
|
|
1575
|
+
});
|
|
1576
|
+
return;
|
|
1577
|
+
}
|
|
1293
1578
|
handleStreamingToolCallError({
|
|
1294
1579
|
error,
|
|
1295
1580
|
currentToolCall,
|
|
@@ -1321,19 +1606,28 @@ function handleStreamingToolCallError(params) {
|
|
|
1321
1606
|
flushText(ctrl, originalCallText);
|
|
1322
1607
|
}
|
|
1323
1608
|
function findEarliestToolTag(buffer, toolNames) {
|
|
1324
|
-
let
|
|
1325
|
-
let
|
|
1609
|
+
let bestIndex = -1;
|
|
1610
|
+
let bestName = "";
|
|
1611
|
+
let bestSelfClosing = false;
|
|
1326
1612
|
if (toolNames.length > 0) {
|
|
1327
1613
|
for (const name of toolNames) {
|
|
1328
|
-
const
|
|
1329
|
-
const
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1614
|
+
const openTag = `<${name}>`;
|
|
1615
|
+
const selfTag = `<${name}/>`;
|
|
1616
|
+
const idxOpen = buffer.indexOf(openTag);
|
|
1617
|
+
const idxSelf = buffer.indexOf(selfTag);
|
|
1618
|
+
if (idxOpen !== -1 && (bestIndex === -1 || idxOpen < bestIndex)) {
|
|
1619
|
+
bestIndex = idxOpen;
|
|
1620
|
+
bestName = name;
|
|
1621
|
+
bestSelfClosing = false;
|
|
1622
|
+
}
|
|
1623
|
+
if (idxSelf !== -1 && (bestIndex === -1 || idxSelf < bestIndex)) {
|
|
1624
|
+
bestIndex = idxSelf;
|
|
1625
|
+
bestName = name;
|
|
1626
|
+
bestSelfClosing = true;
|
|
1333
1627
|
}
|
|
1334
1628
|
}
|
|
1335
1629
|
}
|
|
1336
|
-
return { index:
|
|
1630
|
+
return { index: bestIndex, name: bestName, selfClosing: bestSelfClosing };
|
|
1337
1631
|
}
|
|
1338
1632
|
function handleNoToolTagInBuffer(buffer, maxStartTagLen, controller, flushText) {
|
|
1339
1633
|
const tail = Math.max(0, maxStartTagLen - 1);
|
|
@@ -1356,10 +1650,12 @@ function processToolCallInBuffer(params) {
|
|
|
1356
1650
|
setBuffer
|
|
1357
1651
|
} = params;
|
|
1358
1652
|
const endTag = `</${currentToolCall.name}>`;
|
|
1359
|
-
const
|
|
1653
|
+
const normalized = normalizeCloseTags(buffer);
|
|
1654
|
+
const effectiveBuffer = normalized;
|
|
1655
|
+
const endTagIndex = effectiveBuffer.indexOf(endTag);
|
|
1360
1656
|
if (endTagIndex !== -1) {
|
|
1361
|
-
const toolContent =
|
|
1362
|
-
const newBuffer =
|
|
1657
|
+
const toolContent = effectiveBuffer.substring(0, endTagIndex);
|
|
1658
|
+
const newBuffer = effectiveBuffer.substring(endTagIndex + endTag.length);
|
|
1363
1659
|
setBuffer("");
|
|
1364
1660
|
handleStreamingToolCallEnd({
|
|
1365
1661
|
toolContent,
|
|
@@ -1372,14 +1668,46 @@ function processToolCallInBuffer(params) {
|
|
|
1372
1668
|
setBuffer(newBuffer);
|
|
1373
1669
|
return { buffer: newBuffer, currentToolCall: null, shouldBreak: false };
|
|
1374
1670
|
}
|
|
1375
|
-
return { buffer, currentToolCall, shouldBreak: true };
|
|
1671
|
+
return { buffer: effectiveBuffer, currentToolCall, shouldBreak: true };
|
|
1376
1672
|
}
|
|
1377
1673
|
function processNoToolCallInBuffer(params) {
|
|
1378
|
-
const {
|
|
1379
|
-
|
|
1674
|
+
const {
|
|
1675
|
+
buffer,
|
|
1676
|
+
toolNames,
|
|
1677
|
+
maxStartTagLen,
|
|
1678
|
+
controller,
|
|
1679
|
+
flushText,
|
|
1680
|
+
tools,
|
|
1681
|
+
options
|
|
1682
|
+
} = params;
|
|
1683
|
+
const {
|
|
1684
|
+
index: earliestStartTagIndex,
|
|
1685
|
+
name: earliestToolName,
|
|
1686
|
+
selfClosing
|
|
1687
|
+
} = findEarliestToolTag(buffer, toolNames);
|
|
1380
1688
|
if (earliestStartTagIndex !== -1) {
|
|
1381
1689
|
const textBeforeTag = buffer.substring(0, earliestStartTagIndex);
|
|
1382
1690
|
flushText(controller, textBeforeTag);
|
|
1691
|
+
if (selfClosing) {
|
|
1692
|
+
const selfTag = `<${earliestToolName}/>`;
|
|
1693
|
+
const newBuffer2 = buffer.substring(
|
|
1694
|
+
earliestStartTagIndex + selfTag.length
|
|
1695
|
+
);
|
|
1696
|
+
handleStreamingToolCallEnd({
|
|
1697
|
+
toolContent: "",
|
|
1698
|
+
currentToolCall: { name: earliestToolName, content: "" },
|
|
1699
|
+
tools,
|
|
1700
|
+
options,
|
|
1701
|
+
ctrl: controller,
|
|
1702
|
+
flushText
|
|
1703
|
+
});
|
|
1704
|
+
return {
|
|
1705
|
+
buffer: newBuffer2,
|
|
1706
|
+
currentToolCall: null,
|
|
1707
|
+
shouldBreak: false,
|
|
1708
|
+
shouldContinue: false
|
|
1709
|
+
};
|
|
1710
|
+
}
|
|
1383
1711
|
const startTag = `<${earliestToolName}>`;
|
|
1384
1712
|
const newBuffer = buffer.substring(earliestStartTagIndex + startTag.length);
|
|
1385
1713
|
return {
|
|
@@ -1408,7 +1736,7 @@ function createFlushTextHandler(getBuffer, setBuffer, getCurrentTextId, setCurre
|
|
|
1408
1736
|
if (content) {
|
|
1409
1737
|
const currentTextId2 = getCurrentTextId();
|
|
1410
1738
|
if (!currentTextId2) {
|
|
1411
|
-
const newId =
|
|
1739
|
+
const newId = generateId2();
|
|
1412
1740
|
setCurrentTextId(newId);
|
|
1413
1741
|
controller.enqueue({ type: "text-start", id: newId });
|
|
1414
1742
|
}
|
|
@@ -1460,6 +1788,8 @@ function processBufferWithoutToolCall(params, controller) {
|
|
|
1460
1788
|
getBuffer,
|
|
1461
1789
|
setBuffer,
|
|
1462
1790
|
setCurrentToolCall,
|
|
1791
|
+
tools,
|
|
1792
|
+
options,
|
|
1463
1793
|
toolNames,
|
|
1464
1794
|
maxStartTagLen,
|
|
1465
1795
|
flushText
|
|
@@ -1469,7 +1799,9 @@ function processBufferWithoutToolCall(params, controller) {
|
|
|
1469
1799
|
toolNames,
|
|
1470
1800
|
maxStartTagLen,
|
|
1471
1801
|
controller,
|
|
1472
|
-
flushText
|
|
1802
|
+
flushText,
|
|
1803
|
+
tools,
|
|
1804
|
+
options
|
|
1473
1805
|
});
|
|
1474
1806
|
setBuffer(result.buffer);
|
|
1475
1807
|
setCurrentToolCall(result.currentToolCall);
|
|
@@ -1544,7 +1876,17 @@ var morphXmlProtocol = () => ({
|
|
|
1544
1876
|
}
|
|
1545
1877
|
const processedElements = [];
|
|
1546
1878
|
let currentIndex = 0;
|
|
1547
|
-
const
|
|
1879
|
+
const toolCallsRaw = findToolCalls(text, toolNames);
|
|
1880
|
+
const toolCallsNorm = collectToolCallsFromNormalizedText(text, toolNames);
|
|
1881
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1882
|
+
const toolCalls = [...toolCallsRaw, ...toolCallsNorm].filter((tc) => {
|
|
1883
|
+
const key = `${tc.toolName}:${tc.startIndex}:${tc.endIndex}`;
|
|
1884
|
+
if (seen.has(key)) {
|
|
1885
|
+
return false;
|
|
1886
|
+
}
|
|
1887
|
+
seen.add(key);
|
|
1888
|
+
return true;
|
|
1889
|
+
}).sort((a, b) => a.startIndex - b.startIndex);
|
|
1548
1890
|
for (const toolCall of toolCalls) {
|
|
1549
1891
|
currentIndex = processTextBeforeToolCall(
|
|
1550
1892
|
text,
|
|
@@ -1632,53 +1974,225 @@ function getToolSchema(tools, toolName) {
|
|
|
1632
1974
|
var _a;
|
|
1633
1975
|
return (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
|
|
1634
1976
|
}
|
|
1635
|
-
function
|
|
1636
|
-
let
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1977
|
+
function findClosingTagEndFlexible(text, contentStart, toolName) {
|
|
1978
|
+
let pos = contentStart;
|
|
1979
|
+
let depth = 1;
|
|
1980
|
+
while (pos < text.length) {
|
|
1981
|
+
const tok = nextTagToken(text, pos);
|
|
1982
|
+
if (tok.kind === "eof") {
|
|
1983
|
+
break;
|
|
1984
|
+
}
|
|
1985
|
+
const result = updateDepthWithToken(tok, toolName, depth);
|
|
1986
|
+
depth = result.depth;
|
|
1987
|
+
if (result.closedAt !== void 0) {
|
|
1988
|
+
return result.closedAt;
|
|
1989
|
+
}
|
|
1990
|
+
pos = tok.nextPos;
|
|
1991
|
+
}
|
|
1992
|
+
return -1;
|
|
1993
|
+
}
|
|
1994
|
+
function skipSpecialSegment(text, lt) {
|
|
1995
|
+
const next = text[lt + 1];
|
|
1996
|
+
if (next !== "!" && next !== "?") {
|
|
1997
|
+
return null;
|
|
1998
|
+
}
|
|
1999
|
+
const gt = text.indexOf(">", lt + 1);
|
|
2000
|
+
if (gt === -1) {
|
|
2001
|
+
return null;
|
|
2002
|
+
}
|
|
2003
|
+
return gt + 1;
|
|
2004
|
+
}
|
|
2005
|
+
function consumeClosingTag(text, lt, toolName) {
|
|
2006
|
+
let p = lt + 2;
|
|
2007
|
+
while (p < text.length && WHITESPACE_REGEX2.test(text[p])) {
|
|
2008
|
+
p += 1;
|
|
2009
|
+
}
|
|
2010
|
+
if (text.slice(p, p + toolName.length) === toolName) {
|
|
2011
|
+
p += toolName.length;
|
|
1640
2012
|
while (p < text.length && WHITESPACE_REGEX2.test(text[p])) {
|
|
1641
2013
|
p += 1;
|
|
1642
2014
|
}
|
|
1643
2015
|
if (text[p] === ">") {
|
|
1644
|
-
|
|
2016
|
+
const endPos2 = p + 1;
|
|
2017
|
+
return { matched: true, endPos: endPos2 };
|
|
1645
2018
|
}
|
|
1646
2019
|
}
|
|
1647
|
-
|
|
2020
|
+
const gt = text.indexOf(">", lt + 1);
|
|
2021
|
+
const endPos = gt === -1 ? text.length : gt + 1;
|
|
2022
|
+
return { matched: false, endPos };
|
|
1648
2023
|
}
|
|
1649
|
-
function
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
const
|
|
1655
|
-
|
|
1656
|
-
|
|
2024
|
+
function consumeOpenTag(text, lt) {
|
|
2025
|
+
let p = lt + 1;
|
|
2026
|
+
while (p < text.length && WHITESPACE_REGEX2.test(text[p])) {
|
|
2027
|
+
p += 1;
|
|
2028
|
+
}
|
|
2029
|
+
const nameStart = p;
|
|
2030
|
+
while (p < text.length && NAME_CHAR_RE.test(text.charAt(p))) {
|
|
2031
|
+
p += 1;
|
|
2032
|
+
}
|
|
2033
|
+
const name = text.slice(nameStart, p);
|
|
2034
|
+
const q = text.indexOf(">", p);
|
|
2035
|
+
if (q === -1) {
|
|
2036
|
+
return null;
|
|
2037
|
+
}
|
|
2038
|
+
let r = q - 1;
|
|
2039
|
+
while (r >= nameStart && WHITESPACE_REGEX2.test(text[r])) {
|
|
2040
|
+
r -= 1;
|
|
2041
|
+
}
|
|
2042
|
+
const selfClosing = text[r] === "/";
|
|
2043
|
+
return { name, selfClosing, nextPos: q + 1 };
|
|
2044
|
+
}
|
|
2045
|
+
function updateDepthWithToken(tok, toolName, depth) {
|
|
2046
|
+
if (tok.kind === "close" && tok.name === toolName) {
|
|
2047
|
+
const newDepth = depth - 1;
|
|
2048
|
+
return newDepth === 0 ? { depth: newDepth, closedAt: tok.nextPos } : { depth: newDepth };
|
|
2049
|
+
}
|
|
2050
|
+
if (tok.kind === "open" && tok.name === toolName && !tok.selfClosing) {
|
|
2051
|
+
return { depth: depth + 1 };
|
|
2052
|
+
}
|
|
2053
|
+
return { depth };
|
|
2054
|
+
}
|
|
2055
|
+
function nextTagToken(text, fromPos) {
|
|
2056
|
+
const lt = text.indexOf("<", fromPos);
|
|
2057
|
+
if (lt === -1 || lt + 1 >= text.length) {
|
|
2058
|
+
return { kind: "eof", nextPos: text.length };
|
|
2059
|
+
}
|
|
2060
|
+
const next = text[lt + 1];
|
|
2061
|
+
const specialEnd = skipSpecialSegment(text, lt);
|
|
2062
|
+
if (specialEnd !== null) {
|
|
2063
|
+
return { kind: "special", nextPos: specialEnd };
|
|
2064
|
+
}
|
|
2065
|
+
if (next === "/") {
|
|
2066
|
+
const closing = consumeClosingTag(text, lt, "");
|
|
2067
|
+
let p = lt + 2;
|
|
2068
|
+
while (p < text.length && WHITESPACE_REGEX2.test(text[p])) {
|
|
2069
|
+
p += 1;
|
|
2070
|
+
}
|
|
2071
|
+
const nameStart = p;
|
|
2072
|
+
while (p < text.length && NAME_CHAR_RE.test(text.charAt(p))) {
|
|
2073
|
+
p += 1;
|
|
2074
|
+
}
|
|
2075
|
+
const name = text.slice(nameStart, p);
|
|
2076
|
+
return { kind: "close", name, nextPos: closing.endPos };
|
|
2077
|
+
}
|
|
2078
|
+
const open = consumeOpenTag(text, lt);
|
|
2079
|
+
if (open === null) {
|
|
2080
|
+
return { kind: "eof", nextPos: text.length };
|
|
2081
|
+
}
|
|
1657
2082
|
return {
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
segment
|
|
2083
|
+
kind: "open",
|
|
2084
|
+
name: open.name,
|
|
2085
|
+
selfClosing: open.selfClosing,
|
|
2086
|
+
nextPos: open.nextPos
|
|
1663
2087
|
};
|
|
1664
2088
|
}
|
|
2089
|
+
function collectToolCallsFromNormalizedText(text, toolNames) {
|
|
2090
|
+
var _a;
|
|
2091
|
+
const normalizedText = normalizeCloseTags(text);
|
|
2092
|
+
const collected = [];
|
|
2093
|
+
for (const toolName of toolNames) {
|
|
2094
|
+
const startTag = `<${toolName}>`;
|
|
2095
|
+
let idx = 0;
|
|
2096
|
+
let lastOrigIdx = 0;
|
|
2097
|
+
while (idx < normalizedText.length) {
|
|
2098
|
+
const tagStartNorm = normalizedText.indexOf(startTag, idx);
|
|
2099
|
+
if (tagStartNorm === -1) {
|
|
2100
|
+
break;
|
|
2101
|
+
}
|
|
2102
|
+
const contentStartNorm = tagStartNorm + startTag.length;
|
|
2103
|
+
const endNorm = findClosingTagEndFlexible(
|
|
2104
|
+
normalizedText,
|
|
2105
|
+
contentStartNorm,
|
|
2106
|
+
toolName
|
|
2107
|
+
);
|
|
2108
|
+
if (endNorm > contentStartNorm) {
|
|
2109
|
+
const tagStartOrig = text.indexOf(startTag, lastOrigIdx);
|
|
2110
|
+
const contentStartOrig = tagStartOrig + startTag.length;
|
|
2111
|
+
let endOrig = findClosingTagEndFlexible(
|
|
2112
|
+
text,
|
|
2113
|
+
contentStartOrig,
|
|
2114
|
+
toolName
|
|
2115
|
+
);
|
|
2116
|
+
if (endOrig === -1) {
|
|
2117
|
+
const approxLen = endNorm - tagStartNorm;
|
|
2118
|
+
endOrig = Math.min(text.length, tagStartOrig + approxLen);
|
|
2119
|
+
}
|
|
2120
|
+
const segment = text.substring(tagStartOrig, endOrig);
|
|
2121
|
+
const inner = (_a = extractRawInner(segment, toolName)) != null ? _a : segment.substring(startTag.length, segment.lastIndexOf("<"));
|
|
2122
|
+
collected.push({
|
|
2123
|
+
toolName,
|
|
2124
|
+
startIndex: tagStartOrig,
|
|
2125
|
+
endIndex: endOrig,
|
|
2126
|
+
content: inner,
|
|
2127
|
+
segment
|
|
2128
|
+
});
|
|
2129
|
+
lastOrigIdx = endOrig;
|
|
2130
|
+
idx = endNorm;
|
|
2131
|
+
} else {
|
|
2132
|
+
idx = contentStartNorm;
|
|
2133
|
+
}
|
|
2134
|
+
}
|
|
2135
|
+
}
|
|
2136
|
+
return collected.sort((a, b) => a.startIndex - b.startIndex);
|
|
2137
|
+
}
|
|
2138
|
+
function getNextTagInfo(text, toolName, fromIndex) {
|
|
2139
|
+
const startTag = `<${toolName}>`;
|
|
2140
|
+
const selfTag = `<${toolName}/>`;
|
|
2141
|
+
const openIdx = text.indexOf(startTag, fromIndex);
|
|
2142
|
+
const selfIdx = text.indexOf(selfTag, fromIndex);
|
|
2143
|
+
const hasOpen = openIdx !== -1;
|
|
2144
|
+
const hasSelf = selfIdx !== -1;
|
|
2145
|
+
if (!(hasOpen || hasSelf)) {
|
|
2146
|
+
return {
|
|
2147
|
+
found: false,
|
|
2148
|
+
tagStart: -1,
|
|
2149
|
+
selfClosing: false,
|
|
2150
|
+
startTag,
|
|
2151
|
+
selfTag
|
|
2152
|
+
};
|
|
2153
|
+
}
|
|
2154
|
+
const pickSelf = hasSelf && (!hasOpen || selfIdx < openIdx);
|
|
2155
|
+
const tagStart = pickSelf ? selfIdx : openIdx;
|
|
2156
|
+
return { found: true, tagStart, selfClosing: pickSelf, startTag, selfTag };
|
|
2157
|
+
}
|
|
1665
2158
|
function findToolCallsForName(text, toolName) {
|
|
2159
|
+
var _a;
|
|
1666
2160
|
const toolCalls = [];
|
|
1667
|
-
const startTag = `<${toolName}>`;
|
|
1668
2161
|
let searchIndex = 0;
|
|
1669
2162
|
while (searchIndex < text.length) {
|
|
1670
|
-
const
|
|
1671
|
-
if (
|
|
2163
|
+
const info = getNextTagInfo(text, toolName, searchIndex);
|
|
2164
|
+
if (!info.found) {
|
|
1672
2165
|
break;
|
|
1673
2166
|
}
|
|
1674
|
-
const
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
const
|
|
1678
|
-
toolCalls.push(
|
|
1679
|
-
|
|
2167
|
+
const { tagStart, selfClosing, startTag, selfTag } = info;
|
|
2168
|
+
if (selfClosing) {
|
|
2169
|
+
const endIndex = tagStart + selfTag.length;
|
|
2170
|
+
const segment = text.substring(tagStart, endIndex);
|
|
2171
|
+
toolCalls.push({
|
|
2172
|
+
toolName,
|
|
2173
|
+
startIndex: tagStart,
|
|
2174
|
+
endIndex,
|
|
2175
|
+
content: "",
|
|
2176
|
+
segment
|
|
2177
|
+
});
|
|
2178
|
+
searchIndex = endIndex;
|
|
2179
|
+
continue;
|
|
2180
|
+
}
|
|
2181
|
+
const contentStart = tagStart + startTag.length;
|
|
2182
|
+
const fullTagEnd = findClosingTagEndFlexible(text, contentStart, toolName);
|
|
2183
|
+
if (fullTagEnd !== -1 && fullTagEnd > contentStart) {
|
|
2184
|
+
const segment = text.substring(tagStart, fullTagEnd);
|
|
2185
|
+
const inner = (_a = extractRawInner(segment, toolName)) != null ? _a : segment.substring(startTag.length, segment.lastIndexOf("<"));
|
|
2186
|
+
toolCalls.push({
|
|
2187
|
+
toolName,
|
|
2188
|
+
startIndex: tagStart,
|
|
2189
|
+
endIndex: fullTagEnd,
|
|
2190
|
+
content: inner,
|
|
2191
|
+
segment
|
|
2192
|
+
});
|
|
2193
|
+
searchIndex = fullTagEnd;
|
|
1680
2194
|
} else {
|
|
1681
|
-
searchIndex =
|
|
2195
|
+
searchIndex = contentStart;
|
|
1682
2196
|
}
|
|
1683
2197
|
}
|
|
1684
2198
|
return toolCalls;
|
|
@@ -1692,14 +2206,53 @@ function findToolCalls(text, toolNames) {
|
|
|
1692
2206
|
return toolCalls.sort((a, b) => a.startIndex - b.startIndex);
|
|
1693
2207
|
}
|
|
1694
2208
|
|
|
1695
|
-
// src/
|
|
1696
|
-
|
|
1697
|
-
|
|
2209
|
+
// src/generate-handler.ts
|
|
2210
|
+
import { generateId as generateId3 } from "@ai-sdk/provider-utils";
|
|
2211
|
+
import { coerceBySchema } from "@ai-sdk-tool/rxml";
|
|
2212
|
+
|
|
2213
|
+
// src/utils/on-error.ts
|
|
2214
|
+
function extractOnErrorOption(providerOptions) {
|
|
2215
|
+
var _a;
|
|
2216
|
+
if (providerOptions && typeof providerOptions === "object") {
|
|
2217
|
+
const onError = (_a = providerOptions.toolCallMiddleware) == null ? void 0 : _a.onError;
|
|
2218
|
+
return onError ? { onError } : void 0;
|
|
2219
|
+
}
|
|
2220
|
+
return;
|
|
2221
|
+
}
|
|
2222
|
+
|
|
2223
|
+
// src/utils/provider-options.ts
|
|
2224
|
+
var originalToolsSchema = {
|
|
2225
|
+
encode: encodeOriginalTools,
|
|
2226
|
+
decode: decodeOriginalTools
|
|
2227
|
+
};
|
|
2228
|
+
function encodeOriginalTools(tools) {
|
|
2229
|
+
return (tools == null ? void 0 : tools.map((t) => ({
|
|
2230
|
+
name: t.name,
|
|
2231
|
+
inputSchema: JSON.stringify(t.inputSchema)
|
|
2232
|
+
}))) || [];
|
|
2233
|
+
}
|
|
2234
|
+
function decodeOriginalTools(originalTools) {
|
|
2235
|
+
if (!originalTools) {
|
|
2236
|
+
return [];
|
|
2237
|
+
}
|
|
2238
|
+
return originalTools.map(
|
|
2239
|
+
(t) => ({
|
|
2240
|
+
type: "function",
|
|
2241
|
+
name: t.name,
|
|
2242
|
+
inputSchema: JSON.parse(t.inputSchema)
|
|
2243
|
+
})
|
|
2244
|
+
);
|
|
2245
|
+
}
|
|
2246
|
+
function extractToolNamesFromOriginalTools(originalTools) {
|
|
2247
|
+
return (originalTools == null ? void 0 : originalTools.map((t) => t.name)) || [];
|
|
2248
|
+
}
|
|
2249
|
+
function isToolChoiceActive(params) {
|
|
2250
|
+
var _a, _b, _c;
|
|
2251
|
+
const toolChoice = (_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.toolChoice;
|
|
2252
|
+
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"));
|
|
1698
2253
|
}
|
|
1699
2254
|
|
|
1700
2255
|
// src/generate-handler.ts
|
|
1701
|
-
import { generateId as generateId4 } from "@ai-sdk/provider-utils";
|
|
1702
|
-
import { coerceBySchema } from "@ai-sdk-tool/rxml";
|
|
1703
2256
|
function parseToolChoiceJson(text, providerOptions) {
|
|
1704
2257
|
var _a;
|
|
1705
2258
|
try {
|
|
@@ -1743,7 +2296,7 @@ async function handleToolChoice(doGenerate, params) {
|
|
|
1743
2296
|
}
|
|
1744
2297
|
const toolCall = {
|
|
1745
2298
|
type: "tool-call",
|
|
1746
|
-
toolCallId:
|
|
2299
|
+
toolCallId: generateId3(),
|
|
1747
2300
|
toolName: parsed.name || "unknown",
|
|
1748
2301
|
input: JSON.stringify(parsed.arguments || {})
|
|
1749
2302
|
};
|
|
@@ -1869,8 +2422,13 @@ function fixToolCallWithSchema(part, tools) {
|
|
|
1869
2422
|
};
|
|
1870
2423
|
}
|
|
1871
2424
|
|
|
2425
|
+
// src/protocols/tool-call-protocol.ts
|
|
2426
|
+
function isProtocolFactory(protocol) {
|
|
2427
|
+
return typeof protocol === "function";
|
|
2428
|
+
}
|
|
2429
|
+
|
|
1872
2430
|
// src/stream-handler.ts
|
|
1873
|
-
import { generateId as
|
|
2431
|
+
import { generateId as generateId4 } from "@ai-sdk/provider-utils";
|
|
1874
2432
|
function extractToolCallSegments(protocol, fullRawText, tools) {
|
|
1875
2433
|
const segments = protocol.extractToolCallSegments ? protocol.extractToolCallSegments({
|
|
1876
2434
|
text: fullRawText,
|
|
@@ -1907,7 +2465,7 @@ function handleDebugSummary(parsedToolCalls, origin, params) {
|
|
|
1907
2465
|
}
|
|
1908
2466
|
function createDebugSummaryTransform({
|
|
1909
2467
|
protocol,
|
|
1910
|
-
|
|
2468
|
+
getFullRawText,
|
|
1911
2469
|
tools,
|
|
1912
2470
|
params
|
|
1913
2471
|
}) {
|
|
@@ -1920,11 +2478,9 @@ function createDebugSummaryTransform({
|
|
|
1920
2478
|
}
|
|
1921
2479
|
if (part.type === "finish") {
|
|
1922
2480
|
try {
|
|
1923
|
-
const
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
tools
|
|
1927
|
-
);
|
|
2481
|
+
const raw = getFullRawText();
|
|
2482
|
+
logRawChunk(raw);
|
|
2483
|
+
const origin = extractToolCallSegments(protocol, raw, tools);
|
|
1928
2484
|
handleDebugSummary(parsedToolCalls, origin, params);
|
|
1929
2485
|
} catch (e) {
|
|
1930
2486
|
}
|
|
@@ -2022,7 +2578,7 @@ async function wrapStream({
|
|
|
2022
2578
|
const withSummary = parsed.pipeThrough(
|
|
2023
2579
|
createDebugSummaryTransform({
|
|
2024
2580
|
protocol,
|
|
2025
|
-
fullRawText,
|
|
2581
|
+
getFullRawText: () => fullRawText,
|
|
2026
2582
|
tools,
|
|
2027
2583
|
params
|
|
2028
2584
|
})
|
|
@@ -2056,19 +2612,26 @@ async function toolChoiceStream({
|
|
|
2056
2612
|
}
|
|
2057
2613
|
const toolCallChunk = {
|
|
2058
2614
|
type: "tool-call",
|
|
2059
|
-
toolCallId:
|
|
2615
|
+
toolCallId: generateId4(),
|
|
2060
2616
|
toolName: toolJson.name || "unknown",
|
|
2061
2617
|
input: JSON.stringify(toolJson.arguments || {})
|
|
2062
2618
|
};
|
|
2063
2619
|
const finishChunk = {
|
|
2064
2620
|
type: "finish",
|
|
2065
|
-
usage: (result == null ? void 0 : result.usage) ||
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2621
|
+
usage: (result == null ? void 0 : result.usage) || {
|
|
2622
|
+
inputTokens: {
|
|
2623
|
+
total: 0,
|
|
2624
|
+
noCache: void 0,
|
|
2625
|
+
cacheRead: void 0,
|
|
2626
|
+
cacheWrite: void 0
|
|
2627
|
+
},
|
|
2628
|
+
outputTokens: {
|
|
2629
|
+
total: 0,
|
|
2630
|
+
text: void 0,
|
|
2631
|
+
reasoning: void 0
|
|
2632
|
+
}
|
|
2070
2633
|
},
|
|
2071
|
-
finishReason: "tool-calls"
|
|
2634
|
+
finishReason: { unified: "tool-calls", raw: void 0 }
|
|
2072
2635
|
};
|
|
2073
2636
|
const stream = new ReadableStream({
|
|
2074
2637
|
start(controller) {
|
|
@@ -2102,26 +2665,106 @@ async function toolChoiceStream({
|
|
|
2102
2665
|
};
|
|
2103
2666
|
}
|
|
2104
2667
|
|
|
2668
|
+
// src/utils/dynamic-tool-schema.ts
|
|
2669
|
+
function createDynamicIfThenElseSchema(tools) {
|
|
2670
|
+
let currentSchema = {};
|
|
2671
|
+
const toolNames = [];
|
|
2672
|
+
for (let i = tools.length - 1; i >= 0; i -= 1) {
|
|
2673
|
+
const tool = tools[i];
|
|
2674
|
+
if (tool.type === "provider") {
|
|
2675
|
+
throw new Error(
|
|
2676
|
+
"Provider tools are not supported by this middleware. Please use function tools."
|
|
2677
|
+
);
|
|
2678
|
+
}
|
|
2679
|
+
toolNames.unshift(tool.name);
|
|
2680
|
+
const toolCondition = {
|
|
2681
|
+
if: {
|
|
2682
|
+
properties: {
|
|
2683
|
+
name: {
|
|
2684
|
+
const: tool.name
|
|
2685
|
+
}
|
|
2686
|
+
},
|
|
2687
|
+
required: ["name"]
|
|
2688
|
+
},
|
|
2689
|
+
// biome-ignore lint/suspicious/noThenProperty: JSON Schema uses 'then' as a keyword
|
|
2690
|
+
then: {
|
|
2691
|
+
properties: {
|
|
2692
|
+
name: {
|
|
2693
|
+
const: tool.name
|
|
2694
|
+
},
|
|
2695
|
+
arguments: tool.inputSchema
|
|
2696
|
+
},
|
|
2697
|
+
required: ["name", "arguments"]
|
|
2698
|
+
}
|
|
2699
|
+
};
|
|
2700
|
+
if (Object.keys(currentSchema).length > 0) {
|
|
2701
|
+
toolCondition.else = currentSchema;
|
|
2702
|
+
}
|
|
2703
|
+
currentSchema = toolCondition;
|
|
2704
|
+
}
|
|
2705
|
+
return {
|
|
2706
|
+
type: "object",
|
|
2707
|
+
// Explicitly specify type as "object"
|
|
2708
|
+
properties: {
|
|
2709
|
+
name: {
|
|
2710
|
+
type: "string",
|
|
2711
|
+
description: "Name of the tool to call",
|
|
2712
|
+
enum: toolNames
|
|
2713
|
+
},
|
|
2714
|
+
arguments: {
|
|
2715
|
+
type: "object",
|
|
2716
|
+
// By default, arguments is also specified as object type
|
|
2717
|
+
description: "Argument object to be passed to the tool"
|
|
2718
|
+
}
|
|
2719
|
+
},
|
|
2720
|
+
required: ["name", "arguments"],
|
|
2721
|
+
...currentSchema
|
|
2722
|
+
};
|
|
2723
|
+
}
|
|
2724
|
+
|
|
2105
2725
|
// src/transform-handler.ts
|
|
2106
|
-
function buildFinalPrompt(systemPrompt, processedPrompt) {
|
|
2107
|
-
|
|
2108
|
-
if (
|
|
2726
|
+
function buildFinalPrompt(systemPrompt, processedPrompt, placement) {
|
|
2727
|
+
const systemIndex = processedPrompt.findIndex((m) => m.role === "system");
|
|
2728
|
+
if (systemIndex !== -1) {
|
|
2729
|
+
const existing = processedPrompt[systemIndex].content;
|
|
2730
|
+
let existingText = "";
|
|
2731
|
+
if (typeof existing === "string") {
|
|
2732
|
+
existingText = existing;
|
|
2733
|
+
} else if (Array.isArray(existing)) {
|
|
2734
|
+
existingText = existing.map((p) => {
|
|
2735
|
+
var _a;
|
|
2736
|
+
return (p == null ? void 0 : p.type) === "text" ? (_a = p.text) != null ? _a : "" : "";
|
|
2737
|
+
}).filter(Boolean).join("\n");
|
|
2738
|
+
} else {
|
|
2739
|
+
existingText = String(existing != null ? existing : "");
|
|
2740
|
+
}
|
|
2741
|
+
const mergedContent = placement === "first" ? `${systemPrompt}
|
|
2742
|
+
|
|
2743
|
+
${existingText}` : `${existingText}
|
|
2744
|
+
|
|
2745
|
+
${systemPrompt}`;
|
|
2746
|
+
return processedPrompt.map(
|
|
2747
|
+
(m, idx) => idx === systemIndex ? {
|
|
2748
|
+
...m,
|
|
2749
|
+
content: mergedContent
|
|
2750
|
+
} : m
|
|
2751
|
+
);
|
|
2752
|
+
}
|
|
2753
|
+
if (placement === "first") {
|
|
2109
2754
|
return [
|
|
2110
2755
|
{
|
|
2111
2756
|
role: "system",
|
|
2112
|
-
content:
|
|
2113
|
-
|
|
2114
|
-
${processedPrompt[0].content}`
|
|
2757
|
+
content: systemPrompt
|
|
2115
2758
|
},
|
|
2116
|
-
...processedPrompt
|
|
2759
|
+
...processedPrompt
|
|
2117
2760
|
];
|
|
2118
2761
|
}
|
|
2119
2762
|
return [
|
|
2763
|
+
...processedPrompt,
|
|
2120
2764
|
{
|
|
2121
2765
|
role: "system",
|
|
2122
2766
|
content: systemPrompt
|
|
2123
|
-
}
|
|
2124
|
-
...processedPrompt
|
|
2767
|
+
}
|
|
2125
2768
|
];
|
|
2126
2769
|
}
|
|
2127
2770
|
function buildBaseReturnParams(params, finalPrompt, functionTools) {
|
|
@@ -2221,7 +2864,8 @@ function handleToolChoiceRequired(params, baseReturnParams, functionTools) {
|
|
|
2221
2864
|
function transformParams({
|
|
2222
2865
|
params,
|
|
2223
2866
|
protocol,
|
|
2224
|
-
toolSystemPromptTemplate
|
|
2867
|
+
toolSystemPromptTemplate,
|
|
2868
|
+
placement = "first"
|
|
2225
2869
|
}) {
|
|
2226
2870
|
var _a, _b, _c, _d, _e;
|
|
2227
2871
|
const resolvedProtocol = isProtocolFactory(protocol) ? protocol() : protocol;
|
|
@@ -2237,7 +2881,11 @@ function transformParams({
|
|
|
2237
2881
|
resolvedProtocol,
|
|
2238
2882
|
extractOnErrorOption(params.providerOptions)
|
|
2239
2883
|
);
|
|
2240
|
-
const finalPrompt = buildFinalPrompt(
|
|
2884
|
+
const finalPrompt = buildFinalPrompt(
|
|
2885
|
+
systemPrompt,
|
|
2886
|
+
processedPrompt,
|
|
2887
|
+
placement
|
|
2888
|
+
);
|
|
2241
2889
|
const baseReturnParams = buildBaseReturnParams(
|
|
2242
2890
|
params,
|
|
2243
2891
|
finalPrompt,
|
|
@@ -2314,7 +2962,10 @@ function processMessage(message, resolvedProtocol, providerOptions) {
|
|
|
2314
2962
|
};
|
|
2315
2963
|
}
|
|
2316
2964
|
if (message.role === "tool") {
|
|
2317
|
-
|
|
2965
|
+
const toolResultParts = message.content.filter(
|
|
2966
|
+
(part) => part.type === "tool-result"
|
|
2967
|
+
);
|
|
2968
|
+
return processToolMessage(toolResultParts, resolvedProtocol);
|
|
2318
2969
|
}
|
|
2319
2970
|
return message;
|
|
2320
2971
|
}
|
|
@@ -2389,7 +3040,8 @@ function convertToolPrompt(prompt, resolvedProtocol, providerOptions) {
|
|
|
2389
3040
|
// src/tool-call-middleware.ts
|
|
2390
3041
|
function createToolMiddleware({
|
|
2391
3042
|
protocol,
|
|
2392
|
-
toolSystemPromptTemplate
|
|
3043
|
+
toolSystemPromptTemplate,
|
|
3044
|
+
placement = "last"
|
|
2393
3045
|
}) {
|
|
2394
3046
|
const resolvedProtocol = isProtocolFactory(protocol) ? protocol() : protocol;
|
|
2395
3047
|
return {
|
|
@@ -2416,6 +3068,7 @@ function createToolMiddleware({
|
|
|
2416
3068
|
transformParams: async ({ params }) => transformParams({
|
|
2417
3069
|
protocol: resolvedProtocol,
|
|
2418
3070
|
toolSystemPromptTemplate,
|
|
3071
|
+
placement,
|
|
2419
3072
|
params
|
|
2420
3073
|
})
|
|
2421
3074
|
};
|
|
@@ -2461,6 +3114,7 @@ For each function call return a json object with function name and arguments wit
|
|
|
2461
3114
|
});
|
|
2462
3115
|
var morphXmlToolMiddleware = createToolMiddleware({
|
|
2463
3116
|
protocol: morphXmlProtocol,
|
|
3117
|
+
placement: "last",
|
|
2464
3118
|
toolSystemPromptTemplate(tools) {
|
|
2465
3119
|
return `You are a function calling AI model.
|
|
2466
3120
|
|
|
@@ -2485,30 +3139,30 @@ Available functions are listed inside <tools></tools>.
|
|
|
2485
3139
|
|
|
2486
3140
|
export {
|
|
2487
3141
|
getDebugLevel,
|
|
3142
|
+
logParseFailure,
|
|
2488
3143
|
logRawChunk,
|
|
2489
3144
|
logParsedChunk,
|
|
2490
3145
|
logParsedSummary,
|
|
2491
|
-
createDynamicIfThenElseSchema,
|
|
2492
3146
|
getPotentialStartIndex,
|
|
2493
|
-
extractOnErrorOption,
|
|
2494
|
-
originalToolsSchema,
|
|
2495
|
-
encodeOriginalTools,
|
|
2496
|
-
decodeOriginalTools,
|
|
2497
|
-
extractToolNamesFromOriginalTools,
|
|
2498
|
-
isToolChoiceActive,
|
|
2499
3147
|
escapeRegExp,
|
|
2500
3148
|
transform,
|
|
2501
3149
|
parse,
|
|
2502
3150
|
stringify,
|
|
2503
|
-
|
|
3151
|
+
jsonMixProtocol,
|
|
2504
3152
|
isToolCallContent,
|
|
2505
3153
|
isToolResultPart,
|
|
2506
3154
|
hasInputProperty,
|
|
2507
|
-
jsonMixProtocol,
|
|
2508
3155
|
morphXmlProtocol,
|
|
3156
|
+
extractOnErrorOption,
|
|
3157
|
+
originalToolsSchema,
|
|
3158
|
+
encodeOriginalTools,
|
|
3159
|
+
decodeOriginalTools,
|
|
3160
|
+
extractToolNamesFromOriginalTools,
|
|
3161
|
+
isToolChoiceActive,
|
|
3162
|
+
createDynamicIfThenElseSchema,
|
|
2509
3163
|
createToolMiddleware,
|
|
2510
3164
|
gemmaToolMiddleware,
|
|
2511
3165
|
hermesToolMiddleware,
|
|
2512
3166
|
morphXmlToolMiddleware
|
|
2513
3167
|
};
|
|
2514
|
-
//# sourceMappingURL=chunk-
|
|
3168
|
+
//# sourceMappingURL=chunk-L4X363EL.js.map
|