@ai-sdk-tool/parser 2.1.4 → 2.1.6
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/README.md +1 -1
- package/dist/index.cjs +200 -331
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +32 -19
- package/dist/index.d.ts +32 -19
- package/dist/index.js +186 -332
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -722,210 +722,6 @@ function stringify(obj) {
|
|
|
722
722
|
return "null";
|
|
723
723
|
}
|
|
724
724
|
|
|
725
|
-
// src/utils/coercion.ts
|
|
726
|
-
function unwrapJsonSchema(schema) {
|
|
727
|
-
if (!schema || typeof schema !== "object") return schema;
|
|
728
|
-
const s = schema;
|
|
729
|
-
if (s.jsonSchema && typeof s.jsonSchema === "object") {
|
|
730
|
-
return unwrapJsonSchema(s.jsonSchema);
|
|
731
|
-
}
|
|
732
|
-
return schema;
|
|
733
|
-
}
|
|
734
|
-
function getSchemaType(schema) {
|
|
735
|
-
const unwrapped = unwrapJsonSchema(schema);
|
|
736
|
-
if (!unwrapped || typeof unwrapped !== "object") return void 0;
|
|
737
|
-
const t = unwrapped.type;
|
|
738
|
-
if (typeof t === "string") return t;
|
|
739
|
-
if (Array.isArray(t)) {
|
|
740
|
-
const preferred = [
|
|
741
|
-
"object",
|
|
742
|
-
"array",
|
|
743
|
-
"boolean",
|
|
744
|
-
"number",
|
|
745
|
-
"integer",
|
|
746
|
-
"string"
|
|
747
|
-
];
|
|
748
|
-
for (const p of preferred) if (t.includes(p)) return p;
|
|
749
|
-
}
|
|
750
|
-
const s = unwrapped;
|
|
751
|
-
if (s && typeof s === "object" && (s.properties || s.additionalProperties)) {
|
|
752
|
-
return "object";
|
|
753
|
-
}
|
|
754
|
-
if (s && typeof s === "object" && (s.items || s.prefixItems)) {
|
|
755
|
-
return "array";
|
|
756
|
-
}
|
|
757
|
-
return void 0;
|
|
758
|
-
}
|
|
759
|
-
function coerceBySchema(value, schema) {
|
|
760
|
-
const unwrapped = unwrapJsonSchema(schema);
|
|
761
|
-
if (!unwrapped || typeof unwrapped !== "object") {
|
|
762
|
-
if (typeof value === "string") {
|
|
763
|
-
const s = value.trim();
|
|
764
|
-
const lower = s.toLowerCase();
|
|
765
|
-
if (lower === "true") return true;
|
|
766
|
-
if (lower === "false") return false;
|
|
767
|
-
if (/^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(s)) {
|
|
768
|
-
const num = Number(s);
|
|
769
|
-
if (Number.isFinite(num)) return num;
|
|
770
|
-
}
|
|
771
|
-
if (s.startsWith("{") && s.endsWith("}") || s.startsWith("[") && s.endsWith("]")) {
|
|
772
|
-
try {
|
|
773
|
-
const parsed = JSON.parse(s);
|
|
774
|
-
return coerceBySchema(parsed, void 0);
|
|
775
|
-
} catch (e) {
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
return value;
|
|
780
|
-
}
|
|
781
|
-
const schemaType = getSchemaType(unwrapped);
|
|
782
|
-
if (typeof value === "string") {
|
|
783
|
-
const s = value.trim();
|
|
784
|
-
if (schemaType === "object") {
|
|
785
|
-
try {
|
|
786
|
-
let normalized = s.replace(/'/g, '"');
|
|
787
|
-
normalized = normalized.replace(/^\{\s*\}$/s, "{}");
|
|
788
|
-
const obj = JSON.parse(normalized);
|
|
789
|
-
if (obj && typeof obj === "object" && !Array.isArray(obj)) {
|
|
790
|
-
const props = unwrapped.properties;
|
|
791
|
-
const out = {};
|
|
792
|
-
for (const [k, v] of Object.entries(obj)) {
|
|
793
|
-
const propSchema = props ? props[k] : void 0;
|
|
794
|
-
out[k] = typeof propSchema === "boolean" ? v : coerceBySchema(v, propSchema);
|
|
795
|
-
}
|
|
796
|
-
return out;
|
|
797
|
-
}
|
|
798
|
-
} catch (e) {
|
|
799
|
-
}
|
|
800
|
-
}
|
|
801
|
-
if (schemaType === "array") {
|
|
802
|
-
try {
|
|
803
|
-
const normalized = s.replace(/'/g, '"');
|
|
804
|
-
const arr = JSON.parse(normalized);
|
|
805
|
-
if (Array.isArray(arr)) {
|
|
806
|
-
const u = unwrapped;
|
|
807
|
-
const prefixItems = Array.isArray(
|
|
808
|
-
u.prefixItems
|
|
809
|
-
) ? u.prefixItems : void 0;
|
|
810
|
-
const itemsSchema = u.items;
|
|
811
|
-
if (prefixItems && arr.length === prefixItems.length) {
|
|
812
|
-
return arr.map((v, i) => coerceBySchema(v, prefixItems[i]));
|
|
813
|
-
}
|
|
814
|
-
return arr.map((v) => coerceBySchema(v, itemsSchema));
|
|
815
|
-
}
|
|
816
|
-
} catch (e) {
|
|
817
|
-
const csv = s.includes("\n") ? s.split(/\n+/) : s.split(/,\s*/);
|
|
818
|
-
const trimmed = csv.map((x) => x.trim()).filter((x) => x.length > 0);
|
|
819
|
-
const u = unwrapped;
|
|
820
|
-
const prefixItems = Array.isArray(
|
|
821
|
-
u.prefixItems
|
|
822
|
-
) ? u.prefixItems : void 0;
|
|
823
|
-
const itemsSchema = u.items;
|
|
824
|
-
if (prefixItems && trimmed.length === prefixItems.length) {
|
|
825
|
-
return trimmed.map((x, i) => coerceBySchema(x, prefixItems[i]));
|
|
826
|
-
}
|
|
827
|
-
return trimmed.map((x) => coerceBySchema(x, itemsSchema));
|
|
828
|
-
}
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
if (schemaType === "object" && value && typeof value === "object" && !Array.isArray(value)) {
|
|
832
|
-
const out = {};
|
|
833
|
-
const props = unwrapped.properties;
|
|
834
|
-
for (const [k, v] of Object.entries(value)) {
|
|
835
|
-
const propSchema = props ? props[k] : void 0;
|
|
836
|
-
out[k] = typeof propSchema === "boolean" ? v : coerceBySchema(v, propSchema);
|
|
837
|
-
}
|
|
838
|
-
return out;
|
|
839
|
-
}
|
|
840
|
-
if (schemaType === "array") {
|
|
841
|
-
const u = unwrapped;
|
|
842
|
-
const itemsSchema = u.items;
|
|
843
|
-
const prefixItems = Array.isArray(
|
|
844
|
-
u.prefixItems
|
|
845
|
-
) ? u.prefixItems : void 0;
|
|
846
|
-
if (Array.isArray(value)) {
|
|
847
|
-
if (prefixItems && value.length === prefixItems.length) {
|
|
848
|
-
return value.map((v, i) => coerceBySchema(v, prefixItems[i]));
|
|
849
|
-
}
|
|
850
|
-
return value.map((v) => coerceBySchema(v, itemsSchema));
|
|
851
|
-
}
|
|
852
|
-
if (value && typeof value === "object") {
|
|
853
|
-
const maybe = value;
|
|
854
|
-
if (Object.prototype.hasOwnProperty.call(maybe, "item")) {
|
|
855
|
-
const items = maybe.item;
|
|
856
|
-
const arr = Array.isArray(items) ? items : [items];
|
|
857
|
-
if (prefixItems && arr.length === prefixItems.length) {
|
|
858
|
-
return arr.map((v, i) => coerceBySchema(v, prefixItems[i]));
|
|
859
|
-
}
|
|
860
|
-
return arr.map((v) => coerceBySchema(v, itemsSchema));
|
|
861
|
-
}
|
|
862
|
-
const keys = Object.keys(maybe);
|
|
863
|
-
if (keys.length === 1) {
|
|
864
|
-
const singleKey = keys[0];
|
|
865
|
-
const singleValue = maybe[singleKey];
|
|
866
|
-
if (Array.isArray(singleValue)) {
|
|
867
|
-
const coercedArray = singleValue.map(
|
|
868
|
-
(v) => coerceBySchema(v, itemsSchema)
|
|
869
|
-
);
|
|
870
|
-
return coercedArray;
|
|
871
|
-
}
|
|
872
|
-
}
|
|
873
|
-
if (keys.length > 0 && keys.every((k) => /^\d+$/.test(k))) {
|
|
874
|
-
const arr = keys.sort((a, b) => Number(a) - Number(b)).map((k) => maybe[k]);
|
|
875
|
-
if (prefixItems && arr.length === prefixItems.length) {
|
|
876
|
-
return arr.map((v, i) => coerceBySchema(v, prefixItems[i]));
|
|
877
|
-
}
|
|
878
|
-
return arr.map((v) => coerceBySchema(v, itemsSchema));
|
|
879
|
-
}
|
|
880
|
-
}
|
|
881
|
-
if (value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
882
|
-
if (prefixItems && prefixItems.length > 0) {
|
|
883
|
-
return [coerceBySchema(value, prefixItems[0])];
|
|
884
|
-
}
|
|
885
|
-
return [coerceBySchema(value, itemsSchema)];
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
if (typeof value === "string") {
|
|
889
|
-
const s = value.trim();
|
|
890
|
-
if (schemaType === "boolean") {
|
|
891
|
-
const lower = s.toLowerCase();
|
|
892
|
-
if (lower === "true") return true;
|
|
893
|
-
if (lower === "false") return false;
|
|
894
|
-
}
|
|
895
|
-
if (schemaType === "number" || schemaType === "integer") {
|
|
896
|
-
if (/^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(s)) {
|
|
897
|
-
const num = Number(s);
|
|
898
|
-
if (Number.isFinite(num)) return num;
|
|
899
|
-
}
|
|
900
|
-
}
|
|
901
|
-
}
|
|
902
|
-
return value;
|
|
903
|
-
}
|
|
904
|
-
function fixToolCallWithSchema(part, tools) {
|
|
905
|
-
var _a;
|
|
906
|
-
if (part.type !== "tool-call") return part;
|
|
907
|
-
const tc = part;
|
|
908
|
-
let args = {};
|
|
909
|
-
if (typeof tc.input === "string") {
|
|
910
|
-
try {
|
|
911
|
-
args = JSON.parse(tc.input);
|
|
912
|
-
} catch (e) {
|
|
913
|
-
return part;
|
|
914
|
-
}
|
|
915
|
-
} else if (tc.input && typeof tc.input === "object") {
|
|
916
|
-
args = tc.input;
|
|
917
|
-
}
|
|
918
|
-
const schema = (_a = tools.find((t) => t.name === tc.toolName)) == null ? void 0 : _a.inputSchema;
|
|
919
|
-
const coerced = coerceBySchema(args, schema);
|
|
920
|
-
return {
|
|
921
|
-
...part,
|
|
922
|
-
input: JSON.stringify(coerced != null ? coerced : {})
|
|
923
|
-
};
|
|
924
|
-
}
|
|
925
|
-
function coerceToolCallInput(part, tools) {
|
|
926
|
-
return fixToolCallWithSchema(part, tools);
|
|
927
|
-
}
|
|
928
|
-
|
|
929
725
|
// src/utils/debug.ts
|
|
930
726
|
function normalizeBooleanString(value) {
|
|
931
727
|
const normalized = value.trim().toLowerCase();
|
|
@@ -1013,33 +809,34 @@ function extractOnErrorOption(providerOptions) {
|
|
|
1013
809
|
return void 0;
|
|
1014
810
|
}
|
|
1015
811
|
|
|
1016
|
-
// src/utils/
|
|
812
|
+
// src/utils/provider-options.ts
|
|
813
|
+
var originalToolsSchema = {
|
|
814
|
+
encode: encodeOriginalTools,
|
|
815
|
+
decode: decodeOriginalTools
|
|
816
|
+
};
|
|
817
|
+
function encodeOriginalTools(tools) {
|
|
818
|
+
return (tools == null ? void 0 : tools.map((t) => ({
|
|
819
|
+
name: t.name,
|
|
820
|
+
inputSchema: JSON.stringify(t.inputSchema)
|
|
821
|
+
}))) || [];
|
|
822
|
+
}
|
|
823
|
+
function decodeOriginalTools(originalTools) {
|
|
824
|
+
const tools = (originalTools == null ? void 0 : originalTools.map(
|
|
825
|
+
(t) => ({
|
|
826
|
+
name: t.name,
|
|
827
|
+
inputSchema: JSON.parse(t.inputSchema)
|
|
828
|
+
})
|
|
829
|
+
)) || [];
|
|
830
|
+
return tools;
|
|
831
|
+
}
|
|
832
|
+
function extractToolNamesFromOriginalTools(originalTools) {
|
|
833
|
+
return (originalTools == null ? void 0 : originalTools.map((t) => t.name)) || [];
|
|
834
|
+
}
|
|
1017
835
|
function isToolChoiceActive(params) {
|
|
1018
836
|
var _a, _b, _c;
|
|
1019
837
|
const toolChoice = (_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.toolChoice;
|
|
1020
838
|
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"));
|
|
1021
839
|
}
|
|
1022
|
-
function getFunctionTools(params) {
|
|
1023
|
-
var _a, _b;
|
|
1024
|
-
const functionTools = ((_a = params.tools) != null ? _a : []).filter(
|
|
1025
|
-
(t) => t.type === "function"
|
|
1026
|
-
);
|
|
1027
|
-
if (functionTools.length > 0) return functionTools;
|
|
1028
|
-
const rawToolNames = params.providerOptions && typeof params.providerOptions === "object" && ((_b = params.providerOptions.toolCallMiddleware) == null ? void 0 : _b.toolNames) || [];
|
|
1029
|
-
const toStringArray = (val) => Array.isArray(val) ? val.filter(
|
|
1030
|
-
(item) => typeof item === "string"
|
|
1031
|
-
) : [];
|
|
1032
|
-
const toolNames = toStringArray(rawToolNames);
|
|
1033
|
-
if (toolNames.length > 0) {
|
|
1034
|
-
return toolNames.map((name) => ({
|
|
1035
|
-
type: "function",
|
|
1036
|
-
name,
|
|
1037
|
-
description: "",
|
|
1038
|
-
inputSchema: { type: "object" }
|
|
1039
|
-
}));
|
|
1040
|
-
}
|
|
1041
|
-
return [];
|
|
1042
|
-
}
|
|
1043
840
|
|
|
1044
841
|
// src/utils/type-guards.ts
|
|
1045
842
|
function isToolCallContent(content) {
|
|
@@ -1294,64 +1091,13 @@ var jsonMixProtocol = ({
|
|
|
1294
1091
|
|
|
1295
1092
|
// src/protocols/morph-xml-protocol.ts
|
|
1296
1093
|
import { generateId as generateId3 } from "@ai-sdk/provider-utils";
|
|
1297
|
-
import
|
|
1298
|
-
findFirstTopLevelRange,
|
|
1299
|
-
parse as parseXml,
|
|
1300
|
-
RXMLCoercionError,
|
|
1301
|
-
RXMLDuplicateStringTagError,
|
|
1302
|
-
RXMLParseError,
|
|
1303
|
-
stringify as stringify2
|
|
1304
|
-
} from "@ai-sdk-tool/rxml";
|
|
1305
|
-
function getToolSchema(tools, originalSchemas, toolName) {
|
|
1306
|
-
var _a;
|
|
1307
|
-
const original = originalSchemas[toolName];
|
|
1308
|
-
if (original) return original;
|
|
1309
|
-
const fallback = (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
|
|
1310
|
-
return fallback;
|
|
1311
|
-
}
|
|
1312
|
-
function findToolCalls(text, toolNames) {
|
|
1313
|
-
const toolCalls = [];
|
|
1314
|
-
for (const toolName of toolNames) {
|
|
1315
|
-
let searchIndex = 0;
|
|
1316
|
-
while (searchIndex < text.length) {
|
|
1317
|
-
const startTag = `<${toolName}>`;
|
|
1318
|
-
const tagStart = text.indexOf(startTag, searchIndex);
|
|
1319
|
-
if (tagStart === -1) break;
|
|
1320
|
-
const remainingText = text.substring(tagStart);
|
|
1321
|
-
const range = findFirstTopLevelRange(remainingText, toolName);
|
|
1322
|
-
if (range) {
|
|
1323
|
-
const contentStart = tagStart + startTag.length;
|
|
1324
|
-
const contentEnd = contentStart + (range.end - range.start);
|
|
1325
|
-
let fullTagEnd = contentEnd + `</${toolName}>`.length;
|
|
1326
|
-
const closeHead = text.indexOf(`</${toolName}`, contentEnd);
|
|
1327
|
-
if (closeHead === contentEnd) {
|
|
1328
|
-
let p = closeHead + 2 + toolName.length;
|
|
1329
|
-
while (p < text.length && /\s/.test(text[p])) p++;
|
|
1330
|
-
if (text[p] === ">") fullTagEnd = p + 1;
|
|
1331
|
-
}
|
|
1332
|
-
const toolContent = text.substring(contentStart, contentEnd);
|
|
1333
|
-
const fullSegment = text.substring(tagStart, fullTagEnd);
|
|
1334
|
-
toolCalls.push({
|
|
1335
|
-
toolName,
|
|
1336
|
-
startIndex: tagStart,
|
|
1337
|
-
endIndex: fullTagEnd,
|
|
1338
|
-
content: toolContent,
|
|
1339
|
-
segment: fullSegment
|
|
1340
|
-
});
|
|
1341
|
-
searchIndex = fullTagEnd;
|
|
1342
|
-
} else {
|
|
1343
|
-
searchIndex = tagStart + startTag.length;
|
|
1344
|
-
}
|
|
1345
|
-
}
|
|
1346
|
-
}
|
|
1347
|
-
return toolCalls.sort((a, b) => a.startIndex - b.startIndex);
|
|
1348
|
-
}
|
|
1094
|
+
import * as RXML from "@ai-sdk-tool/rxml";
|
|
1349
1095
|
var morphXmlProtocol = () => ({
|
|
1350
1096
|
formatTools({ tools, toolSystemPromptTemplate }) {
|
|
1351
1097
|
const toolsForPrompt = (tools || []).map((tool) => ({
|
|
1352
1098
|
name: tool.name,
|
|
1353
1099
|
description: tool.description,
|
|
1354
|
-
parameters: unwrapJsonSchema(tool.inputSchema)
|
|
1100
|
+
parameters: RXML.unwrapJsonSchema(tool.inputSchema)
|
|
1355
1101
|
}));
|
|
1356
1102
|
return toolSystemPromptTemplate(JSON.stringify(toolsForPrompt));
|
|
1357
1103
|
},
|
|
@@ -1367,20 +1113,19 @@ var morphXmlProtocol = () => ({
|
|
|
1367
1113
|
} else {
|
|
1368
1114
|
args = inputValue;
|
|
1369
1115
|
}
|
|
1370
|
-
return
|
|
1116
|
+
return RXML.stringify(toolCall.toolName, args, {
|
|
1371
1117
|
suppressEmptyNode: false,
|
|
1372
1118
|
format: false
|
|
1373
1119
|
});
|
|
1374
1120
|
},
|
|
1375
1121
|
formatToolResponse(toolResult) {
|
|
1376
|
-
return
|
|
1122
|
+
return RXML.stringify("tool_response", {
|
|
1377
1123
|
tool_name: toolResult.toolName,
|
|
1378
1124
|
result: toolResult.output
|
|
1379
1125
|
});
|
|
1380
1126
|
},
|
|
1381
1127
|
parseGeneratedText({ text, tools, options }) {
|
|
1382
1128
|
var _a;
|
|
1383
|
-
const originalSchemas = (options == null ? void 0 : options.originalToolSchemas) || {};
|
|
1384
1129
|
const toolNames = tools.map((t) => t.name).filter((name) => name != null);
|
|
1385
1130
|
if (toolNames.length === 0) {
|
|
1386
1131
|
return [{ type: "text", text }];
|
|
@@ -1396,13 +1141,11 @@ var morphXmlProtocol = () => ({
|
|
|
1396
1141
|
}
|
|
1397
1142
|
}
|
|
1398
1143
|
try {
|
|
1399
|
-
const toolSchema = getToolSchema(
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
const parsed = parseXml(toolCall.content, toolSchema, {
|
|
1405
|
-
onError: options == null ? void 0 : options.onError
|
|
1144
|
+
const toolSchema = getToolSchema(tools, toolCall.toolName);
|
|
1145
|
+
const parsed = RXML.parse(toolCall.content, toolSchema, {
|
|
1146
|
+
onError: options == null ? void 0 : options.onError,
|
|
1147
|
+
// Disable HTML self-closing tag behavior to allow base, meta, link etc. as regular tags
|
|
1148
|
+
noChildNodes: []
|
|
1406
1149
|
});
|
|
1407
1150
|
processedElements.push({
|
|
1408
1151
|
type: "tool-call",
|
|
@@ -1434,8 +1177,8 @@ var morphXmlProtocol = () => ({
|
|
|
1434
1177
|
return processedElements;
|
|
1435
1178
|
},
|
|
1436
1179
|
createStreamParser({ tools, options }) {
|
|
1437
|
-
const originalSchemas = (options == null ? void 0 : options.originalToolSchemas) || {};
|
|
1438
1180
|
const toolNames = tools.map((t) => t.name).filter((name) => name != null);
|
|
1181
|
+
const maxStartTagLen = toolNames.length ? Math.max(...toolNames.map((n) => `<${n}>`.length)) : 0;
|
|
1439
1182
|
let buffer = "";
|
|
1440
1183
|
let currentToolCall = null;
|
|
1441
1184
|
let currentTextId = null;
|
|
@@ -1477,13 +1220,11 @@ var morphXmlProtocol = () => ({
|
|
|
1477
1220
|
const toolContent = buffer.substring(0, endTagIndex);
|
|
1478
1221
|
buffer = buffer.substring(endTagIndex + endTag.length);
|
|
1479
1222
|
try {
|
|
1480
|
-
const toolSchema = getToolSchema(
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
const parsed = parseXml(toolContent, toolSchema, {
|
|
1486
|
-
onError: options == null ? void 0 : options.onError
|
|
1223
|
+
const toolSchema = getToolSchema(tools, currentToolCall.name);
|
|
1224
|
+
const parsed = RXML.parse(toolContent, toolSchema, {
|
|
1225
|
+
onError: options == null ? void 0 : options.onError,
|
|
1226
|
+
// Disable HTML self-closing tag behavior to allow base, meta, link etc. as regular tags
|
|
1227
|
+
noChildNodes: []
|
|
1487
1228
|
});
|
|
1488
1229
|
flushText(controller);
|
|
1489
1230
|
controller.enqueue({
|
|
@@ -1495,11 +1236,11 @@ var morphXmlProtocol = () => ({
|
|
|
1495
1236
|
} catch (error) {
|
|
1496
1237
|
const originalCallText = `<${currentToolCall.name}>${toolContent}${endTag}`;
|
|
1497
1238
|
let message = "Could not process streaming XML tool call; emitting original text.";
|
|
1498
|
-
if (error instanceof RXMLDuplicateStringTagError) {
|
|
1239
|
+
if (error instanceof RXML.RXMLDuplicateStringTagError) {
|
|
1499
1240
|
message = `Duplicate string tags detected in streaming tool call '${currentToolCall.name}'; emitting original text.`;
|
|
1500
|
-
} else if (error instanceof RXMLCoercionError) {
|
|
1241
|
+
} else if (error instanceof RXML.RXMLCoercionError) {
|
|
1501
1242
|
message = `Failed to coerce arguments for streaming tool call '${currentToolCall.name}'; emitting original text.`;
|
|
1502
|
-
} else if (error instanceof RXMLParseError) {
|
|
1243
|
+
} else if (error instanceof RXML.RXMLParseError) {
|
|
1503
1244
|
message = `Failed to parse XML for streaming tool call '${currentToolCall.name}'; emitting original text.`;
|
|
1504
1245
|
}
|
|
1505
1246
|
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, message, {
|
|
@@ -1535,6 +1276,14 @@ var morphXmlProtocol = () => ({
|
|
|
1535
1276
|
);
|
|
1536
1277
|
currentToolCall = { name: earliestToolName, content: "" };
|
|
1537
1278
|
} else {
|
|
1279
|
+
const tail = Math.max(0, maxStartTagLen - 1);
|
|
1280
|
+
const safeLen = Math.max(0, buffer.length - tail);
|
|
1281
|
+
if (safeLen > 0) {
|
|
1282
|
+
const textToFlush = buffer.slice(0, safeLen);
|
|
1283
|
+
flushText(controller, textToFlush);
|
|
1284
|
+
buffer = buffer.slice(safeLen);
|
|
1285
|
+
continue;
|
|
1286
|
+
}
|
|
1538
1287
|
break;
|
|
1539
1288
|
}
|
|
1540
1289
|
}
|
|
@@ -1559,6 +1308,48 @@ var morphXmlProtocol = () => ({
|
|
|
1559
1308
|
return findToolCalls(text, toolNames).map((tc) => tc.segment);
|
|
1560
1309
|
}
|
|
1561
1310
|
});
|
|
1311
|
+
function getToolSchema(tools, toolName) {
|
|
1312
|
+
var _a;
|
|
1313
|
+
return (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
|
|
1314
|
+
}
|
|
1315
|
+
function findToolCalls(text, toolNames) {
|
|
1316
|
+
var _a;
|
|
1317
|
+
const toolCalls = [];
|
|
1318
|
+
for (const toolName of toolNames) {
|
|
1319
|
+
let searchIndex = 0;
|
|
1320
|
+
while (searchIndex < text.length) {
|
|
1321
|
+
const startTag = `<${toolName}>`;
|
|
1322
|
+
const tagStart = text.indexOf(startTag, searchIndex);
|
|
1323
|
+
if (tagStart === -1) break;
|
|
1324
|
+
const remainingText = text.substring(tagStart);
|
|
1325
|
+
const range = RXML.findFirstTopLevelRange(remainingText, toolName);
|
|
1326
|
+
if (range) {
|
|
1327
|
+
const contentStart = tagStart + startTag.length;
|
|
1328
|
+
const contentEnd = contentStart + (range.end - range.start);
|
|
1329
|
+
let fullTagEnd = contentEnd + `</${toolName}>`.length;
|
|
1330
|
+
const closeHead = text.indexOf(`</${toolName}`, contentEnd);
|
|
1331
|
+
if (closeHead === contentEnd) {
|
|
1332
|
+
let p = closeHead + 2 + toolName.length;
|
|
1333
|
+
while (p < text.length && /\s/.test(text[p])) p++;
|
|
1334
|
+
if (text[p] === ">") fullTagEnd = p + 1;
|
|
1335
|
+
}
|
|
1336
|
+
const segment = text.substring(tagStart, fullTagEnd);
|
|
1337
|
+
const content = (_a = RXML.extractRawInner(segment, toolName)) != null ? _a : text.substring(contentStart, contentEnd);
|
|
1338
|
+
toolCalls.push({
|
|
1339
|
+
toolName,
|
|
1340
|
+
startIndex: tagStart,
|
|
1341
|
+
endIndex: fullTagEnd,
|
|
1342
|
+
content,
|
|
1343
|
+
segment
|
|
1344
|
+
});
|
|
1345
|
+
searchIndex = fullTagEnd;
|
|
1346
|
+
} else {
|
|
1347
|
+
searchIndex = tagStart + startTag.length;
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
return toolCalls.sort((a, b) => a.startIndex - b.startIndex);
|
|
1352
|
+
}
|
|
1562
1353
|
|
|
1563
1354
|
// src/protocols/tool-call-protocol.ts
|
|
1564
1355
|
function isProtocolFactory(protocol) {
|
|
@@ -1567,12 +1358,13 @@ function isProtocolFactory(protocol) {
|
|
|
1567
1358
|
|
|
1568
1359
|
// src/generate-handler.ts
|
|
1569
1360
|
import { generateId as generateId4 } from "@ai-sdk/provider-utils";
|
|
1361
|
+
import * as RXML2 from "@ai-sdk-tool/rxml";
|
|
1570
1362
|
async function wrapGenerate({
|
|
1571
1363
|
protocol,
|
|
1572
1364
|
doGenerate,
|
|
1573
1365
|
params
|
|
1574
1366
|
}) {
|
|
1575
|
-
var _a, _b;
|
|
1367
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1576
1368
|
if (isToolChoiceActive(params)) {
|
|
1577
1369
|
const result2 = await doGenerate();
|
|
1578
1370
|
let parsed2 = {};
|
|
@@ -1605,7 +1397,16 @@ async function wrapGenerate({
|
|
|
1605
1397
|
};
|
|
1606
1398
|
const debugLevelToolChoice = getDebugLevel();
|
|
1607
1399
|
const originText = first && first.type === "text" ? first.text : "";
|
|
1608
|
-
|
|
1400
|
+
const dbg2 = (_d = (_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware) == null ? void 0 : _d.debugSummary;
|
|
1401
|
+
if (dbg2) {
|
|
1402
|
+
dbg2.originalText = originText;
|
|
1403
|
+
try {
|
|
1404
|
+
dbg2.toolCalls = JSON.stringify([
|
|
1405
|
+
{ toolName: toolCall.toolName, input: toolCall.input }
|
|
1406
|
+
]);
|
|
1407
|
+
} catch (e) {
|
|
1408
|
+
}
|
|
1409
|
+
} else if (debugLevelToolChoice === "parse") {
|
|
1609
1410
|
logParsedSummary({ toolCalls: [toolCall], originalText: originText });
|
|
1610
1411
|
}
|
|
1611
1412
|
return {
|
|
@@ -1613,6 +1414,9 @@ async function wrapGenerate({
|
|
|
1613
1414
|
content: [toolCall]
|
|
1614
1415
|
};
|
|
1615
1416
|
}
|
|
1417
|
+
const tools = originalToolsSchema.decode(
|
|
1418
|
+
(_f = (_e = params.providerOptions) == null ? void 0 : _e.toolCallMiddleware) == null ? void 0 : _f.originalTools
|
|
1419
|
+
);
|
|
1616
1420
|
const result = await doGenerate();
|
|
1617
1421
|
if (result.content.length === 0) {
|
|
1618
1422
|
return result;
|
|
@@ -1628,30 +1432,41 @@ async function wrapGenerate({
|
|
|
1628
1432
|
}
|
|
1629
1433
|
return protocol.parseGeneratedText({
|
|
1630
1434
|
text: contentItem.text,
|
|
1631
|
-
tools
|
|
1435
|
+
tools,
|
|
1632
1436
|
options: {
|
|
1633
1437
|
...extractOnErrorOption(params.providerOptions),
|
|
1634
1438
|
...(_a2 = params.providerOptions) == null ? void 0 : _a2.toolCallMiddleware
|
|
1635
1439
|
}
|
|
1636
1440
|
});
|
|
1637
1441
|
});
|
|
1638
|
-
const tools = getFunctionTools(params);
|
|
1639
1442
|
const newContent = parsed.map(
|
|
1640
|
-
(part) =>
|
|
1443
|
+
(part) => fixToolCallWithSchema(part, tools)
|
|
1641
1444
|
);
|
|
1642
1445
|
const debugLevel = getDebugLevel();
|
|
1643
1446
|
if (debugLevel === "stream") {
|
|
1644
1447
|
newContent.forEach((part) => logParsedChunk(part));
|
|
1645
1448
|
}
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1449
|
+
const allText = result.content.filter(
|
|
1450
|
+
(c) => c.type === "text"
|
|
1451
|
+
).map((c) => c.text).join("\n\n");
|
|
1452
|
+
const segments = protocol.extractToolCallSegments ? protocol.extractToolCallSegments({ text: allText, tools }) : [];
|
|
1453
|
+
const originalText = segments.join("\n\n");
|
|
1454
|
+
const toolCalls = newContent.filter(
|
|
1455
|
+
(p) => p.type === "tool-call"
|
|
1456
|
+
);
|
|
1457
|
+
const dbg = (_h = (_g = params.providerOptions) == null ? void 0 : _g.toolCallMiddleware) == null ? void 0 : _h.debugSummary;
|
|
1458
|
+
if (dbg) {
|
|
1459
|
+
dbg.originalText = originalText;
|
|
1460
|
+
try {
|
|
1461
|
+
dbg.toolCalls = JSON.stringify(
|
|
1462
|
+
toolCalls.map((tc) => ({
|
|
1463
|
+
toolName: tc.toolName,
|
|
1464
|
+
input: tc.input
|
|
1465
|
+
}))
|
|
1466
|
+
);
|
|
1467
|
+
} catch (e) {
|
|
1468
|
+
}
|
|
1469
|
+
} else if (debugLevel === "parse") {
|
|
1655
1470
|
logParsedSummary({ toolCalls, originalText });
|
|
1656
1471
|
}
|
|
1657
1472
|
return {
|
|
@@ -1659,6 +1474,27 @@ async function wrapGenerate({
|
|
|
1659
1474
|
content: newContent
|
|
1660
1475
|
};
|
|
1661
1476
|
}
|
|
1477
|
+
function fixToolCallWithSchema(part, tools) {
|
|
1478
|
+
var _a;
|
|
1479
|
+
if (part.type !== "tool-call") return part;
|
|
1480
|
+
const tc = part;
|
|
1481
|
+
let args = {};
|
|
1482
|
+
if (typeof tc.input === "string") {
|
|
1483
|
+
try {
|
|
1484
|
+
args = JSON.parse(tc.input);
|
|
1485
|
+
} catch (e) {
|
|
1486
|
+
return part;
|
|
1487
|
+
}
|
|
1488
|
+
} else if (tc.input && typeof tc.input === "object") {
|
|
1489
|
+
args = tc.input;
|
|
1490
|
+
}
|
|
1491
|
+
const schema = (_a = tools.find((t) => t.name === tc.toolName)) == null ? void 0 : _a.inputSchema;
|
|
1492
|
+
const coerced = RXML2.coerceBySchema(args, schema);
|
|
1493
|
+
return {
|
|
1494
|
+
...part,
|
|
1495
|
+
input: JSON.stringify(coerced != null ? coerced : {})
|
|
1496
|
+
};
|
|
1497
|
+
}
|
|
1662
1498
|
|
|
1663
1499
|
// src/stream-handler.ts
|
|
1664
1500
|
import { generateId as generateId5 } from "@ai-sdk/provider-utils";
|
|
@@ -1668,7 +1504,7 @@ async function wrapStream({
|
|
|
1668
1504
|
doGenerate,
|
|
1669
1505
|
params
|
|
1670
1506
|
}) {
|
|
1671
|
-
var _a;
|
|
1507
|
+
var _a, _b, _c;
|
|
1672
1508
|
if (isToolChoiceActive(params)) {
|
|
1673
1509
|
return toolChoiceStream({
|
|
1674
1510
|
doGenerate,
|
|
@@ -1677,10 +1513,12 @@ async function wrapStream({
|
|
|
1677
1513
|
}
|
|
1678
1514
|
const { stream, ...rest } = await doStream();
|
|
1679
1515
|
const debugLevel = getDebugLevel();
|
|
1680
|
-
const tools =
|
|
1516
|
+
const tools = originalToolsSchema.decode(
|
|
1517
|
+
(_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.originalTools
|
|
1518
|
+
);
|
|
1681
1519
|
const options = {
|
|
1682
1520
|
...extractOnErrorOption(params.providerOptions),
|
|
1683
|
-
...(
|
|
1521
|
+
...(_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware
|
|
1684
1522
|
};
|
|
1685
1523
|
if (debugLevel === "off") {
|
|
1686
1524
|
return {
|
|
@@ -1750,6 +1588,7 @@ async function wrapStream({
|
|
|
1750
1588
|
transform: /* @__PURE__ */ (() => {
|
|
1751
1589
|
const parsedToolCalls = [];
|
|
1752
1590
|
return (part, controller) => {
|
|
1591
|
+
var _a2, _b2;
|
|
1753
1592
|
if (part.type === "tool-call") {
|
|
1754
1593
|
parsedToolCalls.push(part);
|
|
1755
1594
|
}
|
|
@@ -1760,10 +1599,27 @@ async function wrapStream({
|
|
|
1760
1599
|
tools
|
|
1761
1600
|
}) : [];
|
|
1762
1601
|
const origin = segments.join("\n\n");
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
originalText
|
|
1766
|
-
|
|
1602
|
+
const dbg = (_b2 = (_a2 = params.providerOptions) == null ? void 0 : _a2.toolCallMiddleware) == null ? void 0 : _b2.debugSummary;
|
|
1603
|
+
if (dbg) {
|
|
1604
|
+
dbg.originalText = origin;
|
|
1605
|
+
try {
|
|
1606
|
+
const toolCallParts = parsedToolCalls.filter(
|
|
1607
|
+
(p) => p.type === "tool-call"
|
|
1608
|
+
);
|
|
1609
|
+
dbg.toolCalls = JSON.stringify(
|
|
1610
|
+
toolCallParts.map((tc) => ({
|
|
1611
|
+
toolName: tc.toolName,
|
|
1612
|
+
input: tc.input
|
|
1613
|
+
}))
|
|
1614
|
+
);
|
|
1615
|
+
} catch (e) {
|
|
1616
|
+
}
|
|
1617
|
+
} else {
|
|
1618
|
+
logParsedSummary({
|
|
1619
|
+
toolCalls: parsedToolCalls,
|
|
1620
|
+
originalText: origin
|
|
1621
|
+
});
|
|
1622
|
+
}
|
|
1767
1623
|
} catch (e) {
|
|
1768
1624
|
}
|
|
1769
1625
|
}
|
|
@@ -1889,10 +1745,10 @@ async function transformParams({
|
|
|
1889
1745
|
...params.providerOptions || {},
|
|
1890
1746
|
toolCallMiddleware: {
|
|
1891
1747
|
...params.providerOptions && typeof params.providerOptions === "object" && params.providerOptions.toolCallMiddleware || {},
|
|
1892
|
-
// INTERNAL: used by the middleware
|
|
1893
|
-
//
|
|
1894
|
-
//
|
|
1895
|
-
|
|
1748
|
+
// INTERNAL: used by the middleware so downstream parsers can access
|
|
1749
|
+
// the original tool schemas even if providers strip `params.tools`.
|
|
1750
|
+
// Not a stable public API.
|
|
1751
|
+
originalTools: originalToolsSchema.encode(functionTools)
|
|
1896
1752
|
}
|
|
1897
1753
|
}
|
|
1898
1754
|
};
|
|
@@ -2173,25 +2029,23 @@ When an argument is an array, write each item inside a single element on one lin
|
|
|
2173
2029
|
Examples:
|
|
2174
2030
|
<get_weather>
|
|
2175
2031
|
<location>
|
|
2176
|
-
San
|
|
2032
|
+
San Francisco
|
|
2177
2033
|
</location>
|
|
2178
2034
|
</get_weather>`;
|
|
2179
2035
|
}
|
|
2180
2036
|
});
|
|
2181
2037
|
export {
|
|
2182
2038
|
robust_json_exports as RJSON,
|
|
2183
|
-
coerceBySchema,
|
|
2184
|
-
coerceToolCallInput,
|
|
2185
2039
|
createDynamicIfThenElseSchema,
|
|
2186
2040
|
createToolMiddleware,
|
|
2041
|
+
decodeOriginalTools,
|
|
2042
|
+
encodeOriginalTools,
|
|
2187
2043
|
escapeRegExp,
|
|
2188
2044
|
extractOnErrorOption,
|
|
2189
|
-
|
|
2045
|
+
extractToolNamesFromOriginalTools,
|
|
2190
2046
|
gemmaToolMiddleware,
|
|
2191
2047
|
getDebugLevel,
|
|
2192
|
-
getFunctionTools,
|
|
2193
2048
|
getPotentialStartIndex,
|
|
2194
|
-
getSchemaType,
|
|
2195
2049
|
hasInputProperty,
|
|
2196
2050
|
hermesToolMiddleware,
|
|
2197
2051
|
isToolCallContent,
|
|
@@ -2202,7 +2056,7 @@ export {
|
|
|
2202
2056
|
logParsedSummary,
|
|
2203
2057
|
logRawChunk,
|
|
2204
2058
|
morphXmlProtocol,
|
|
2205
|
-
|
|
2059
|
+
originalToolsSchema,
|
|
2206
2060
|
xmlToolMiddleware
|
|
2207
2061
|
};
|
|
2208
2062
|
//# sourceMappingURL=index.js.map
|