@ai-sdk-tool/parser 3.3.2 → 3.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-OUGMLYAW.js → chunk-2KK5BDZF.js} +373 -8
- package/dist/chunk-2KK5BDZF.js.map +1 -0
- package/dist/{chunk-ZDBNJWLY.js → chunk-CXWS24JX.js} +2 -2
- package/dist/{chunk-5WKXBBCU.js → chunk-NAQSTPDQ.js} +696 -97
- package/dist/chunk-NAQSTPDQ.js.map +1 -0
- package/dist/community.cjs +1075 -113
- package/dist/community.cjs.map +1 -1
- package/dist/community.js +3 -3
- package/dist/index.cjs +1075 -113
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -8
- package/dist/index.d.ts +14 -8
- package/dist/index.js +3 -3
- package/dist/rxml.cjs +377 -12
- package/dist/rxml.cjs.map +1 -1
- package/dist/rxml.js +2 -2
- package/dist/schema-coerce.cjs +372 -7
- package/dist/schema-coerce.cjs.map +1 -1
- package/dist/schema-coerce.js +1 -1
- package/package.json +8 -8
- package/dist/chunk-5WKXBBCU.js.map +0 -1
- package/dist/chunk-OUGMLYAW.js.map +0 -1
- /package/dist/{chunk-ZDBNJWLY.js.map → chunk-CXWS24JX.js.map} +0 -0
|
@@ -2,13 +2,15 @@ import {
|
|
|
2
2
|
escapeRegExp,
|
|
3
3
|
parse as parse2,
|
|
4
4
|
stringify
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-CXWS24JX.js";
|
|
6
6
|
import {
|
|
7
7
|
parse
|
|
8
8
|
} from "./chunk-IX4FJELL.js";
|
|
9
9
|
import {
|
|
10
|
-
coerceBySchema
|
|
11
|
-
|
|
10
|
+
coerceBySchema,
|
|
11
|
+
getSchemaType,
|
|
12
|
+
unwrapJsonSchema
|
|
13
|
+
} from "./chunk-2KK5BDZF.js";
|
|
12
14
|
|
|
13
15
|
// src/core/utils/debug.ts
|
|
14
16
|
var LINE_SPLIT_REGEX = /\r?\n/;
|
|
@@ -518,6 +520,30 @@ function isTCMProtocolFactory(protocol) {
|
|
|
518
520
|
var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
|
|
519
521
|
var WHITESPACE_REGEX = /\s/;
|
|
520
522
|
|
|
523
|
+
// src/core/utils/xml-root-repair.ts
|
|
524
|
+
var XML_SELF_CLOSING_ROOT_WITH_BODY_REGEX = /^<([A-Za-z_][A-Za-z0-9_-]*)\s*\r?\n([\s\S]+?)\r?\n\s*\/>\s*$/;
|
|
525
|
+
function tryRepairXmlSelfClosingRootWithBody(rawText, toolNames) {
|
|
526
|
+
const trimmed = rawText.trim();
|
|
527
|
+
if (trimmed.length === 0) {
|
|
528
|
+
return null;
|
|
529
|
+
}
|
|
530
|
+
const match = trimmed.match(XML_SELF_CLOSING_ROOT_WITH_BODY_REGEX);
|
|
531
|
+
if (!match) {
|
|
532
|
+
return null;
|
|
533
|
+
}
|
|
534
|
+
const rootTag = match[1];
|
|
535
|
+
if (!toolNames.includes(rootTag)) {
|
|
536
|
+
return null;
|
|
537
|
+
}
|
|
538
|
+
const body = match[2].trimEnd();
|
|
539
|
+
if (body.trim().length === 0 || body.includes(`</${rootTag}>`)) {
|
|
540
|
+
return null;
|
|
541
|
+
}
|
|
542
|
+
return `<${rootTag}>
|
|
543
|
+
${body}
|
|
544
|
+
</${rootTag}>`;
|
|
545
|
+
}
|
|
546
|
+
|
|
521
547
|
// src/core/protocols/xml-protocol.ts
|
|
522
548
|
function getToolSchema(tools, toolName) {
|
|
523
549
|
var _a;
|
|
@@ -799,6 +825,102 @@ function findToolCalls(text, toolNames) {
|
|
|
799
825
|
}
|
|
800
826
|
return toolCalls.sort((a, b) => a.startIndex - b.startIndex);
|
|
801
827
|
}
|
|
828
|
+
function handleSpecialToken(depth) {
|
|
829
|
+
return { depth, lastCompleteEnd: -1, shouldBreak: false };
|
|
830
|
+
}
|
|
831
|
+
function handleOpenToken(token, depth, lastCompleteEnd) {
|
|
832
|
+
if (token.selfClosing) {
|
|
833
|
+
return {
|
|
834
|
+
depth,
|
|
835
|
+
lastCompleteEnd: depth === 0 ? token.nextPos : lastCompleteEnd,
|
|
836
|
+
shouldBreak: false
|
|
837
|
+
};
|
|
838
|
+
}
|
|
839
|
+
return { depth: depth + 1, lastCompleteEnd, shouldBreak: false };
|
|
840
|
+
}
|
|
841
|
+
function handleCloseToken(token, depth) {
|
|
842
|
+
if (depth <= 0) {
|
|
843
|
+
return { depth, lastCompleteEnd: -1, shouldBreak: true };
|
|
844
|
+
}
|
|
845
|
+
const newDepth = depth - 1;
|
|
846
|
+
return {
|
|
847
|
+
depth: newDepth,
|
|
848
|
+
lastCompleteEnd: newDepth === 0 ? token.nextPos : -1,
|
|
849
|
+
shouldBreak: false
|
|
850
|
+
};
|
|
851
|
+
}
|
|
852
|
+
function findLinePrefixedXmlBodyEnd(text, bodyStartIndex) {
|
|
853
|
+
let cursor = bodyStartIndex;
|
|
854
|
+
let depth = 0;
|
|
855
|
+
let lastCompleteEnd = -1;
|
|
856
|
+
while (cursor < text.length) {
|
|
857
|
+
if (depth === 0) {
|
|
858
|
+
cursor = consumeWhitespace(text, cursor);
|
|
859
|
+
if (cursor >= text.length || text.charAt(cursor) !== "<") {
|
|
860
|
+
break;
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
const token = nextTagToken(text, cursor);
|
|
864
|
+
if (token.kind === "eof") {
|
|
865
|
+
break;
|
|
866
|
+
}
|
|
867
|
+
let result;
|
|
868
|
+
if (token.kind === "special") {
|
|
869
|
+
result = handleSpecialToken(depth);
|
|
870
|
+
} else if (token.kind === "open") {
|
|
871
|
+
result = handleOpenToken(token, depth, lastCompleteEnd);
|
|
872
|
+
} else {
|
|
873
|
+
result = handleCloseToken(token, depth);
|
|
874
|
+
}
|
|
875
|
+
depth = result.depth;
|
|
876
|
+
if (result.lastCompleteEnd !== -1) {
|
|
877
|
+
lastCompleteEnd = result.lastCompleteEnd;
|
|
878
|
+
}
|
|
879
|
+
if (result.shouldBreak) {
|
|
880
|
+
break;
|
|
881
|
+
}
|
|
882
|
+
cursor = token.nextPos;
|
|
883
|
+
}
|
|
884
|
+
return lastCompleteEnd;
|
|
885
|
+
}
|
|
886
|
+
function findLinePrefixedToolCall(text, toolNames) {
|
|
887
|
+
var _a;
|
|
888
|
+
let best = null;
|
|
889
|
+
for (const toolName of toolNames) {
|
|
890
|
+
const linePattern = new RegExp(
|
|
891
|
+
`(^|\\n)[\\t ]*${escapeRegExp(toolName)}[\\t ]*:?[\\t ]*(?:\\r?\\n|$)`,
|
|
892
|
+
"g"
|
|
893
|
+
);
|
|
894
|
+
let match = linePattern.exec(text);
|
|
895
|
+
while (match !== null) {
|
|
896
|
+
const prefix = (_a = match[1]) != null ? _a : "";
|
|
897
|
+
const startIndex = match.index + prefix.length;
|
|
898
|
+
const contentStart = consumeWhitespace(text, linePattern.lastIndex);
|
|
899
|
+
if (contentStart >= text.length || text.charAt(contentStart) !== "<") {
|
|
900
|
+
match = linePattern.exec(text);
|
|
901
|
+
continue;
|
|
902
|
+
}
|
|
903
|
+
const contentEnd = findLinePrefixedXmlBodyEnd(text, contentStart);
|
|
904
|
+
if (contentEnd === -1 || contentEnd <= contentStart) {
|
|
905
|
+
match = linePattern.exec(text);
|
|
906
|
+
continue;
|
|
907
|
+
}
|
|
908
|
+
const content = text.slice(contentStart, contentEnd);
|
|
909
|
+
const candidate = {
|
|
910
|
+
toolName,
|
|
911
|
+
startIndex,
|
|
912
|
+
endIndex: contentEnd,
|
|
913
|
+
content,
|
|
914
|
+
segment: text.slice(startIndex, contentEnd)
|
|
915
|
+
};
|
|
916
|
+
if (best === null || candidate.startIndex < best.startIndex) {
|
|
917
|
+
best = candidate;
|
|
918
|
+
}
|
|
919
|
+
break;
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
return best;
|
|
923
|
+
}
|
|
802
924
|
function findEarliestToolTag(buffer, toolNames) {
|
|
803
925
|
var _a, _b;
|
|
804
926
|
let bestIndex = -1;
|
|
@@ -1088,6 +1210,27 @@ function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, se
|
|
|
1088
1210
|
}
|
|
1089
1211
|
};
|
|
1090
1212
|
}
|
|
1213
|
+
function findToolCallsWithFallbacks(text, toolNames) {
|
|
1214
|
+
let parseText = text;
|
|
1215
|
+
let toolCalls = findToolCalls(parseText, toolNames);
|
|
1216
|
+
if (toolCalls.length === 0) {
|
|
1217
|
+
const fallbackToolCall = findLinePrefixedToolCall(parseText, toolNames);
|
|
1218
|
+
if (fallbackToolCall !== null) {
|
|
1219
|
+
toolCalls.push(fallbackToolCall);
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
if (toolCalls.length === 0) {
|
|
1223
|
+
const repaired = tryRepairXmlSelfClosingRootWithBody(parseText, toolNames);
|
|
1224
|
+
if (repaired) {
|
|
1225
|
+
const repairedCalls = findToolCalls(repaired, toolNames);
|
|
1226
|
+
if (repairedCalls.length > 0) {
|
|
1227
|
+
parseText = repaired;
|
|
1228
|
+
toolCalls = repairedCalls;
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
return { parseText, toolCalls };
|
|
1233
|
+
}
|
|
1091
1234
|
var xmlProtocol = (protocolOptions) => {
|
|
1092
1235
|
var _a;
|
|
1093
1236
|
const parseOptions = {
|
|
@@ -1121,28 +1264,31 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
1121
1264
|
}
|
|
1122
1265
|
const processedElements = [];
|
|
1123
1266
|
let currentIndex = 0;
|
|
1124
|
-
const toolCalls =
|
|
1267
|
+
const { parseText, toolCalls } = findToolCallsWithFallbacks(
|
|
1268
|
+
text,
|
|
1269
|
+
toolNames
|
|
1270
|
+
);
|
|
1125
1271
|
for (const tc of toolCalls) {
|
|
1126
1272
|
if (tc.startIndex > currentIndex) {
|
|
1127
1273
|
processedElements.push({
|
|
1128
1274
|
type: "text",
|
|
1129
|
-
text:
|
|
1275
|
+
text: parseText.substring(currentIndex, tc.startIndex)
|
|
1130
1276
|
});
|
|
1131
1277
|
}
|
|
1132
1278
|
processToolCall({
|
|
1133
1279
|
toolCall: tc,
|
|
1134
1280
|
tools,
|
|
1135
1281
|
options,
|
|
1136
|
-
text,
|
|
1282
|
+
text: parseText,
|
|
1137
1283
|
processedElements,
|
|
1138
1284
|
parseOptions
|
|
1139
1285
|
});
|
|
1140
1286
|
currentIndex = tc.endIndex;
|
|
1141
1287
|
}
|
|
1142
|
-
if (currentIndex <
|
|
1288
|
+
if (currentIndex < parseText.length) {
|
|
1143
1289
|
processedElements.push({
|
|
1144
1290
|
type: "text",
|
|
1145
|
-
text:
|
|
1291
|
+
text: parseText.substring(currentIndex)
|
|
1146
1292
|
});
|
|
1147
1293
|
}
|
|
1148
1294
|
return processedElements;
|
|
@@ -1181,6 +1327,20 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
1181
1327
|
return new TransformStream({
|
|
1182
1328
|
transform(chunk, controller) {
|
|
1183
1329
|
var _a2;
|
|
1330
|
+
if (chunk.type === "finish") {
|
|
1331
|
+
if (currentToolCall) {
|
|
1332
|
+
const unfinishedContent = `<${currentToolCall.name}>${currentToolCall.content}${buffer}`;
|
|
1333
|
+
flushText(controller, unfinishedContent);
|
|
1334
|
+
buffer = "";
|
|
1335
|
+
currentToolCall = null;
|
|
1336
|
+
} else if (buffer) {
|
|
1337
|
+
flushText(controller, buffer);
|
|
1338
|
+
buffer = "";
|
|
1339
|
+
}
|
|
1340
|
+
flushText(controller);
|
|
1341
|
+
controller.enqueue(chunk);
|
|
1342
|
+
return;
|
|
1343
|
+
}
|
|
1184
1344
|
if (chunk.type !== "text-delta") {
|
|
1185
1345
|
if (buffer) {
|
|
1186
1346
|
flushText(controller, buffer);
|
|
@@ -1507,18 +1667,32 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
1507
1667
|
}
|
|
1508
1668
|
const processedElements = [];
|
|
1509
1669
|
let currentIndex = 0;
|
|
1510
|
-
|
|
1670
|
+
let parseText = text;
|
|
1671
|
+
let toolCalls = findToolCalls2(parseText, toolNames);
|
|
1672
|
+
if (toolCalls.length === 0) {
|
|
1673
|
+
const repaired = tryRepairXmlSelfClosingRootWithBody(
|
|
1674
|
+
parseText,
|
|
1675
|
+
toolNames
|
|
1676
|
+
);
|
|
1677
|
+
if (repaired) {
|
|
1678
|
+
const repairedCalls = findToolCalls2(repaired, toolNames);
|
|
1679
|
+
if (repairedCalls.length > 0) {
|
|
1680
|
+
parseText = repaired;
|
|
1681
|
+
toolCalls = repairedCalls;
|
|
1682
|
+
}
|
|
1683
|
+
}
|
|
1684
|
+
}
|
|
1511
1685
|
for (const tc of toolCalls) {
|
|
1512
1686
|
currentIndex = processToolCallMatch(
|
|
1513
|
-
|
|
1687
|
+
parseText,
|
|
1514
1688
|
tc,
|
|
1515
1689
|
currentIndex,
|
|
1516
1690
|
processedElements,
|
|
1517
1691
|
options
|
|
1518
1692
|
);
|
|
1519
1693
|
}
|
|
1520
|
-
if (currentIndex <
|
|
1521
|
-
addTextSegment(
|
|
1694
|
+
if (currentIndex < parseText.length) {
|
|
1695
|
+
addTextSegment(parseText.substring(currentIndex), processedElements);
|
|
1522
1696
|
}
|
|
1523
1697
|
return processedElements;
|
|
1524
1698
|
},
|
|
@@ -1614,6 +1788,20 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
1614
1788
|
return new TransformStream({
|
|
1615
1789
|
transform(chunk, controller) {
|
|
1616
1790
|
var _a;
|
|
1791
|
+
if (chunk.type === "finish") {
|
|
1792
|
+
if (currentToolCall) {
|
|
1793
|
+
const unfinishedContent = `<${currentToolCall.name}>${buffer}`;
|
|
1794
|
+
flushText(controller, unfinishedContent);
|
|
1795
|
+
buffer = "";
|
|
1796
|
+
currentToolCall = null;
|
|
1797
|
+
} else if (buffer) {
|
|
1798
|
+
flushText(controller, buffer);
|
|
1799
|
+
buffer = "";
|
|
1800
|
+
}
|
|
1801
|
+
flushText(controller);
|
|
1802
|
+
controller.enqueue(chunk);
|
|
1803
|
+
return;
|
|
1804
|
+
}
|
|
1617
1805
|
if (chunk.type !== "text-delta") {
|
|
1618
1806
|
if (buffer) {
|
|
1619
1807
|
flushText(controller, buffer);
|
|
@@ -1737,17 +1925,56 @@ function encodeOriginalTools(tools) {
|
|
|
1737
1925
|
inputSchema: JSON.stringify(t.inputSchema)
|
|
1738
1926
|
}))) || [];
|
|
1739
1927
|
}
|
|
1740
|
-
function decodeOriginalTools(originalTools) {
|
|
1928
|
+
function decodeOriginalTools(originalTools, options) {
|
|
1929
|
+
var _a, _b, _c;
|
|
1741
1930
|
if (!originalTools) {
|
|
1742
1931
|
return [];
|
|
1743
1932
|
}
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1933
|
+
const decodedTools = [];
|
|
1934
|
+
for (const [index, tool] of originalTools.entries()) {
|
|
1935
|
+
if (!tool || typeof tool.name !== "string") {
|
|
1936
|
+
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, "Invalid originalTools entry: missing tool name", {
|
|
1937
|
+
index,
|
|
1938
|
+
tool
|
|
1939
|
+
});
|
|
1940
|
+
continue;
|
|
1941
|
+
}
|
|
1942
|
+
if (typeof tool.inputSchema !== "string") {
|
|
1943
|
+
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
1944
|
+
options,
|
|
1945
|
+
"Invalid originalTools entry: inputSchema must be a string",
|
|
1946
|
+
{
|
|
1947
|
+
index,
|
|
1948
|
+
toolName: tool.name
|
|
1949
|
+
}
|
|
1950
|
+
);
|
|
1951
|
+
continue;
|
|
1952
|
+
}
|
|
1953
|
+
try {
|
|
1954
|
+
decodedTools.push({
|
|
1955
|
+
type: "function",
|
|
1956
|
+
name: tool.name,
|
|
1957
|
+
inputSchema: JSON.parse(tool.inputSchema)
|
|
1958
|
+
});
|
|
1959
|
+
} catch (error) {
|
|
1960
|
+
(_c = options == null ? void 0 : options.onError) == null ? void 0 : _c.call(
|
|
1961
|
+
options,
|
|
1962
|
+
"Failed to decode originalTools input schema, using permissive fallback schema",
|
|
1963
|
+
{
|
|
1964
|
+
index,
|
|
1965
|
+
toolName: tool.name,
|
|
1966
|
+
inputSchema: tool.inputSchema,
|
|
1967
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1968
|
+
}
|
|
1969
|
+
);
|
|
1970
|
+
decodedTools.push({
|
|
1971
|
+
type: "function",
|
|
1972
|
+
name: tool.name,
|
|
1973
|
+
inputSchema: { type: "object" }
|
|
1974
|
+
});
|
|
1975
|
+
}
|
|
1976
|
+
}
|
|
1977
|
+
return decodedTools;
|
|
1751
1978
|
}
|
|
1752
1979
|
function extractToolNamesFromOriginalTools(originalTools) {
|
|
1753
1980
|
return (originalTools == null ? void 0 : originalTools.map((t) => t.name)) || [];
|
|
@@ -1772,23 +1999,337 @@ function hasInputProperty(obj) {
|
|
|
1772
1999
|
|
|
1773
2000
|
// src/generate-handler.ts
|
|
1774
2001
|
import { generateId as generateId2 } from "@ai-sdk/provider-utils";
|
|
1775
|
-
|
|
2002
|
+
|
|
2003
|
+
// src/core/utils/generated-text-json-recovery.ts
|
|
2004
|
+
function isRecord(value) {
|
|
2005
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2006
|
+
}
|
|
2007
|
+
function safeStringify2(value) {
|
|
2008
|
+
try {
|
|
2009
|
+
return JSON.stringify(value != null ? value : {});
|
|
2010
|
+
} catch (e) {
|
|
2011
|
+
return "{}";
|
|
2012
|
+
}
|
|
2013
|
+
}
|
|
2014
|
+
function parseJsonCandidate(candidateText) {
|
|
2015
|
+
try {
|
|
2016
|
+
return parse(candidateText);
|
|
2017
|
+
} catch (e) {
|
|
2018
|
+
return void 0;
|
|
2019
|
+
}
|
|
2020
|
+
}
|
|
2021
|
+
function extractCodeBlockCandidates(text) {
|
|
2022
|
+
var _a, _b;
|
|
2023
|
+
const codeBlockRegex = /```(?:json|yaml|xml)?\s*([\s\S]*?)```/gi;
|
|
2024
|
+
const candidates = [];
|
|
2025
|
+
let match;
|
|
2026
|
+
while (true) {
|
|
2027
|
+
match = codeBlockRegex.exec(text);
|
|
2028
|
+
if (!match) {
|
|
2029
|
+
break;
|
|
2030
|
+
}
|
|
2031
|
+
const body = (_a = match[1]) == null ? void 0 : _a.trim();
|
|
2032
|
+
if (body) {
|
|
2033
|
+
const startIndex = (_b = match.index) != null ? _b : 0;
|
|
2034
|
+
const endIndex = startIndex + match[0].length;
|
|
2035
|
+
candidates.push({
|
|
2036
|
+
text: body,
|
|
2037
|
+
startIndex,
|
|
2038
|
+
endIndex
|
|
2039
|
+
});
|
|
2040
|
+
}
|
|
2041
|
+
}
|
|
2042
|
+
return candidates;
|
|
2043
|
+
}
|
|
2044
|
+
function scanJsonChar(state, char) {
|
|
2045
|
+
if (state.inString) {
|
|
2046
|
+
if (state.escaping) {
|
|
2047
|
+
return { ...state, escaping: false };
|
|
2048
|
+
}
|
|
2049
|
+
if (char === "\\") {
|
|
2050
|
+
return { ...state, escaping: true };
|
|
2051
|
+
}
|
|
2052
|
+
if (char === '"') {
|
|
2053
|
+
return { ...state, inString: false };
|
|
2054
|
+
}
|
|
2055
|
+
return state;
|
|
2056
|
+
}
|
|
2057
|
+
if (char === '"') {
|
|
2058
|
+
return { ...state, inString: true };
|
|
2059
|
+
}
|
|
2060
|
+
if (char === "{") {
|
|
2061
|
+
return { ...state, depth: state.depth + 1 };
|
|
2062
|
+
}
|
|
2063
|
+
if (char === "}") {
|
|
2064
|
+
return { ...state, depth: Math.max(0, state.depth - 1) };
|
|
2065
|
+
}
|
|
2066
|
+
return state;
|
|
2067
|
+
}
|
|
2068
|
+
function extractBalancedJsonObjects(text) {
|
|
2069
|
+
const maxCandidateLength = 1e4;
|
|
2070
|
+
const candidates = [];
|
|
2071
|
+
let state = { depth: 0, inString: false, escaping: false };
|
|
2072
|
+
let currentStart = null;
|
|
2073
|
+
let ignoreCurrent = false;
|
|
2074
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
2075
|
+
const char = text[index];
|
|
2076
|
+
if (!state.inString && char === "{" && state.depth === 0) {
|
|
2077
|
+
currentStart = index;
|
|
2078
|
+
ignoreCurrent = false;
|
|
2079
|
+
}
|
|
2080
|
+
state = scanJsonChar(state, char);
|
|
2081
|
+
if (currentStart !== null && !ignoreCurrent && index - currentStart + 1 > maxCandidateLength) {
|
|
2082
|
+
ignoreCurrent = true;
|
|
2083
|
+
}
|
|
2084
|
+
if (!state.inString && char === "}" && state.depth === 0) {
|
|
2085
|
+
if (currentStart !== null && !ignoreCurrent) {
|
|
2086
|
+
const endIndex = index + 1;
|
|
2087
|
+
const candidate = text.slice(currentStart, endIndex);
|
|
2088
|
+
if (candidate.length > 1) {
|
|
2089
|
+
candidates.push({
|
|
2090
|
+
text: candidate,
|
|
2091
|
+
startIndex: currentStart,
|
|
2092
|
+
endIndex
|
|
2093
|
+
});
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
currentStart = null;
|
|
2097
|
+
ignoreCurrent = false;
|
|
2098
|
+
}
|
|
2099
|
+
}
|
|
2100
|
+
return candidates;
|
|
2101
|
+
}
|
|
2102
|
+
function extractTaggedToolCallCandidates(rawText) {
|
|
2103
|
+
var _a, _b;
|
|
2104
|
+
const toolCallRegex = /<tool_call>([\s\S]*?)<\/tool_call>/gi;
|
|
2105
|
+
const candidates = [];
|
|
2106
|
+
let match;
|
|
2107
|
+
while (true) {
|
|
2108
|
+
match = toolCallRegex.exec(rawText);
|
|
2109
|
+
if (!match) {
|
|
2110
|
+
break;
|
|
2111
|
+
}
|
|
2112
|
+
const body = (_a = match[1]) == null ? void 0 : _a.trim();
|
|
2113
|
+
if (!body) {
|
|
2114
|
+
continue;
|
|
2115
|
+
}
|
|
2116
|
+
const startIndex = (_b = match.index) != null ? _b : 0;
|
|
2117
|
+
const endIndex = startIndex + match[0].length;
|
|
2118
|
+
candidates.push({
|
|
2119
|
+
text: body,
|
|
2120
|
+
startIndex,
|
|
2121
|
+
endIndex
|
|
2122
|
+
});
|
|
2123
|
+
}
|
|
2124
|
+
return candidates;
|
|
2125
|
+
}
|
|
2126
|
+
function extractJsonLikeCandidates(rawText) {
|
|
2127
|
+
return mergeJsonCandidatesByStart(
|
|
2128
|
+
extractTaggedToolCallCandidates(rawText),
|
|
2129
|
+
extractCodeBlockCandidates(rawText),
|
|
2130
|
+
extractBalancedJsonObjects(rawText)
|
|
2131
|
+
);
|
|
2132
|
+
}
|
|
2133
|
+
function mergeJsonCandidatesByStart(tagged, codeBlocks, balanced) {
|
|
2134
|
+
return [...tagged, ...codeBlocks, ...balanced].sort(
|
|
2135
|
+
(a, b) => a.startIndex !== b.startIndex ? a.startIndex - b.startIndex : b.endIndex - a.endIndex
|
|
2136
|
+
);
|
|
2137
|
+
}
|
|
2138
|
+
function toToolCallPart(candidate) {
|
|
2139
|
+
return {
|
|
2140
|
+
type: "tool-call",
|
|
2141
|
+
toolCallId: generateId(),
|
|
2142
|
+
toolName: candidate.toolName,
|
|
2143
|
+
input: candidate.input
|
|
2144
|
+
};
|
|
2145
|
+
}
|
|
2146
|
+
function toRecoveredParts(text, candidate, toolCallPart) {
|
|
2147
|
+
const out = [];
|
|
2148
|
+
const prefix = text.slice(0, candidate.startIndex);
|
|
2149
|
+
if (prefix.length > 0) {
|
|
2150
|
+
out.push({ type: "text", text: prefix });
|
|
2151
|
+
}
|
|
2152
|
+
out.push(toolCallPart);
|
|
2153
|
+
const suffix = text.slice(candidate.endIndex);
|
|
2154
|
+
if (suffix.length > 0) {
|
|
2155
|
+
out.push({ type: "text", text: suffix });
|
|
2156
|
+
}
|
|
2157
|
+
return out;
|
|
2158
|
+
}
|
|
2159
|
+
function parseAsToolPayload(payload, tools) {
|
|
2160
|
+
if (!isRecord(payload)) {
|
|
2161
|
+
return null;
|
|
2162
|
+
}
|
|
2163
|
+
const toolName = typeof payload.name === "string" && payload.name.trim().length > 0 ? payload.name.trim() : null;
|
|
2164
|
+
if (!toolName) {
|
|
2165
|
+
return null;
|
|
2166
|
+
}
|
|
2167
|
+
if (!tools.some((tool) => tool.name === toolName)) {
|
|
2168
|
+
return null;
|
|
2169
|
+
}
|
|
2170
|
+
const rawArgs = Object.hasOwn(payload, "arguments") ? payload.arguments : {};
|
|
2171
|
+
if (!isRecord(rawArgs)) {
|
|
2172
|
+
return null;
|
|
2173
|
+
}
|
|
2174
|
+
return {
|
|
2175
|
+
toolName,
|
|
2176
|
+
input: safeStringify2(rawArgs)
|
|
2177
|
+
};
|
|
2178
|
+
}
|
|
2179
|
+
function isLikelyArgumentsShapeForTool(args, tool) {
|
|
2180
|
+
const unwrapped = unwrapJsonSchema(tool.inputSchema);
|
|
2181
|
+
if (!isRecord(unwrapped)) {
|
|
2182
|
+
return false;
|
|
2183
|
+
}
|
|
2184
|
+
if (getSchemaType(unwrapped) !== "object") {
|
|
2185
|
+
return false;
|
|
2186
|
+
}
|
|
2187
|
+
const properties = unwrapped.properties;
|
|
2188
|
+
if (!isRecord(properties)) {
|
|
2189
|
+
return false;
|
|
2190
|
+
}
|
|
2191
|
+
const keys = Object.keys(args);
|
|
2192
|
+
if (keys.length === 0) {
|
|
2193
|
+
return false;
|
|
2194
|
+
}
|
|
2195
|
+
const knownKeys = keys.filter((key) => Object.hasOwn(properties, key));
|
|
2196
|
+
if (knownKeys.length === 0) {
|
|
2197
|
+
return false;
|
|
2198
|
+
}
|
|
2199
|
+
if (unwrapped.additionalProperties === false && knownKeys.length !== keys.length) {
|
|
2200
|
+
return false;
|
|
2201
|
+
}
|
|
2202
|
+
return true;
|
|
2203
|
+
}
|
|
2204
|
+
function parseAsArgumentsOnly(payload, tools) {
|
|
2205
|
+
if (tools.length !== 1) {
|
|
2206
|
+
return null;
|
|
2207
|
+
}
|
|
2208
|
+
if (!isRecord(payload)) {
|
|
2209
|
+
return null;
|
|
2210
|
+
}
|
|
2211
|
+
const hasNameEnvelope = Object.hasOwn(payload, "name") && typeof payload.name === "string" && payload.name.length > 0;
|
|
2212
|
+
const hasArgumentsEnvelope = Object.hasOwn(payload, "arguments") && (typeof payload.arguments === "string" || isRecord(payload.arguments));
|
|
2213
|
+
if (hasNameEnvelope || hasArgumentsEnvelope) {
|
|
2214
|
+
return null;
|
|
2215
|
+
}
|
|
2216
|
+
const tool = tools[0];
|
|
2217
|
+
if (!isLikelyArgumentsShapeForTool(payload, tool)) {
|
|
2218
|
+
return null;
|
|
2219
|
+
}
|
|
2220
|
+
return {
|
|
2221
|
+
toolName: tool.name,
|
|
2222
|
+
input: safeStringify2(payload)
|
|
2223
|
+
};
|
|
2224
|
+
}
|
|
2225
|
+
function recoverToolCallFromJsonCandidates(text, tools) {
|
|
2226
|
+
if (tools.length === 0) {
|
|
2227
|
+
return null;
|
|
2228
|
+
}
|
|
2229
|
+
const jsonCandidates = extractJsonLikeCandidates(text);
|
|
2230
|
+
for (const jsonCandidate of jsonCandidates) {
|
|
2231
|
+
const parsed = parseJsonCandidate(jsonCandidate.text);
|
|
2232
|
+
if (parsed === void 0) {
|
|
2233
|
+
continue;
|
|
2234
|
+
}
|
|
2235
|
+
const toolPayload = parseAsToolPayload(parsed, tools);
|
|
2236
|
+
if (toolPayload) {
|
|
2237
|
+
return toRecoveredParts(text, jsonCandidate, toToolCallPart(toolPayload));
|
|
2238
|
+
}
|
|
2239
|
+
const argsPayload = parseAsArgumentsOnly(parsed, tools);
|
|
2240
|
+
if (argsPayload) {
|
|
2241
|
+
return toRecoveredParts(text, jsonCandidate, toToolCallPart(argsPayload));
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
return null;
|
|
2245
|
+
}
|
|
2246
|
+
|
|
2247
|
+
// src/core/utils/tool-call-coercion.ts
|
|
2248
|
+
function coerceToolCallInput(toolName, input, tools) {
|
|
1776
2249
|
var _a;
|
|
2250
|
+
let args = {};
|
|
2251
|
+
if (typeof input === "string") {
|
|
2252
|
+
try {
|
|
2253
|
+
args = JSON.parse(input);
|
|
2254
|
+
} catch (e) {
|
|
2255
|
+
return;
|
|
2256
|
+
}
|
|
2257
|
+
} else if (input && typeof input === "object") {
|
|
2258
|
+
args = input;
|
|
2259
|
+
} else {
|
|
2260
|
+
return;
|
|
2261
|
+
}
|
|
2262
|
+
const schema = (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
|
|
2263
|
+
const coerced = coerceBySchema(args, schema);
|
|
2264
|
+
return JSON.stringify(coerced != null ? coerced : {});
|
|
2265
|
+
}
|
|
2266
|
+
function coerceToolCallPart(part, tools) {
|
|
2267
|
+
const coercedInput = coerceToolCallInput(part.toolName, part.input, tools);
|
|
2268
|
+
if (coercedInput === void 0) {
|
|
2269
|
+
return part;
|
|
2270
|
+
}
|
|
2271
|
+
return {
|
|
2272
|
+
...part,
|
|
2273
|
+
input: coercedInput
|
|
2274
|
+
};
|
|
2275
|
+
}
|
|
2276
|
+
|
|
2277
|
+
// src/core/utils/tool-choice.ts
|
|
2278
|
+
function ensureNonEmptyToolName(name) {
|
|
2279
|
+
if (typeof name !== "string") {
|
|
2280
|
+
return "unknown";
|
|
2281
|
+
}
|
|
2282
|
+
const trimmed = name.trim();
|
|
2283
|
+
return trimmed.length > 0 ? trimmed : "unknown";
|
|
2284
|
+
}
|
|
2285
|
+
function safeStringify3(value) {
|
|
2286
|
+
try {
|
|
2287
|
+
return JSON.stringify(value != null ? value : {});
|
|
2288
|
+
} catch (e) {
|
|
2289
|
+
return "{}";
|
|
2290
|
+
}
|
|
2291
|
+
}
|
|
2292
|
+
function parseToolChoicePayload({
|
|
2293
|
+
text,
|
|
2294
|
+
tools,
|
|
2295
|
+
onError,
|
|
2296
|
+
errorMessage
|
|
2297
|
+
}) {
|
|
2298
|
+
let parsed;
|
|
1777
2299
|
try {
|
|
1778
|
-
|
|
2300
|
+
parsed = JSON.parse(text);
|
|
1779
2301
|
} catch (error) {
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
2302
|
+
onError == null ? void 0 : onError(errorMessage, {
|
|
2303
|
+
text,
|
|
2304
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2305
|
+
});
|
|
2306
|
+
return { toolName: "unknown", input: "{}" };
|
|
2307
|
+
}
|
|
2308
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
2309
|
+
onError == null ? void 0 : onError("toolChoice JSON payload must be an object", {
|
|
2310
|
+
parsedType: typeof parsed,
|
|
2311
|
+
parsed
|
|
2312
|
+
});
|
|
2313
|
+
return { toolName: "unknown", input: "{}" };
|
|
2314
|
+
}
|
|
2315
|
+
const payload = parsed;
|
|
2316
|
+
const toolName = ensureNonEmptyToolName(payload.name);
|
|
2317
|
+
const rawArgs = Object.hasOwn(payload, "arguments") ? payload.arguments : {};
|
|
2318
|
+
if (rawArgs == null || typeof rawArgs !== "object" || Array.isArray(rawArgs)) {
|
|
2319
|
+
onError == null ? void 0 : onError("toolChoice arguments must be a JSON object", {
|
|
2320
|
+
toolName,
|
|
2321
|
+
arguments: rawArgs
|
|
2322
|
+
});
|
|
2323
|
+
return { toolName, input: "{}" };
|
|
1790
2324
|
}
|
|
2325
|
+
const coercedInput = coerceToolCallInput(toolName, rawArgs, tools);
|
|
2326
|
+
return {
|
|
2327
|
+
toolName,
|
|
2328
|
+
input: coercedInput != null ? coercedInput : safeStringify3(rawArgs)
|
|
2329
|
+
};
|
|
1791
2330
|
}
|
|
2331
|
+
|
|
2332
|
+
// src/generate-handler.ts
|
|
1792
2333
|
function logDebugSummary(debugSummary, toolCall, originText) {
|
|
1793
2334
|
if (debugSummary) {
|
|
1794
2335
|
debugSummary.originalText = originText;
|
|
@@ -1802,25 +2343,34 @@ function logDebugSummary(debugSummary, toolCall, originText) {
|
|
|
1802
2343
|
logParsedSummary({ toolCalls: [toolCall], originalText: originText });
|
|
1803
2344
|
}
|
|
1804
2345
|
}
|
|
1805
|
-
async function handleToolChoice(doGenerate, params) {
|
|
1806
|
-
var _a, _b, _c;
|
|
2346
|
+
async function handleToolChoice(doGenerate, params, tools) {
|
|
2347
|
+
var _a, _b, _c, _d;
|
|
1807
2348
|
const result = await doGenerate();
|
|
1808
2349
|
const first = (_a = result.content) == null ? void 0 : _a[0];
|
|
1809
|
-
|
|
2350
|
+
const onError = (_b = extractOnErrorOption(params.providerOptions)) == null ? void 0 : _b.onError;
|
|
2351
|
+
let toolName = "unknown";
|
|
2352
|
+
let input = "{}";
|
|
1810
2353
|
if (first && first.type === "text") {
|
|
1811
2354
|
if (getDebugLevel() === "parse") {
|
|
1812
2355
|
logRawChunk(first.text);
|
|
1813
2356
|
}
|
|
1814
|
-
parsed =
|
|
2357
|
+
const parsed = parseToolChoicePayload({
|
|
2358
|
+
text: first.text,
|
|
2359
|
+
tools,
|
|
2360
|
+
onError,
|
|
2361
|
+
errorMessage: "Failed to parse toolChoice JSON from generated model output"
|
|
2362
|
+
});
|
|
2363
|
+
toolName = parsed.toolName;
|
|
2364
|
+
input = parsed.input;
|
|
1815
2365
|
}
|
|
1816
2366
|
const toolCall = {
|
|
1817
2367
|
type: "tool-call",
|
|
1818
2368
|
toolCallId: generateId2(),
|
|
1819
|
-
toolName
|
|
1820
|
-
input
|
|
2369
|
+
toolName,
|
|
2370
|
+
input
|
|
1821
2371
|
};
|
|
1822
2372
|
const originText = first && first.type === "text" ? first.text : "";
|
|
1823
|
-
const debugSummary = (
|
|
2373
|
+
const debugSummary = (_d = (_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware) == null ? void 0 : _d.debugSummary;
|
|
1824
2374
|
logDebugSummary(debugSummary, toolCall, originText);
|
|
1825
2375
|
return {
|
|
1826
2376
|
...result,
|
|
@@ -1835,7 +2385,7 @@ function parseContent(content, protocol, tools, providerOptions) {
|
|
|
1835
2385
|
if (getDebugLevel() === "stream") {
|
|
1836
2386
|
logRawChunk(contentItem.text);
|
|
1837
2387
|
}
|
|
1838
|
-
|
|
2388
|
+
const parsedByProtocol = protocol.parseGeneratedText({
|
|
1839
2389
|
text: contentItem.text,
|
|
1840
2390
|
tools,
|
|
1841
2391
|
options: {
|
|
@@ -1843,9 +2393,20 @@ function parseContent(content, protocol, tools, providerOptions) {
|
|
|
1843
2393
|
...providerOptions == null ? void 0 : providerOptions.toolCallMiddleware
|
|
1844
2394
|
}
|
|
1845
2395
|
});
|
|
2396
|
+
const hasToolCall = parsedByProtocol.some(
|
|
2397
|
+
(part) => part.type === "tool-call"
|
|
2398
|
+
);
|
|
2399
|
+
if (hasToolCall) {
|
|
2400
|
+
return parsedByProtocol;
|
|
2401
|
+
}
|
|
2402
|
+
const recoveredFromJson = recoverToolCallFromJsonCandidates(
|
|
2403
|
+
contentItem.text,
|
|
2404
|
+
tools
|
|
2405
|
+
);
|
|
2406
|
+
return recoveredFromJson != null ? recoveredFromJson : parsedByProtocol;
|
|
1846
2407
|
});
|
|
1847
2408
|
return parsed.map(
|
|
1848
|
-
(part) =>
|
|
2409
|
+
(part) => part.type === "tool-call" ? coerceToolCallPart(part, tools) : part
|
|
1849
2410
|
);
|
|
1850
2411
|
}
|
|
1851
2412
|
function logParsedContent(content) {
|
|
@@ -1888,12 +2449,14 @@ async function wrapGenerate({
|
|
|
1888
2449
|
params
|
|
1889
2450
|
}) {
|
|
1890
2451
|
var _a, _b;
|
|
1891
|
-
|
|
1892
|
-
return handleToolChoice(doGenerate, params);
|
|
1893
|
-
}
|
|
2452
|
+
const onError = extractOnErrorOption(params.providerOptions);
|
|
1894
2453
|
const tools = originalToolsSchema.decode(
|
|
1895
|
-
(_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.originalTools
|
|
2454
|
+
(_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.originalTools,
|
|
2455
|
+
onError
|
|
1896
2456
|
);
|
|
2457
|
+
if (isToolChoiceActive(params)) {
|
|
2458
|
+
return handleToolChoice(doGenerate, params, tools);
|
|
2459
|
+
}
|
|
1897
2460
|
const result = await doGenerate();
|
|
1898
2461
|
if (result.content.length === 0) {
|
|
1899
2462
|
return result;
|
|
@@ -1917,28 +2480,6 @@ async function wrapGenerate({
|
|
|
1917
2480
|
content: newContent
|
|
1918
2481
|
};
|
|
1919
2482
|
}
|
|
1920
|
-
function fixToolCallWithSchema(part, tools) {
|
|
1921
|
-
var _a;
|
|
1922
|
-
if (part.type !== "tool-call") {
|
|
1923
|
-
return part;
|
|
1924
|
-
}
|
|
1925
|
-
let args = {};
|
|
1926
|
-
if (typeof part.input === "string") {
|
|
1927
|
-
try {
|
|
1928
|
-
args = JSON.parse(part.input);
|
|
1929
|
-
} catch (e) {
|
|
1930
|
-
return part;
|
|
1931
|
-
}
|
|
1932
|
-
} else if (part.input && typeof part.input === "object") {
|
|
1933
|
-
args = part.input;
|
|
1934
|
-
}
|
|
1935
|
-
const schema = (_a = tools.find((t) => t.name === part.toolName)) == null ? void 0 : _a.inputSchema;
|
|
1936
|
-
const coerced = coerceBySchema(args, schema);
|
|
1937
|
-
return {
|
|
1938
|
-
...part,
|
|
1939
|
-
input: JSON.stringify(coerced != null ? coerced : {})
|
|
1940
|
-
};
|
|
1941
|
-
}
|
|
1942
2483
|
|
|
1943
2484
|
// src/core/prompts/hermes-system-prompt.ts
|
|
1944
2485
|
function hermesSystemPromptTemplate(tools) {
|
|
@@ -2342,19 +2883,22 @@ async function wrapStream({
|
|
|
2342
2883
|
params
|
|
2343
2884
|
}) {
|
|
2344
2885
|
var _a, _b, _c;
|
|
2886
|
+
const onErrorOptions = extractOnErrorOption(params.providerOptions);
|
|
2887
|
+
const tools = originalToolsSchema.decode(
|
|
2888
|
+
(_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.originalTools,
|
|
2889
|
+
onErrorOptions
|
|
2890
|
+
);
|
|
2345
2891
|
if (isToolChoiceActive(params)) {
|
|
2346
2892
|
return toolChoiceStream({
|
|
2347
2893
|
doGenerate,
|
|
2348
|
-
|
|
2894
|
+
tools,
|
|
2895
|
+
options: onErrorOptions
|
|
2349
2896
|
});
|
|
2350
2897
|
}
|
|
2351
2898
|
const { stream, ...rest } = await doStream();
|
|
2352
2899
|
const debugLevel = getDebugLevel();
|
|
2353
|
-
const tools = originalToolsSchema.decode(
|
|
2354
|
-
(_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.originalTools
|
|
2355
|
-
);
|
|
2356
2900
|
const options = {
|
|
2357
|
-
...
|
|
2901
|
+
...onErrorOptions,
|
|
2358
2902
|
...((_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware) || {}
|
|
2359
2903
|
};
|
|
2360
2904
|
const coreStream = stream.pipeThrough(
|
|
@@ -2372,10 +2916,11 @@ async function wrapStream({
|
|
|
2372
2916
|
const v3Stream = coreStream.pipeThrough(
|
|
2373
2917
|
new TransformStream({
|
|
2374
2918
|
transform(part, controller) {
|
|
2919
|
+
const normalizedPart = part.type === "tool-call" ? coerceToolCallPart(part, tools) : part;
|
|
2375
2920
|
if (debugLevel === "stream") {
|
|
2376
|
-
logParsedChunk(
|
|
2921
|
+
logParsedChunk(normalizedPart);
|
|
2377
2922
|
}
|
|
2378
|
-
controller.enqueue(
|
|
2923
|
+
controller.enqueue(normalizedPart);
|
|
2379
2924
|
}
|
|
2380
2925
|
})
|
|
2381
2926
|
);
|
|
@@ -2386,41 +2931,36 @@ async function wrapStream({
|
|
|
2386
2931
|
}
|
|
2387
2932
|
async function toolChoiceStream({
|
|
2388
2933
|
doGenerate,
|
|
2934
|
+
tools,
|
|
2389
2935
|
options
|
|
2390
2936
|
}) {
|
|
2391
|
-
var _a
|
|
2937
|
+
var _a;
|
|
2938
|
+
const normalizedTools = Array.isArray(tools) ? tools : [];
|
|
2392
2939
|
const result = await doGenerate();
|
|
2393
|
-
let
|
|
2940
|
+
let toolName = "unknown";
|
|
2941
|
+
let input = "{}";
|
|
2394
2942
|
if ((result == null ? void 0 : result.content) && result.content.length > 0 && ((_a = result.content[0]) == null ? void 0 : _a.type) === "text") {
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
error: error instanceof Error ? error.message : String(error)
|
|
2404
|
-
}
|
|
2405
|
-
);
|
|
2406
|
-
toolJson = {};
|
|
2407
|
-
}
|
|
2943
|
+
const parsed = parseToolChoicePayload({
|
|
2944
|
+
text: result.content[0].text,
|
|
2945
|
+
tools: normalizedTools,
|
|
2946
|
+
onError: options == null ? void 0 : options.onError,
|
|
2947
|
+
errorMessage: "Failed to parse toolChoice JSON from streamed model output"
|
|
2948
|
+
});
|
|
2949
|
+
toolName = parsed.toolName;
|
|
2950
|
+
input = parsed.input;
|
|
2408
2951
|
}
|
|
2409
2952
|
const stream = new ReadableStream({
|
|
2410
2953
|
start(controller) {
|
|
2411
2954
|
controller.enqueue({
|
|
2412
2955
|
type: "tool-call",
|
|
2413
2956
|
toolCallId: generateId3(),
|
|
2414
|
-
toolName
|
|
2415
|
-
input
|
|
2957
|
+
toolName,
|
|
2958
|
+
input
|
|
2416
2959
|
});
|
|
2417
2960
|
controller.enqueue({
|
|
2418
2961
|
type: "finish",
|
|
2419
|
-
usage: (result == null ? void 0 : result.usage)
|
|
2420
|
-
|
|
2421
|
-
outputTokens: 0
|
|
2422
|
-
},
|
|
2423
|
-
finishReason: "tool-calls"
|
|
2962
|
+
usage: normalizeUsage(result == null ? void 0 : result.usage),
|
|
2963
|
+
finishReason: normalizeToolCallsFinishReason(result == null ? void 0 : result.finishReason)
|
|
2424
2964
|
});
|
|
2425
2965
|
controller.close();
|
|
2426
2966
|
}
|
|
@@ -2431,6 +2971,60 @@ async function toolChoiceStream({
|
|
|
2431
2971
|
stream
|
|
2432
2972
|
};
|
|
2433
2973
|
}
|
|
2974
|
+
var ZERO_USAGE = {
|
|
2975
|
+
inputTokens: {
|
|
2976
|
+
total: 0,
|
|
2977
|
+
noCache: void 0,
|
|
2978
|
+
cacheRead: void 0,
|
|
2979
|
+
cacheWrite: void 0
|
|
2980
|
+
},
|
|
2981
|
+
outputTokens: {
|
|
2982
|
+
total: 0,
|
|
2983
|
+
text: void 0,
|
|
2984
|
+
reasoning: void 0
|
|
2985
|
+
}
|
|
2986
|
+
};
|
|
2987
|
+
function normalizeToolCallsFinishReason(finishReason) {
|
|
2988
|
+
let raw = "tool-calls";
|
|
2989
|
+
if (typeof finishReason === "string") {
|
|
2990
|
+
raw = finishReason;
|
|
2991
|
+
} else if (finishReason && typeof finishReason === "object" && "raw" in finishReason && typeof finishReason.raw === "string") {
|
|
2992
|
+
raw = finishReason.raw;
|
|
2993
|
+
} else if (finishReason && typeof finishReason === "object" && "unified" in finishReason && typeof finishReason.unified === "string") {
|
|
2994
|
+
raw = finishReason.unified;
|
|
2995
|
+
}
|
|
2996
|
+
return {
|
|
2997
|
+
unified: "tool-calls",
|
|
2998
|
+
raw
|
|
2999
|
+
};
|
|
3000
|
+
}
|
|
3001
|
+
function normalizeUsage(usage) {
|
|
3002
|
+
if (!usage || typeof usage !== "object") {
|
|
3003
|
+
return ZERO_USAGE;
|
|
3004
|
+
}
|
|
3005
|
+
const usageRecord = usage;
|
|
3006
|
+
const input = usageRecord.inputTokens;
|
|
3007
|
+
const output = usageRecord.outputTokens;
|
|
3008
|
+
if (input && typeof input === "object" && output && typeof output === "object") {
|
|
3009
|
+
return usage;
|
|
3010
|
+
}
|
|
3011
|
+
if (typeof input === "number" && typeof output === "number") {
|
|
3012
|
+
return {
|
|
3013
|
+
inputTokens: {
|
|
3014
|
+
total: input,
|
|
3015
|
+
noCache: void 0,
|
|
3016
|
+
cacheRead: void 0,
|
|
3017
|
+
cacheWrite: void 0
|
|
3018
|
+
},
|
|
3019
|
+
outputTokens: {
|
|
3020
|
+
total: output,
|
|
3021
|
+
text: void 0,
|
|
3022
|
+
reasoning: void 0
|
|
3023
|
+
}
|
|
3024
|
+
};
|
|
3025
|
+
}
|
|
3026
|
+
return ZERO_USAGE;
|
|
3027
|
+
}
|
|
2434
3028
|
|
|
2435
3029
|
// src/transform-handler.ts
|
|
2436
3030
|
function buildFinalPrompt(systemPrompt, processedPrompt, placement) {
|
|
@@ -2556,6 +3150,11 @@ function handleToolChoiceRequired(params, baseReturnParams, functionTools) {
|
|
|
2556
3150
|
"Tool choice type 'required' is set, but no tools are provided in params.tools."
|
|
2557
3151
|
);
|
|
2558
3152
|
}
|
|
3153
|
+
if (functionTools.length === 0) {
|
|
3154
|
+
throw new Error(
|
|
3155
|
+
"Tool choice type 'required' is set, but no function tools are provided. Provider-defined tools are not supported by this middleware."
|
|
3156
|
+
);
|
|
3157
|
+
}
|
|
2559
3158
|
return {
|
|
2560
3159
|
...baseReturnParams,
|
|
2561
3160
|
responseFormat: {
|
|
@@ -2866,4 +3465,4 @@ export {
|
|
|
2866
3465
|
xmlToolMiddleware,
|
|
2867
3466
|
yamlToolMiddleware
|
|
2868
3467
|
};
|
|
2869
|
-
//# sourceMappingURL=chunk-
|
|
3468
|
+
//# sourceMappingURL=chunk-NAQSTPDQ.js.map
|