@ai-sdk-tool/parser 2.1.0 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +129 -0
- package/dist/index.cjs +1154 -470
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +97 -7
- package/dist/index.d.ts +97 -7
- package/dist/index.js +1154 -470
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -24,12 +24,15 @@ __export(index_exports, {
|
|
|
24
24
|
gemmaToolMiddleware: () => gemmaToolMiddleware,
|
|
25
25
|
hermesToolMiddleware: () => hermesToolMiddleware,
|
|
26
26
|
jsonMixProtocol: () => jsonMixProtocol,
|
|
27
|
-
|
|
27
|
+
morphXmlProtocol: () => morphXmlProtocol,
|
|
28
28
|
xmlToolMiddleware: () => xmlToolMiddleware
|
|
29
29
|
});
|
|
30
30
|
module.exports = __toCommonJS(index_exports);
|
|
31
31
|
|
|
32
|
-
// src/
|
|
32
|
+
// src/protocols/dummy-protocol.ts
|
|
33
|
+
var import_provider_utils = require("@ai-sdk/provider-utils");
|
|
34
|
+
|
|
35
|
+
// src/protocols/json-mix-protocol.ts
|
|
33
36
|
var import_provider_utils2 = require("@ai-sdk/provider-utils");
|
|
34
37
|
|
|
35
38
|
// src/utils/dynamic-tool-schema.ts
|
|
@@ -106,6 +109,11 @@ function getPotentialStartIndex(text, searchedText) {
|
|
|
106
109
|
return null;
|
|
107
110
|
}
|
|
108
111
|
|
|
112
|
+
// src/utils/regex.ts
|
|
113
|
+
function escapeRegExp(literal) {
|
|
114
|
+
return literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
115
|
+
}
|
|
116
|
+
|
|
109
117
|
// src/utils/relaxed-json.ts
|
|
110
118
|
var relaxed_json_exports = {};
|
|
111
119
|
__export(relaxed_json_exports, {
|
|
@@ -440,7 +448,6 @@ function appendPair(state, obj, key, value) {
|
|
|
440
448
|
}
|
|
441
449
|
function parsePair(tokens, state, obj) {
|
|
442
450
|
let token = skipPunctuation(tokens, state, [":", "string", "number", "atom"]);
|
|
443
|
-
let key;
|
|
444
451
|
let value;
|
|
445
452
|
if (token.type !== "string") {
|
|
446
453
|
raiseUnexpected(state, token, "string key");
|
|
@@ -490,7 +497,7 @@ function parsePair(tokens, state, obj) {
|
|
|
490
497
|
}
|
|
491
498
|
}
|
|
492
499
|
checkDuplicates(state, obj, token);
|
|
493
|
-
key = String(token.value);
|
|
500
|
+
const key = String(token.value);
|
|
494
501
|
skipColon(tokens, state);
|
|
495
502
|
value = parseAny(tokens, state);
|
|
496
503
|
appendPair(state, obj, key, value);
|
|
@@ -661,7 +668,10 @@ function parse(text, optsOrReviver) {
|
|
|
661
668
|
if (!options.relaxed && !options.warnings && !options.tolerant) {
|
|
662
669
|
if (!options.duplicate) {
|
|
663
670
|
} else {
|
|
664
|
-
return JSON.parse(
|
|
671
|
+
return JSON.parse(
|
|
672
|
+
text,
|
|
673
|
+
options.reviver
|
|
674
|
+
);
|
|
665
675
|
}
|
|
666
676
|
}
|
|
667
677
|
const lexerToUse = options.relaxed ? lexer : strictLexer;
|
|
@@ -681,7 +691,7 @@ function parse(text, optsOrReviver) {
|
|
|
681
691
|
};
|
|
682
692
|
return parseAny(tokens, state, true);
|
|
683
693
|
} else {
|
|
684
|
-
|
|
694
|
+
tokens.reduce((str, token) => {
|
|
685
695
|
return str + token.match;
|
|
686
696
|
}, "");
|
|
687
697
|
if (!options.relaxed && !options.warnings && !options.tolerant && options.duplicate) {
|
|
@@ -705,8 +715,11 @@ function parse(text, optsOrReviver) {
|
|
|
705
715
|
} else {
|
|
706
716
|
tokens = lexer(text);
|
|
707
717
|
tokens = stripTrailingComma(tokens);
|
|
708
|
-
const
|
|
709
|
-
return JSON.parse(
|
|
718
|
+
const newtext = tokens.reduce((str, token) => str + token.match, "");
|
|
719
|
+
return JSON.parse(
|
|
720
|
+
newtext,
|
|
721
|
+
options.reviver
|
|
722
|
+
);
|
|
710
723
|
}
|
|
711
724
|
}
|
|
712
725
|
}
|
|
@@ -734,22 +747,300 @@ function stringify(obj) {
|
|
|
734
747
|
return "null";
|
|
735
748
|
}
|
|
736
749
|
|
|
737
|
-
// src/utils/
|
|
738
|
-
function
|
|
739
|
-
|
|
750
|
+
// src/utils/coercion.ts
|
|
751
|
+
function unwrapJsonSchema(schema) {
|
|
752
|
+
if (!schema || typeof schema !== "object") return schema;
|
|
753
|
+
const s = schema;
|
|
754
|
+
if (s.jsonSchema && typeof s.jsonSchema === "object") {
|
|
755
|
+
return unwrapJsonSchema(s.jsonSchema);
|
|
756
|
+
}
|
|
757
|
+
return schema;
|
|
758
|
+
}
|
|
759
|
+
function getSchemaType(schema) {
|
|
760
|
+
const unwrapped = unwrapJsonSchema(schema);
|
|
761
|
+
if (!unwrapped || typeof unwrapped !== "object") return void 0;
|
|
762
|
+
const t = unwrapped.type;
|
|
763
|
+
if (typeof t === "string") return t;
|
|
764
|
+
if (Array.isArray(t)) {
|
|
765
|
+
const preferred = [
|
|
766
|
+
"object",
|
|
767
|
+
"array",
|
|
768
|
+
"boolean",
|
|
769
|
+
"number",
|
|
770
|
+
"integer",
|
|
771
|
+
"string"
|
|
772
|
+
];
|
|
773
|
+
for (const p of preferred) if (t.includes(p)) return p;
|
|
774
|
+
}
|
|
775
|
+
const s = unwrapped;
|
|
776
|
+
if (s && typeof s === "object" && (s.properties || s.additionalProperties)) {
|
|
777
|
+
return "object";
|
|
778
|
+
}
|
|
779
|
+
if (s && typeof s === "object" && (s.items || s.prefixItems)) {
|
|
780
|
+
return "array";
|
|
781
|
+
}
|
|
782
|
+
return void 0;
|
|
783
|
+
}
|
|
784
|
+
function coerceBySchema(value, schema) {
|
|
785
|
+
const unwrapped = unwrapJsonSchema(schema);
|
|
786
|
+
if (!unwrapped || typeof unwrapped !== "object") {
|
|
787
|
+
if (typeof value === "string") {
|
|
788
|
+
const s = value.trim();
|
|
789
|
+
const lower = s.toLowerCase();
|
|
790
|
+
if (lower === "true") return true;
|
|
791
|
+
if (lower === "false") return false;
|
|
792
|
+
if (/^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(s)) {
|
|
793
|
+
const num = Number(s);
|
|
794
|
+
if (Number.isFinite(num)) return num;
|
|
795
|
+
}
|
|
796
|
+
if (s.startsWith("{") && s.endsWith("}") || s.startsWith("[") && s.endsWith("]")) {
|
|
797
|
+
try {
|
|
798
|
+
const parsed = JSON.parse(s);
|
|
799
|
+
return coerceBySchema(parsed, void 0);
|
|
800
|
+
} catch (e) {
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
return value;
|
|
805
|
+
}
|
|
806
|
+
const schemaType = getSchemaType(unwrapped);
|
|
807
|
+
if (typeof value === "string") {
|
|
808
|
+
const s = value.trim();
|
|
809
|
+
if (schemaType === "object") {
|
|
810
|
+
try {
|
|
811
|
+
let normalized = s.replace(/'/g, '"');
|
|
812
|
+
normalized = normalized.replace(/^\{\s*\}$/s, "{}");
|
|
813
|
+
const obj = JSON.parse(normalized);
|
|
814
|
+
if (obj && typeof obj === "object" && !Array.isArray(obj)) {
|
|
815
|
+
const props = unwrapped.properties;
|
|
816
|
+
const out = {};
|
|
817
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
818
|
+
const propSchema = props ? props[k] : void 0;
|
|
819
|
+
out[k] = typeof propSchema === "boolean" ? v : coerceBySchema(v, propSchema);
|
|
820
|
+
}
|
|
821
|
+
return out;
|
|
822
|
+
}
|
|
823
|
+
} catch (e) {
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
if (schemaType === "array") {
|
|
827
|
+
try {
|
|
828
|
+
const normalized = s.replace(/'/g, '"');
|
|
829
|
+
const arr = JSON.parse(normalized);
|
|
830
|
+
if (Array.isArray(arr)) {
|
|
831
|
+
const u = unwrapped;
|
|
832
|
+
const prefixItems = Array.isArray(
|
|
833
|
+
u.prefixItems
|
|
834
|
+
) ? u.prefixItems : void 0;
|
|
835
|
+
const itemsSchema = u.items;
|
|
836
|
+
if (prefixItems && arr.length === prefixItems.length) {
|
|
837
|
+
return arr.map((v, i) => coerceBySchema(v, prefixItems[i]));
|
|
838
|
+
}
|
|
839
|
+
return arr.map((v) => coerceBySchema(v, itemsSchema));
|
|
840
|
+
}
|
|
841
|
+
} catch (e) {
|
|
842
|
+
const csv = s.includes("\n") ? s.split(/\n+/) : s.split(/,\s*/);
|
|
843
|
+
const trimmed = csv.map((x) => x.trim()).filter((x) => x.length > 0);
|
|
844
|
+
const u = unwrapped;
|
|
845
|
+
const prefixItems = Array.isArray(
|
|
846
|
+
u.prefixItems
|
|
847
|
+
) ? u.prefixItems : void 0;
|
|
848
|
+
const itemsSchema = u.items;
|
|
849
|
+
if (prefixItems && trimmed.length === prefixItems.length) {
|
|
850
|
+
return trimmed.map((x, i) => coerceBySchema(x, prefixItems[i]));
|
|
851
|
+
}
|
|
852
|
+
return trimmed.map((x) => coerceBySchema(x, itemsSchema));
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
if (schemaType === "object" && value && typeof value === "object" && !Array.isArray(value)) {
|
|
857
|
+
const out = {};
|
|
858
|
+
const props = unwrapped.properties;
|
|
859
|
+
for (const [k, v] of Object.entries(value)) {
|
|
860
|
+
const propSchema = props ? props[k] : void 0;
|
|
861
|
+
out[k] = typeof propSchema === "boolean" ? v : coerceBySchema(v, propSchema);
|
|
862
|
+
}
|
|
863
|
+
return out;
|
|
864
|
+
}
|
|
865
|
+
if (schemaType === "array") {
|
|
866
|
+
const u = unwrapped;
|
|
867
|
+
const itemsSchema = u.items;
|
|
868
|
+
const prefixItems = Array.isArray(
|
|
869
|
+
u.prefixItems
|
|
870
|
+
) ? u.prefixItems : void 0;
|
|
871
|
+
if (Array.isArray(value)) {
|
|
872
|
+
if (prefixItems && value.length === prefixItems.length) {
|
|
873
|
+
return value.map((v, i) => coerceBySchema(v, prefixItems[i]));
|
|
874
|
+
}
|
|
875
|
+
return value.map((v) => coerceBySchema(v, itemsSchema));
|
|
876
|
+
}
|
|
877
|
+
if (value && typeof value === "object") {
|
|
878
|
+
const maybe = value;
|
|
879
|
+
if (Object.prototype.hasOwnProperty.call(maybe, "item")) {
|
|
880
|
+
const items = maybe.item;
|
|
881
|
+
const arr = Array.isArray(items) ? items : [items];
|
|
882
|
+
if (prefixItems && arr.length === prefixItems.length) {
|
|
883
|
+
return arr.map((v, i) => coerceBySchema(v, prefixItems[i]));
|
|
884
|
+
}
|
|
885
|
+
return arr.map((v) => coerceBySchema(v, itemsSchema));
|
|
886
|
+
}
|
|
887
|
+
const keys = Object.keys(maybe);
|
|
888
|
+
if (keys.length === 1) {
|
|
889
|
+
const singleKey = keys[0];
|
|
890
|
+
const singleValue = maybe[singleKey];
|
|
891
|
+
if (Array.isArray(singleValue)) {
|
|
892
|
+
const coercedArray = singleValue.map(
|
|
893
|
+
(v) => coerceBySchema(v, itemsSchema)
|
|
894
|
+
);
|
|
895
|
+
return coercedArray;
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
if (keys.length > 0 && keys.every((k) => /^\d+$/.test(k))) {
|
|
899
|
+
const arr = keys.sort((a, b) => Number(a) - Number(b)).map((k) => maybe[k]);
|
|
900
|
+
if (prefixItems && arr.length === prefixItems.length) {
|
|
901
|
+
return arr.map((v, i) => coerceBySchema(v, prefixItems[i]));
|
|
902
|
+
}
|
|
903
|
+
return arr.map((v) => coerceBySchema(v, itemsSchema));
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
if (value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
907
|
+
if (prefixItems && prefixItems.length > 0) {
|
|
908
|
+
return [coerceBySchema(value, prefixItems[0])];
|
|
909
|
+
}
|
|
910
|
+
return [coerceBySchema(value, itemsSchema)];
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
if (typeof value === "string") {
|
|
914
|
+
const s = value.trim();
|
|
915
|
+
if (schemaType === "boolean") {
|
|
916
|
+
const lower = s.toLowerCase();
|
|
917
|
+
if (lower === "true") return true;
|
|
918
|
+
if (lower === "false") return false;
|
|
919
|
+
}
|
|
920
|
+
if (schemaType === "number" || schemaType === "integer") {
|
|
921
|
+
if (/^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(s)) {
|
|
922
|
+
const num = Number(s);
|
|
923
|
+
if (Number.isFinite(num)) return num;
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
return value;
|
|
928
|
+
}
|
|
929
|
+
function fixToolCallWithSchema(part, tools) {
|
|
930
|
+
var _a;
|
|
931
|
+
if (part.type !== "tool-call") return part;
|
|
932
|
+
const tc = part;
|
|
933
|
+
let args = {};
|
|
934
|
+
if (typeof tc.input === "string") {
|
|
935
|
+
try {
|
|
936
|
+
args = JSON.parse(tc.input);
|
|
937
|
+
} catch (e) {
|
|
938
|
+
return part;
|
|
939
|
+
}
|
|
940
|
+
} else if (tc.input && typeof tc.input === "object") {
|
|
941
|
+
args = tc.input;
|
|
942
|
+
}
|
|
943
|
+
const schema = (_a = tools.find((t) => t.name === tc.toolName)) == null ? void 0 : _a.inputSchema;
|
|
944
|
+
const coerced = coerceBySchema(args, schema);
|
|
945
|
+
return {
|
|
946
|
+
...part,
|
|
947
|
+
input: JSON.stringify(coerced != null ? coerced : {})
|
|
948
|
+
};
|
|
949
|
+
}
|
|
950
|
+
function coerceToolCallInput(part, tools) {
|
|
951
|
+
return fixToolCallWithSchema(part, tools);
|
|
740
952
|
}
|
|
741
953
|
|
|
742
|
-
// src/utils/
|
|
743
|
-
function
|
|
744
|
-
|
|
745
|
-
(
|
|
954
|
+
// src/utils/debug.ts
|
|
955
|
+
function normalizeBooleanString(value) {
|
|
956
|
+
const normalized = value.trim().toLowerCase();
|
|
957
|
+
if (normalized === "1" || normalized === "true" || normalized === "yes") {
|
|
958
|
+
return true;
|
|
959
|
+
}
|
|
960
|
+
if (normalized === "0" || normalized === "false" || normalized === "no") {
|
|
961
|
+
return false;
|
|
962
|
+
}
|
|
963
|
+
return void 0;
|
|
746
964
|
}
|
|
747
|
-
function
|
|
748
|
-
const
|
|
749
|
-
|
|
965
|
+
function getDebugLevel() {
|
|
966
|
+
const envVal = typeof process !== "undefined" && process.env && process.env.DEBUG_PARSER_MW || "off";
|
|
967
|
+
const envLower = String(envVal).toLowerCase();
|
|
968
|
+
if (envLower === "stream" || envLower === "parse" || envLower === "off") {
|
|
969
|
+
return envLower;
|
|
970
|
+
}
|
|
971
|
+
const boolEnv = normalizeBooleanString(envLower);
|
|
972
|
+
if (boolEnv === true) return "stream";
|
|
973
|
+
if (envLower === "2") return "parse";
|
|
974
|
+
return "off";
|
|
750
975
|
}
|
|
751
|
-
function
|
|
752
|
-
return
|
|
976
|
+
function color(code) {
|
|
977
|
+
return (text) => `\x1B[${code}m${text}\x1B[0m`;
|
|
978
|
+
}
|
|
979
|
+
var cGray = color(90);
|
|
980
|
+
var cYellow = color(33);
|
|
981
|
+
var cCyan = color(36);
|
|
982
|
+
var cBgBlue = color(44);
|
|
983
|
+
var cBgGreen = color(42);
|
|
984
|
+
var cInverse = color(7);
|
|
985
|
+
var cUnderline = color(4);
|
|
986
|
+
var cBold = color(1);
|
|
987
|
+
function safeStringify(value) {
|
|
988
|
+
try {
|
|
989
|
+
return `
|
|
990
|
+
${typeof value === "string" ? value : JSON.stringify(value, null, 2)}`;
|
|
991
|
+
} catch (e) {
|
|
992
|
+
return String(value);
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
function logRawChunk(part) {
|
|
996
|
+
console.log(cGray("[debug:mw:raw]"), cYellow(safeStringify(part)));
|
|
997
|
+
}
|
|
998
|
+
function logParsedChunk(part) {
|
|
999
|
+
console.log(cGray("[debug:mw:out]"), cCyan(safeStringify(part)));
|
|
1000
|
+
}
|
|
1001
|
+
function logParsedSummary({
|
|
1002
|
+
toolCalls,
|
|
1003
|
+
originalText
|
|
1004
|
+
}) {
|
|
1005
|
+
if (originalText) {
|
|
1006
|
+
const style = (() => {
|
|
1007
|
+
const envVal = typeof process !== "undefined" && process.env && process.env.DEBUG_PARSER_MW_STYLE || "bg";
|
|
1008
|
+
const normalized = String(envVal).trim().toLowerCase();
|
|
1009
|
+
if (normalized === "inverse" || normalized === "invert")
|
|
1010
|
+
return "inverse";
|
|
1011
|
+
if (normalized === "underline" || normalized === "ul")
|
|
1012
|
+
return "underline";
|
|
1013
|
+
if (normalized === "bold") return "bold";
|
|
1014
|
+
if (normalized === "bg" || normalized === "background")
|
|
1015
|
+
return "bg";
|
|
1016
|
+
const asBool = normalizeBooleanString(normalized);
|
|
1017
|
+
if (asBool === true) return "bg";
|
|
1018
|
+
return "bg";
|
|
1019
|
+
})();
|
|
1020
|
+
const highlight = style === "inverse" ? cInverse : style === "underline" ? cUnderline : style === "bold" ? cBold : style === "bg" ? cBgGreen : cYellow;
|
|
1021
|
+
const rendered = style === "bg" || style === "inverse" || style === "underline" || style === "bold" ? originalText.split(/\r?\n/).map((line) => line.length ? highlight(line) : line).join("\n") : highlight(originalText);
|
|
1022
|
+
console.log(cGray("[debug:mw:origin]"), `
|
|
1023
|
+
${rendered}`);
|
|
1024
|
+
}
|
|
1025
|
+
if (toolCalls.length > 0) {
|
|
1026
|
+
const styledSummary = safeStringify(toolCalls).split(/\r?\n/).map((line) => line.length ? cBgBlue(line) : line).join("\n");
|
|
1027
|
+
console.log(cGray("[debug:mw:summary]"), styledSummary);
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
// src/utils/on-error.ts
|
|
1032
|
+
function extractOnErrorOption(providerOptions) {
|
|
1033
|
+
var _a;
|
|
1034
|
+
if (providerOptions && typeof providerOptions === "object") {
|
|
1035
|
+
const onError = (_a = providerOptions.toolCallMiddleware) == null ? void 0 : _a.onError;
|
|
1036
|
+
return onError ? { onError } : void 0;
|
|
1037
|
+
}
|
|
1038
|
+
return void 0;
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
// src/utils/protocol.ts
|
|
1042
|
+
function isProtocolFactory(protocol) {
|
|
1043
|
+
return typeof protocol === "function";
|
|
753
1044
|
}
|
|
754
1045
|
|
|
755
1046
|
// src/utils/tools.ts
|
|
@@ -760,7 +1051,11 @@ function isToolChoiceActive(params) {
|
|
|
760
1051
|
}
|
|
761
1052
|
function getFunctionTools(params) {
|
|
762
1053
|
var _a, _b;
|
|
763
|
-
const
|
|
1054
|
+
const functionTools = ((_a = params.tools) != null ? _a : []).filter(
|
|
1055
|
+
(t) => t.type === "function"
|
|
1056
|
+
);
|
|
1057
|
+
if (functionTools.length > 0) return functionTools;
|
|
1058
|
+
const rawToolNames = params.providerOptions && typeof params.providerOptions === "object" && ((_b = params.providerOptions.toolCallMiddleware) == null ? void 0 : _b.toolNames) || [];
|
|
764
1059
|
const toStringArray = (val) => Array.isArray(val) ? val.filter(
|
|
765
1060
|
(item) => typeof item === "string"
|
|
766
1061
|
) : [];
|
|
@@ -773,436 +1068,101 @@ function getFunctionTools(params) {
|
|
|
773
1068
|
inputSchema: { type: "object" }
|
|
774
1069
|
}));
|
|
775
1070
|
}
|
|
776
|
-
return
|
|
777
|
-
(t) => t.type === "function"
|
|
778
|
-
);
|
|
1071
|
+
return [];
|
|
779
1072
|
}
|
|
780
1073
|
|
|
781
|
-
// src/utils/
|
|
782
|
-
function
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
return
|
|
1074
|
+
// src/utils/type-guards.ts
|
|
1075
|
+
function isToolCallContent(content) {
|
|
1076
|
+
return content.type === "tool-call" && typeof content.toolName === "string" && // input may be a JSON string or an already-parsed object depending on provider/runtime
|
|
1077
|
+
(typeof content.input === "string" || typeof content.input === "object");
|
|
1078
|
+
}
|
|
1079
|
+
function isToolResultPart(content) {
|
|
1080
|
+
const c = content;
|
|
1081
|
+
return !!c && c.type === "tool-result" && typeof c.toolName === "string" && typeof c.toolCallId === "string" && "output" in c;
|
|
1082
|
+
}
|
|
1083
|
+
function hasInputProperty(obj) {
|
|
1084
|
+
return typeof obj === "object" && obj !== null && "input" in obj;
|
|
789
1085
|
}
|
|
790
1086
|
|
|
791
|
-
// src/
|
|
792
|
-
var
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
1087
|
+
// src/protocols/json-mix-protocol.ts
|
|
1088
|
+
var jsonMixProtocol = ({
|
|
1089
|
+
toolCallStart = "<tool_call>",
|
|
1090
|
+
toolCallEnd = "</tool_call>",
|
|
1091
|
+
toolResponseStart = "<tool_response>",
|
|
1092
|
+
toolResponseEnd = "</tool_response>"
|
|
1093
|
+
} = {}) => ({
|
|
1094
|
+
formatTools({ tools, toolSystemPromptTemplate }) {
|
|
1095
|
+
const toolsForPrompt = (tools || []).filter((tool) => tool.type === "function").map((tool) => ({
|
|
1096
|
+
name: tool.name,
|
|
1097
|
+
description: tool.type === "function" && typeof tool.description === "string" ? tool.description : void 0,
|
|
1098
|
+
parameters: tool.inputSchema
|
|
1099
|
+
}));
|
|
1100
|
+
return toolSystemPromptTemplate(JSON.stringify(toolsForPrompt));
|
|
1101
|
+
},
|
|
1102
|
+
formatToolCall(toolCall) {
|
|
1103
|
+
let args = {};
|
|
801
1104
|
try {
|
|
802
|
-
|
|
803
|
-
} catch (
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
1105
|
+
args = JSON.parse(toolCall.input);
|
|
1106
|
+
} catch (e) {
|
|
1107
|
+
args = toolCall.input;
|
|
1108
|
+
}
|
|
1109
|
+
return `${toolCallStart}${JSON.stringify({
|
|
1110
|
+
name: toolCall.toolName,
|
|
1111
|
+
arguments: args
|
|
1112
|
+
})}${toolCallEnd}`;
|
|
1113
|
+
},
|
|
1114
|
+
formatToolResponse(toolResult) {
|
|
1115
|
+
return `${toolResponseStart}${JSON.stringify({
|
|
1116
|
+
toolName: toolResult.toolName,
|
|
1117
|
+
result: toolResult.output
|
|
1118
|
+
})}${toolResponseEnd}`;
|
|
1119
|
+
},
|
|
1120
|
+
parseGeneratedText({ text, options }) {
|
|
1121
|
+
var _a;
|
|
1122
|
+
const startEsc = escapeRegExp(toolCallStart);
|
|
1123
|
+
const endEsc = escapeRegExp(toolCallEnd);
|
|
1124
|
+
const toolCallRegex = new RegExp(
|
|
1125
|
+
`${startEsc}([\0-\uFFFF]*?)${endEsc}`,
|
|
1126
|
+
"gs"
|
|
1127
|
+
);
|
|
1128
|
+
const processedElements = [];
|
|
1129
|
+
let currentIndex = 0;
|
|
1130
|
+
let match;
|
|
1131
|
+
while ((match = toolCallRegex.exec(text)) !== null) {
|
|
1132
|
+
const startIndex = match.index;
|
|
1133
|
+
const toolCallJson = match[1];
|
|
1134
|
+
if (startIndex > currentIndex) {
|
|
1135
|
+
const textSegment = text.substring(currentIndex, startIndex);
|
|
1136
|
+
if (textSegment.trim()) {
|
|
1137
|
+
processedElements.push({ type: "text", text: textSegment });
|
|
810
1138
|
}
|
|
811
|
-
|
|
812
|
-
|
|
1139
|
+
}
|
|
1140
|
+
if (toolCallJson) {
|
|
1141
|
+
try {
|
|
1142
|
+
const parsedToolCall = relaxed_json_exports.parse(toolCallJson);
|
|
1143
|
+
processedElements.push({
|
|
1144
|
+
type: "tool-call",
|
|
1145
|
+
toolCallId: (0, import_provider_utils2.generateId)(),
|
|
1146
|
+
toolName: parsedToolCall.name,
|
|
1147
|
+
input: JSON.stringify((_a = parsedToolCall.arguments) != null ? _a : {})
|
|
1148
|
+
});
|
|
1149
|
+
} catch (error) {
|
|
1150
|
+
if (options == null ? void 0 : options.onError) {
|
|
1151
|
+
options.onError(
|
|
1152
|
+
"Could not process JSON tool call, keeping original text.",
|
|
1153
|
+
{ toolCall: match[0], error }
|
|
1154
|
+
);
|
|
1155
|
+
}
|
|
1156
|
+
processedElements.push({ type: "text", text: match[0] });
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
currentIndex = startIndex + match[0].length;
|
|
813
1160
|
}
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
input: JSON.stringify(toolJson.arguments || {})
|
|
820
|
-
};
|
|
821
|
-
const finishChunk = {
|
|
822
|
-
type: "finish",
|
|
823
|
-
usage: (result == null ? void 0 : result.usage) || // TODO: If possible, try to return a certain amount of LLM usage.
|
|
824
|
-
{
|
|
825
|
-
inputTokens: 0,
|
|
826
|
-
outputTokens: 0,
|
|
827
|
-
totalTokens: 0
|
|
828
|
-
},
|
|
829
|
-
finishReason: "tool-calls"
|
|
830
|
-
};
|
|
831
|
-
const stream = new ReadableStream({
|
|
832
|
-
start(controller) {
|
|
833
|
-
controller.enqueue(toolCallChunk);
|
|
834
|
-
controller.enqueue(finishChunk);
|
|
835
|
-
controller.close();
|
|
836
|
-
}
|
|
837
|
-
});
|
|
838
|
-
return {
|
|
839
|
-
request: (result == null ? void 0 : result.request) || {},
|
|
840
|
-
response: (result == null ? void 0 : result.response) || {},
|
|
841
|
-
stream
|
|
842
|
-
};
|
|
843
|
-
}
|
|
844
|
-
|
|
845
|
-
// src/tool-call-middleware.ts
|
|
846
|
-
function isProtocolFactory(protocol) {
|
|
847
|
-
return typeof protocol === "function";
|
|
848
|
-
}
|
|
849
|
-
function createToolMiddleware({
|
|
850
|
-
protocol,
|
|
851
|
-
toolSystemPromptTemplate
|
|
852
|
-
}) {
|
|
853
|
-
const resolvedProtocol = isProtocolFactory(protocol) ? protocol() : protocol;
|
|
854
|
-
return {
|
|
855
|
-
middlewareVersion: "v2",
|
|
856
|
-
wrapStream: async ({ doStream, doGenerate, params }) => {
|
|
857
|
-
if (isToolChoiceActive(params)) {
|
|
858
|
-
return toolChoiceStream({
|
|
859
|
-
doGenerate,
|
|
860
|
-
options: extractOnErrorOption(params.providerOptions)
|
|
861
|
-
});
|
|
862
|
-
}
|
|
863
|
-
const { stream, ...rest } = await doStream();
|
|
864
|
-
return {
|
|
865
|
-
stream: stream.pipeThrough(
|
|
866
|
-
resolvedProtocol.createStreamParser({
|
|
867
|
-
tools: getFunctionTools(params),
|
|
868
|
-
options: extractOnErrorOption(params.providerOptions)
|
|
869
|
-
})
|
|
870
|
-
),
|
|
871
|
-
...rest
|
|
872
|
-
};
|
|
873
|
-
},
|
|
874
|
-
wrapGenerate: async ({ doGenerate, params }) => {
|
|
875
|
-
var _a, _b;
|
|
876
|
-
if (isToolChoiceActive(params)) {
|
|
877
|
-
const result2 = await doGenerate();
|
|
878
|
-
let parsed = {};
|
|
879
|
-
const first = (_a = result2.content) == null ? void 0 : _a[0];
|
|
880
|
-
if (first && first.type === "text") {
|
|
881
|
-
try {
|
|
882
|
-
parsed = JSON.parse(first.text);
|
|
883
|
-
} catch (error) {
|
|
884
|
-
const options = extractOnErrorOption(params.providerOptions);
|
|
885
|
-
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
886
|
-
options,
|
|
887
|
-
"Failed to parse toolChoice JSON from generated model output",
|
|
888
|
-
{
|
|
889
|
-
text: first.text,
|
|
890
|
-
error: error instanceof Error ? error.message : String(error)
|
|
891
|
-
}
|
|
892
|
-
);
|
|
893
|
-
parsed = {};
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
return {
|
|
897
|
-
...result2,
|
|
898
|
-
content: [
|
|
899
|
-
{
|
|
900
|
-
type: "tool-call",
|
|
901
|
-
toolCallId: (0, import_provider_utils2.generateId)(),
|
|
902
|
-
toolName: parsed.name || "unknown",
|
|
903
|
-
input: JSON.stringify(parsed.arguments || {})
|
|
904
|
-
}
|
|
905
|
-
]
|
|
906
|
-
};
|
|
907
|
-
}
|
|
908
|
-
const result = await doGenerate();
|
|
909
|
-
if (result.content.length === 0) {
|
|
910
|
-
return result;
|
|
911
|
-
}
|
|
912
|
-
const newContent = result.content.flatMap((contentItem) => {
|
|
913
|
-
if (contentItem.type !== "text") {
|
|
914
|
-
return [contentItem];
|
|
915
|
-
}
|
|
916
|
-
return resolvedProtocol.parseGeneratedText({
|
|
917
|
-
text: contentItem.text,
|
|
918
|
-
tools: getFunctionTools(params),
|
|
919
|
-
options: extractOnErrorOption(params.providerOptions)
|
|
920
|
-
});
|
|
921
|
-
});
|
|
922
|
-
return {
|
|
923
|
-
...result,
|
|
924
|
-
content: newContent
|
|
925
|
-
};
|
|
926
|
-
},
|
|
927
|
-
transformParams: async ({ params }) => {
|
|
928
|
-
var _a, _b, _c, _d, _e, _f;
|
|
929
|
-
const convertToolPrompt = (prompt) => {
|
|
930
|
-
const processedPrompt2 = prompt.map((message) => {
|
|
931
|
-
var _a2;
|
|
932
|
-
if (message.role === "assistant") {
|
|
933
|
-
const newContent = [];
|
|
934
|
-
for (const content of message.content) {
|
|
935
|
-
if (isToolCallContent(content)) {
|
|
936
|
-
newContent.push({
|
|
937
|
-
type: "text",
|
|
938
|
-
text: resolvedProtocol.formatToolCall(content)
|
|
939
|
-
});
|
|
940
|
-
} else if (content.type === "text") {
|
|
941
|
-
newContent.push(content);
|
|
942
|
-
} else if (content.type === "reasoning") {
|
|
943
|
-
newContent.push(content);
|
|
944
|
-
} else {
|
|
945
|
-
const options = extractOnErrorOption(params.providerOptions);
|
|
946
|
-
(_a2 = options == null ? void 0 : options.onError) == null ? void 0 : _a2.call(
|
|
947
|
-
options,
|
|
948
|
-
"tool-call-middleware: unknown assistant content; stringifying for provider compatibility",
|
|
949
|
-
{ content }
|
|
950
|
-
);
|
|
951
|
-
newContent.push({
|
|
952
|
-
type: "text",
|
|
953
|
-
text: JSON.stringify(content)
|
|
954
|
-
});
|
|
955
|
-
}
|
|
956
|
-
}
|
|
957
|
-
const onlyText = newContent.every((c) => c.type === "text");
|
|
958
|
-
const condensedAssistant = onlyText ? [
|
|
959
|
-
{
|
|
960
|
-
type: "text",
|
|
961
|
-
text: newContent.map((c) => c.text).join("\n")
|
|
962
|
-
}
|
|
963
|
-
] : newContent;
|
|
964
|
-
return { role: "assistant", content: condensedAssistant };
|
|
965
|
-
}
|
|
966
|
-
if (message.role === "tool") {
|
|
967
|
-
return {
|
|
968
|
-
role: "user",
|
|
969
|
-
// Map tool results to text response blocks, then condense into a single text block
|
|
970
|
-
content: [
|
|
971
|
-
{
|
|
972
|
-
type: "text",
|
|
973
|
-
text: message.content.map(
|
|
974
|
-
(toolResult) => isToolResultPart(toolResult) ? resolvedProtocol.formatToolResponse(toolResult) : resolvedProtocol.formatToolResponse(
|
|
975
|
-
toolResult
|
|
976
|
-
)
|
|
977
|
-
).join("\n")
|
|
978
|
-
}
|
|
979
|
-
]
|
|
980
|
-
};
|
|
981
|
-
}
|
|
982
|
-
return message;
|
|
983
|
-
});
|
|
984
|
-
for (let i = 0; i < processedPrompt2.length; i++) {
|
|
985
|
-
const msg = processedPrompt2[i];
|
|
986
|
-
if (Array.isArray(msg.content)) {
|
|
987
|
-
const allText = msg.content.every((c) => (c == null ? void 0 : c.type) === "text");
|
|
988
|
-
if (allText && msg.content.length > 1) {
|
|
989
|
-
processedPrompt2[i] = {
|
|
990
|
-
role: msg.role,
|
|
991
|
-
content: [
|
|
992
|
-
{
|
|
993
|
-
type: "text",
|
|
994
|
-
text: msg.content.map((c) => c.text).join("\n")
|
|
995
|
-
}
|
|
996
|
-
]
|
|
997
|
-
};
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
}
|
|
1001
|
-
for (let i = processedPrompt2.length - 1; i > 0; i--) {
|
|
1002
|
-
const current = processedPrompt2[i];
|
|
1003
|
-
const prev = processedPrompt2[i - 1];
|
|
1004
|
-
if (current.role === "user" && prev.role === "user") {
|
|
1005
|
-
const prevContent = prev.content.map((c) => c.type === "text" ? c.text : "").join("\n");
|
|
1006
|
-
const currentContent = current.content.map((c) => c.type === "text" ? c.text : "").join("\n");
|
|
1007
|
-
processedPrompt2[i - 1] = {
|
|
1008
|
-
role: "user",
|
|
1009
|
-
content: [
|
|
1010
|
-
{ type: "text", text: prevContent + "\n" + currentContent }
|
|
1011
|
-
]
|
|
1012
|
-
};
|
|
1013
|
-
processedPrompt2.splice(i, 1);
|
|
1014
|
-
}
|
|
1015
|
-
}
|
|
1016
|
-
return processedPrompt2;
|
|
1017
|
-
};
|
|
1018
|
-
const functionTools = ((_a = params.tools) != null ? _a : []).filter(
|
|
1019
|
-
(t) => t.type === "function"
|
|
1020
|
-
);
|
|
1021
|
-
const systemPrompt = resolvedProtocol.formatTools({
|
|
1022
|
-
tools: functionTools,
|
|
1023
|
-
toolSystemPromptTemplate
|
|
1024
|
-
});
|
|
1025
|
-
const processedPrompt = convertToolPrompt(params.prompt);
|
|
1026
|
-
const finalPrompt = ((_b = processedPrompt[0]) == null ? void 0 : _b.role) === "system" ? [
|
|
1027
|
-
{
|
|
1028
|
-
role: "system",
|
|
1029
|
-
content: systemPrompt + "\n\n" + processedPrompt[0].content
|
|
1030
|
-
},
|
|
1031
|
-
...processedPrompt.slice(1)
|
|
1032
|
-
] : [
|
|
1033
|
-
{
|
|
1034
|
-
role: "system",
|
|
1035
|
-
content: systemPrompt
|
|
1036
|
-
},
|
|
1037
|
-
...processedPrompt
|
|
1038
|
-
];
|
|
1039
|
-
const baseReturnParams = {
|
|
1040
|
-
...params,
|
|
1041
|
-
prompt: finalPrompt,
|
|
1042
|
-
tools: [],
|
|
1043
|
-
toolChoice: void 0,
|
|
1044
|
-
providerOptions: {
|
|
1045
|
-
...params.providerOptions || {},
|
|
1046
|
-
toolCallMiddleware: {
|
|
1047
|
-
...params.providerOptions && typeof params.providerOptions === "object" && params.providerOptions.toolCallMiddleware || {},
|
|
1048
|
-
toolNames: functionTools.map((t) => t.name)
|
|
1049
|
-
}
|
|
1050
|
-
}
|
|
1051
|
-
};
|
|
1052
|
-
if (((_c = params.toolChoice) == null ? void 0 : _c.type) === "none") {
|
|
1053
|
-
throw new Error(
|
|
1054
|
-
"The 'none' toolChoice type is not supported by this middleware. Please use 'auto', 'required', or specify a tool name."
|
|
1055
|
-
);
|
|
1056
|
-
}
|
|
1057
|
-
if (((_d = params.toolChoice) == null ? void 0 : _d.type) === "tool") {
|
|
1058
|
-
const selectedToolName = params.toolChoice.toolName;
|
|
1059
|
-
const selectedTool = (_e = params.tools) == null ? void 0 : _e.find(
|
|
1060
|
-
(tool) => tool.type === "function" ? tool.name === selectedToolName : tool.id === selectedToolName
|
|
1061
|
-
);
|
|
1062
|
-
if (!selectedTool) {
|
|
1063
|
-
throw new Error(
|
|
1064
|
-
`Tool with name '${selectedToolName}' not found in params.tools.`
|
|
1065
|
-
);
|
|
1066
|
-
}
|
|
1067
|
-
if (selectedTool.type === "provider-defined") {
|
|
1068
|
-
throw new Error(
|
|
1069
|
-
"Provider-defined tools are not supported by this middleware. Please use custom tools."
|
|
1070
|
-
);
|
|
1071
|
-
}
|
|
1072
|
-
return {
|
|
1073
|
-
...baseReturnParams,
|
|
1074
|
-
responseFormat: {
|
|
1075
|
-
type: "json",
|
|
1076
|
-
schema: {
|
|
1077
|
-
type: "object",
|
|
1078
|
-
properties: {
|
|
1079
|
-
name: {
|
|
1080
|
-
const: selectedTool.name
|
|
1081
|
-
},
|
|
1082
|
-
arguments: selectedTool.inputSchema
|
|
1083
|
-
},
|
|
1084
|
-
required: ["name", "arguments"]
|
|
1085
|
-
},
|
|
1086
|
-
name: selectedTool.name,
|
|
1087
|
-
description: selectedTool.type === "function" && typeof selectedTool.description === "string" ? selectedTool.description : void 0
|
|
1088
|
-
},
|
|
1089
|
-
providerOptions: {
|
|
1090
|
-
...baseReturnParams.providerOptions || {},
|
|
1091
|
-
toolCallMiddleware: {
|
|
1092
|
-
...baseReturnParams.providerOptions && typeof baseReturnParams.providerOptions === "object" && baseReturnParams.providerOptions.toolCallMiddleware || {},
|
|
1093
|
-
toolChoice: params.toolChoice
|
|
1094
|
-
}
|
|
1095
|
-
}
|
|
1096
|
-
};
|
|
1097
|
-
}
|
|
1098
|
-
if (((_f = params.toolChoice) == null ? void 0 : _f.type) === "required") {
|
|
1099
|
-
if (!params.tools || params.tools.length === 0) {
|
|
1100
|
-
throw new Error(
|
|
1101
|
-
"Tool choice type 'required' is set, but no tools are provided in params.tools."
|
|
1102
|
-
);
|
|
1103
|
-
}
|
|
1104
|
-
return {
|
|
1105
|
-
...baseReturnParams,
|
|
1106
|
-
responseFormat: {
|
|
1107
|
-
type: "json",
|
|
1108
|
-
schema: createDynamicIfThenElseSchema(
|
|
1109
|
-
params.tools.filter((t) => t.type === "function")
|
|
1110
|
-
)
|
|
1111
|
-
},
|
|
1112
|
-
providerOptions: {
|
|
1113
|
-
...baseReturnParams.providerOptions || {},
|
|
1114
|
-
toolCallMiddleware: {
|
|
1115
|
-
...baseReturnParams.providerOptions && typeof baseReturnParams.providerOptions === "object" && baseReturnParams.providerOptions.toolCallMiddleware || {},
|
|
1116
|
-
toolChoice: { type: "required" }
|
|
1117
|
-
}
|
|
1118
|
-
}
|
|
1119
|
-
};
|
|
1120
|
-
}
|
|
1121
|
-
return baseReturnParams;
|
|
1122
|
-
}
|
|
1123
|
-
};
|
|
1124
|
-
}
|
|
1125
|
-
|
|
1126
|
-
// src/protocols/json-mix-protocol.ts
|
|
1127
|
-
var import_provider_utils3 = require("@ai-sdk/provider-utils");
|
|
1128
|
-
var jsonMixProtocol = ({
|
|
1129
|
-
toolCallStart = "<tool_call>",
|
|
1130
|
-
toolCallEnd = "</tool_call>",
|
|
1131
|
-
toolResponseStart = "<tool_response>",
|
|
1132
|
-
toolResponseEnd = "</tool_response>"
|
|
1133
|
-
} = {}) => ({
|
|
1134
|
-
formatTools({ tools, toolSystemPromptTemplate }) {
|
|
1135
|
-
const toolsForPrompt = (tools || []).filter((tool) => tool.type === "function").map((tool) => ({
|
|
1136
|
-
name: tool.name,
|
|
1137
|
-
description: tool.type === "function" && typeof tool.description === "string" ? tool.description : void 0,
|
|
1138
|
-
parameters: tool.inputSchema
|
|
1139
|
-
}));
|
|
1140
|
-
return toolSystemPromptTemplate(JSON.stringify(toolsForPrompt));
|
|
1141
|
-
},
|
|
1142
|
-
formatToolCall(toolCall) {
|
|
1143
|
-
let args = {};
|
|
1144
|
-
try {
|
|
1145
|
-
args = JSON.parse(toolCall.input);
|
|
1146
|
-
} catch (e) {
|
|
1147
|
-
args = toolCall.input;
|
|
1148
|
-
}
|
|
1149
|
-
return `${toolCallStart}${JSON.stringify({
|
|
1150
|
-
name: toolCall.toolName,
|
|
1151
|
-
arguments: args
|
|
1152
|
-
})}${toolCallEnd}`;
|
|
1153
|
-
},
|
|
1154
|
-
formatToolResponse(toolResult) {
|
|
1155
|
-
return `${toolResponseStart}${JSON.stringify({
|
|
1156
|
-
toolName: toolResult.toolName,
|
|
1157
|
-
result: toolResult.output
|
|
1158
|
-
})}${toolResponseEnd}`;
|
|
1159
|
-
},
|
|
1160
|
-
parseGeneratedText({ text, options }) {
|
|
1161
|
-
var _a;
|
|
1162
|
-
const startEsc = escapeRegExp(toolCallStart);
|
|
1163
|
-
const endEsc = escapeRegExp(toolCallEnd);
|
|
1164
|
-
const toolCallRegex = new RegExp(
|
|
1165
|
-
`${startEsc}([\0-\uFFFF]*?)${endEsc}`,
|
|
1166
|
-
"gs"
|
|
1167
|
-
);
|
|
1168
|
-
const processedElements = [];
|
|
1169
|
-
let currentIndex = 0;
|
|
1170
|
-
let match;
|
|
1171
|
-
while ((match = toolCallRegex.exec(text)) !== null) {
|
|
1172
|
-
const startIndex = match.index;
|
|
1173
|
-
const toolCallJson = match[1];
|
|
1174
|
-
if (startIndex > currentIndex) {
|
|
1175
|
-
const textSegment = text.substring(currentIndex, startIndex);
|
|
1176
|
-
if (textSegment.trim()) {
|
|
1177
|
-
processedElements.push({ type: "text", text: textSegment });
|
|
1178
|
-
}
|
|
1179
|
-
}
|
|
1180
|
-
if (toolCallJson) {
|
|
1181
|
-
try {
|
|
1182
|
-
const parsedToolCall = relaxed_json_exports.parse(toolCallJson);
|
|
1183
|
-
processedElements.push({
|
|
1184
|
-
type: "tool-call",
|
|
1185
|
-
toolCallId: (0, import_provider_utils3.generateId)(),
|
|
1186
|
-
toolName: parsedToolCall.name,
|
|
1187
|
-
input: JSON.stringify((_a = parsedToolCall.arguments) != null ? _a : {})
|
|
1188
|
-
});
|
|
1189
|
-
} catch (error) {
|
|
1190
|
-
if (options == null ? void 0 : options.onError) {
|
|
1191
|
-
options.onError(
|
|
1192
|
-
"Could not process JSON tool call, keeping original text.",
|
|
1193
|
-
{ toolCall: match[0], error }
|
|
1194
|
-
);
|
|
1195
|
-
}
|
|
1196
|
-
processedElements.push({ type: "text", text: match[0] });
|
|
1197
|
-
}
|
|
1198
|
-
}
|
|
1199
|
-
currentIndex = startIndex + match[0].length;
|
|
1200
|
-
}
|
|
1201
|
-
if (currentIndex < text.length) {
|
|
1202
|
-
const remainingText = text.substring(currentIndex);
|
|
1203
|
-
if (remainingText.trim()) {
|
|
1204
|
-
processedElements.push({ type: "text", text: remainingText });
|
|
1205
|
-
}
|
|
1161
|
+
if (currentIndex < text.length) {
|
|
1162
|
+
const remainingText = text.substring(currentIndex);
|
|
1163
|
+
if (remainingText.trim()) {
|
|
1164
|
+
processedElements.push({ type: "text", text: remainingText });
|
|
1165
|
+
}
|
|
1206
1166
|
}
|
|
1207
1167
|
return processedElements;
|
|
1208
1168
|
},
|
|
@@ -1218,7 +1178,7 @@ var jsonMixProtocol = ({
|
|
|
1218
1178
|
if (chunk.type === "finish") {
|
|
1219
1179
|
if (isInsideToolCall && buffer.length > 0) {
|
|
1220
1180
|
if (!currentTextId) {
|
|
1221
|
-
currentTextId = (0,
|
|
1181
|
+
currentTextId = (0, import_provider_utils2.generateId)();
|
|
1222
1182
|
controller.enqueue({ type: "text-start", id: currentTextId });
|
|
1223
1183
|
hasEmittedTextStart = true;
|
|
1224
1184
|
}
|
|
@@ -1230,7 +1190,7 @@ var jsonMixProtocol = ({
|
|
|
1230
1190
|
buffer = "";
|
|
1231
1191
|
} else if (!isInsideToolCall && buffer.length > 0) {
|
|
1232
1192
|
if (!currentTextId) {
|
|
1233
|
-
currentTextId = (0,
|
|
1193
|
+
currentTextId = (0, import_provider_utils2.generateId)();
|
|
1234
1194
|
controller.enqueue({ type: "text-start", id: currentTextId });
|
|
1235
1195
|
hasEmittedTextStart = true;
|
|
1236
1196
|
}
|
|
@@ -1247,7 +1207,7 @@ var jsonMixProtocol = ({
|
|
|
1247
1207
|
hasEmittedTextStart = false;
|
|
1248
1208
|
}
|
|
1249
1209
|
if (currentToolCallJson) {
|
|
1250
|
-
const errorId = (0,
|
|
1210
|
+
const errorId = (0, import_provider_utils2.generateId)();
|
|
1251
1211
|
controller.enqueue({ type: "text-start", id: errorId });
|
|
1252
1212
|
controller.enqueue({
|
|
1253
1213
|
type: "text-delta",
|
|
@@ -1275,7 +1235,7 @@ var jsonMixProtocol = ({
|
|
|
1275
1235
|
currentToolCallJson += text;
|
|
1276
1236
|
} else if (text.length > 0) {
|
|
1277
1237
|
if (!currentTextId) {
|
|
1278
|
-
currentTextId = (0,
|
|
1238
|
+
currentTextId = (0, import_provider_utils2.generateId)();
|
|
1279
1239
|
controller.enqueue({ type: "text-start", id: currentTextId });
|
|
1280
1240
|
hasEmittedTextStart = true;
|
|
1281
1241
|
}
|
|
@@ -1310,12 +1270,12 @@ var jsonMixProtocol = ({
|
|
|
1310
1270
|
}
|
|
1311
1271
|
controller.enqueue({
|
|
1312
1272
|
type: "tool-call",
|
|
1313
|
-
toolCallId: (0,
|
|
1273
|
+
toolCallId: (0, import_provider_utils2.generateId)(),
|
|
1314
1274
|
toolName: parsedToolCall.name,
|
|
1315
1275
|
input: JSON.stringify((_a = parsedToolCall.arguments) != null ? _a : {})
|
|
1316
1276
|
});
|
|
1317
1277
|
} catch (e) {
|
|
1318
|
-
const errorId = (0,
|
|
1278
|
+
const errorId = (0, import_provider_utils2.generateId)();
|
|
1319
1279
|
controller.enqueue({ type: "text-start", id: errorId });
|
|
1320
1280
|
controller.enqueue({
|
|
1321
1281
|
type: "text-delta",
|
|
@@ -1348,18 +1308,29 @@ var jsonMixProtocol = ({
|
|
|
1348
1308
|
}
|
|
1349
1309
|
}
|
|
1350
1310
|
});
|
|
1311
|
+
},
|
|
1312
|
+
extractToolCallSegments({ text }) {
|
|
1313
|
+
const startEsc = escapeRegExp(toolCallStart);
|
|
1314
|
+
const endEsc = escapeRegExp(toolCallEnd);
|
|
1315
|
+
const regex = new RegExp(`${startEsc}([\0-\uFFFF]*?)${endEsc}`, "gs");
|
|
1316
|
+
const segments = [];
|
|
1317
|
+
let m;
|
|
1318
|
+
while ((m = regex.exec(text)) != null) {
|
|
1319
|
+
segments.push(m[0]);
|
|
1320
|
+
}
|
|
1321
|
+
return segments;
|
|
1351
1322
|
}
|
|
1352
1323
|
});
|
|
1353
1324
|
|
|
1354
|
-
// src/protocols/xml-protocol.ts
|
|
1355
|
-
var
|
|
1325
|
+
// src/protocols/morph-xml-protocol.ts
|
|
1326
|
+
var import_provider_utils3 = require("@ai-sdk/provider-utils");
|
|
1356
1327
|
var import_fast_xml_parser = require("fast-xml-parser");
|
|
1357
|
-
var
|
|
1328
|
+
var morphXmlProtocol = () => ({
|
|
1358
1329
|
formatTools({ tools, toolSystemPromptTemplate }) {
|
|
1359
1330
|
const toolsForPrompt = (tools || []).map((tool) => ({
|
|
1360
1331
|
name: tool.name,
|
|
1361
1332
|
description: tool.description,
|
|
1362
|
-
parameters: tool.inputSchema
|
|
1333
|
+
parameters: unwrapJsonSchema(tool.inputSchema)
|
|
1363
1334
|
}));
|
|
1364
1335
|
return toolSystemPromptTemplate(JSON.stringify(toolsForPrompt));
|
|
1365
1336
|
},
|
|
@@ -1392,7 +1363,8 @@ var xmlProtocol = () => ({
|
|
|
1392
1363
|
return xmlContent;
|
|
1393
1364
|
},
|
|
1394
1365
|
parseGeneratedText({ text, tools, options }) {
|
|
1395
|
-
var _a, _b;
|
|
1366
|
+
var _a, _b, _c;
|
|
1367
|
+
const originalSchemas = (options == null ? void 0 : options.originalToolSchemas) || {};
|
|
1396
1368
|
const toolNames = tools.map((t) => t.name).filter((name) => name != null);
|
|
1397
1369
|
if (toolNames.length === 0) {
|
|
1398
1370
|
return [{ type: "text", text }];
|
|
@@ -1430,17 +1402,87 @@ var xmlProtocol = () => ({
|
|
|
1430
1402
|
if (v && typeof v === "object" && Object.prototype.hasOwnProperty.call(v, "#text")) {
|
|
1431
1403
|
val = v == null ? void 0 : v["#text"];
|
|
1432
1404
|
}
|
|
1405
|
+
if (Array.isArray(v)) {
|
|
1406
|
+
val = v.map((item) => {
|
|
1407
|
+
if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
|
|
1408
|
+
const textVal = item == null ? void 0 : item["#text"];
|
|
1409
|
+
return typeof textVal === "string" ? textVal.trim() : textVal;
|
|
1410
|
+
}
|
|
1411
|
+
return typeof item === "string" ? item.trim() : item;
|
|
1412
|
+
});
|
|
1413
|
+
} else if (v && typeof v === "object" && !Object.prototype.hasOwnProperty.call(v, "#text")) {
|
|
1414
|
+
const obj = v;
|
|
1415
|
+
const keys = Object.keys(obj);
|
|
1416
|
+
if (keys.length === 1 && keys[0] === "item") {
|
|
1417
|
+
const itemValue = obj.item;
|
|
1418
|
+
if (Array.isArray(itemValue)) {
|
|
1419
|
+
val = itemValue.map((item) => {
|
|
1420
|
+
if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
|
|
1421
|
+
const textVal = item == null ? void 0 : item["#text"];
|
|
1422
|
+
const trimmed2 = typeof textVal === "string" ? textVal.trim() : textVal;
|
|
1423
|
+
if (typeof trimmed2 === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed2)) {
|
|
1424
|
+
const num = Number(trimmed2);
|
|
1425
|
+
if (Number.isFinite(num)) return num;
|
|
1426
|
+
}
|
|
1427
|
+
return trimmed2;
|
|
1428
|
+
}
|
|
1429
|
+
const trimmed = typeof item === "string" ? item.trim() : item;
|
|
1430
|
+
if (typeof trimmed === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed)) {
|
|
1431
|
+
const num = Number(trimmed);
|
|
1432
|
+
if (Number.isFinite(num)) return num;
|
|
1433
|
+
}
|
|
1434
|
+
return trimmed;
|
|
1435
|
+
});
|
|
1436
|
+
} else {
|
|
1437
|
+
const trimmed = typeof itemValue === "string" ? itemValue.trim() : itemValue;
|
|
1438
|
+
if (typeof trimmed === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed)) {
|
|
1439
|
+
const num = Number(trimmed);
|
|
1440
|
+
if (Number.isFinite(num)) {
|
|
1441
|
+
val = num;
|
|
1442
|
+
} else {
|
|
1443
|
+
val = trimmed;
|
|
1444
|
+
}
|
|
1445
|
+
} else {
|
|
1446
|
+
val = trimmed;
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
} else {
|
|
1450
|
+
const isIndexedTuple = keys.length > 0 && keys.every((key) => /^\d+$/.test(key)) && (() => {
|
|
1451
|
+
const indices = keys.map((k2) => parseInt(k2)).sort((a, b) => a - b);
|
|
1452
|
+
return indices[0] === 0 && indices.every((val2, idx) => val2 === idx);
|
|
1453
|
+
})();
|
|
1454
|
+
if (isIndexedTuple) {
|
|
1455
|
+
const sortedKeys = keys.sort(
|
|
1456
|
+
(a, b) => parseInt(a) - parseInt(b)
|
|
1457
|
+
);
|
|
1458
|
+
val = sortedKeys.map((key) => {
|
|
1459
|
+
const item = obj[key];
|
|
1460
|
+
if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
|
|
1461
|
+
const textVal = item == null ? void 0 : item["#text"];
|
|
1462
|
+
return typeof textVal === "string" ? textVal.trim() : textVal;
|
|
1463
|
+
}
|
|
1464
|
+
return typeof item === "string" ? item.trim() : item;
|
|
1465
|
+
});
|
|
1466
|
+
} else {
|
|
1467
|
+
val = v;
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1433
1471
|
args[k] = typeof val === "string" ? val.trim() : val;
|
|
1434
1472
|
}
|
|
1473
|
+
const originalSchema = originalSchemas[toolName];
|
|
1474
|
+
const fallbackSchema = (_b = tools.find((t) => t.name === toolName)) == null ? void 0 : _b.inputSchema;
|
|
1475
|
+
const schema = originalSchema || fallbackSchema;
|
|
1476
|
+
const coercedArgs = coerceBySchema(args, schema);
|
|
1435
1477
|
processedElements.push({
|
|
1436
1478
|
type: "tool-call",
|
|
1437
|
-
toolCallId: (0,
|
|
1479
|
+
toolCallId: (0, import_provider_utils3.generateId)(),
|
|
1438
1480
|
toolName,
|
|
1439
|
-
input: JSON.stringify(
|
|
1481
|
+
input: JSON.stringify(coercedArgs)
|
|
1440
1482
|
});
|
|
1441
1483
|
} catch (error) {
|
|
1442
1484
|
const message = `Could not process XML tool call, keeping original text: ${match[0]}`;
|
|
1443
|
-
(
|
|
1485
|
+
(_c = options == null ? void 0 : options.onError) == null ? void 0 : _c.call(options, message, { toolCall: match[0], toolName, error });
|
|
1444
1486
|
processedElements.push({ type: "text", text: match[0] });
|
|
1445
1487
|
}
|
|
1446
1488
|
currentIndex = startIndex + match[0].length;
|
|
@@ -1454,6 +1496,7 @@ var xmlProtocol = () => ({
|
|
|
1454
1496
|
return processedElements;
|
|
1455
1497
|
},
|
|
1456
1498
|
createStreamParser({ tools, options }) {
|
|
1499
|
+
const originalSchemas = (options == null ? void 0 : options.originalToolSchemas) || {};
|
|
1457
1500
|
const toolNames = tools.map((t) => t.name).filter((name) => name != null);
|
|
1458
1501
|
let buffer = "";
|
|
1459
1502
|
let currentToolCall = null;
|
|
@@ -1462,7 +1505,7 @@ var xmlProtocol = () => ({
|
|
|
1462
1505
|
const content = text != null ? text : buffer;
|
|
1463
1506
|
if (content) {
|
|
1464
1507
|
if (!currentTextId) {
|
|
1465
|
-
currentTextId = (0,
|
|
1508
|
+
currentTextId = (0, import_provider_utils3.generateId)();
|
|
1466
1509
|
controller.enqueue({ type: "text-start", id: currentTextId });
|
|
1467
1510
|
}
|
|
1468
1511
|
controller.enqueue({
|
|
@@ -1481,7 +1524,7 @@ var xmlProtocol = () => ({
|
|
|
1481
1524
|
};
|
|
1482
1525
|
return new TransformStream({
|
|
1483
1526
|
transform(chunk, controller) {
|
|
1484
|
-
var _a;
|
|
1527
|
+
var _a, _b;
|
|
1485
1528
|
if (chunk.type !== "text-delta") {
|
|
1486
1529
|
if (buffer) flushText(controller);
|
|
1487
1530
|
controller.enqueue(chunk);
|
|
@@ -1510,14 +1553,86 @@ var xmlProtocol = () => ({
|
|
|
1510
1553
|
if (v && typeof v === "object" && Object.prototype.hasOwnProperty.call(v, "#text")) {
|
|
1511
1554
|
val = v == null ? void 0 : v["#text"];
|
|
1512
1555
|
}
|
|
1556
|
+
if (Array.isArray(v)) {
|
|
1557
|
+
val = v.map((item) => {
|
|
1558
|
+
if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
|
|
1559
|
+
const textVal = item == null ? void 0 : item["#text"];
|
|
1560
|
+
return typeof textVal === "string" ? textVal.trim() : textVal;
|
|
1561
|
+
}
|
|
1562
|
+
return typeof item === "string" ? item.trim() : item;
|
|
1563
|
+
});
|
|
1564
|
+
} else if (v && typeof v === "object" && !Object.prototype.hasOwnProperty.call(v, "#text")) {
|
|
1565
|
+
const obj = v;
|
|
1566
|
+
const keys = Object.keys(obj);
|
|
1567
|
+
if (keys.length === 1 && keys[0] === "item") {
|
|
1568
|
+
const itemValue = obj.item;
|
|
1569
|
+
if (Array.isArray(itemValue)) {
|
|
1570
|
+
val = itemValue.map((item) => {
|
|
1571
|
+
if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
|
|
1572
|
+
const textVal = item == null ? void 0 : item["#text"];
|
|
1573
|
+
const trimmed2 = typeof textVal === "string" ? textVal.trim() : textVal;
|
|
1574
|
+
if (typeof trimmed2 === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed2)) {
|
|
1575
|
+
const num = Number(trimmed2);
|
|
1576
|
+
if (Number.isFinite(num)) return num;
|
|
1577
|
+
}
|
|
1578
|
+
return trimmed2;
|
|
1579
|
+
}
|
|
1580
|
+
const trimmed = typeof item === "string" ? item.trim() : item;
|
|
1581
|
+
if (typeof trimmed === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed)) {
|
|
1582
|
+
const num = Number(trimmed);
|
|
1583
|
+
if (Number.isFinite(num)) return num;
|
|
1584
|
+
}
|
|
1585
|
+
return trimmed;
|
|
1586
|
+
});
|
|
1587
|
+
} else {
|
|
1588
|
+
const trimmed = typeof itemValue === "string" ? itemValue.trim() : itemValue;
|
|
1589
|
+
if (typeof trimmed === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed)) {
|
|
1590
|
+
const num = Number(trimmed);
|
|
1591
|
+
if (Number.isFinite(num)) {
|
|
1592
|
+
val = num;
|
|
1593
|
+
} else {
|
|
1594
|
+
val = trimmed;
|
|
1595
|
+
}
|
|
1596
|
+
} else {
|
|
1597
|
+
val = trimmed;
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1600
|
+
} else {
|
|
1601
|
+
const isIndexedTuple = keys.length > 0 && keys.every((key) => /^\d+$/.test(key)) && (() => {
|
|
1602
|
+
const indices = keys.map((k2) => parseInt(k2)).sort((a, b) => a - b);
|
|
1603
|
+
return indices[0] === 0 && indices.every((val2, idx) => val2 === idx);
|
|
1604
|
+
})();
|
|
1605
|
+
if (isIndexedTuple) {
|
|
1606
|
+
const sortedKeys = keys.sort(
|
|
1607
|
+
(a, b) => parseInt(a) - parseInt(b)
|
|
1608
|
+
);
|
|
1609
|
+
val = sortedKeys.map((key) => {
|
|
1610
|
+
const item = obj[key];
|
|
1611
|
+
if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
|
|
1612
|
+
const textVal = item == null ? void 0 : item["#text"];
|
|
1613
|
+
return typeof textVal === "string" ? textVal.trim() : textVal;
|
|
1614
|
+
}
|
|
1615
|
+
return typeof item === "string" ? item.trim() : item;
|
|
1616
|
+
});
|
|
1617
|
+
} else {
|
|
1618
|
+
val = v;
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
}
|
|
1513
1622
|
args[k] = typeof val === "string" ? val.trim() : val;
|
|
1514
1623
|
}
|
|
1624
|
+
const originalSchema = originalSchemas[currentToolCall.name];
|
|
1625
|
+
const fallbackSchema = (_b = tools.find(
|
|
1626
|
+
(t) => t.name === currentToolCall.name
|
|
1627
|
+
)) == null ? void 0 : _b.inputSchema;
|
|
1628
|
+
const toolSchema = originalSchema || fallbackSchema;
|
|
1629
|
+
const coercedArgs = coerceBySchema(args, toolSchema);
|
|
1515
1630
|
flushText(controller);
|
|
1516
1631
|
controller.enqueue({
|
|
1517
1632
|
type: "tool-call",
|
|
1518
|
-
toolCallId: (0,
|
|
1633
|
+
toolCallId: (0, import_provider_utils3.generateId)(),
|
|
1519
1634
|
toolName: currentToolCall.name,
|
|
1520
|
-
input: JSON.stringify(
|
|
1635
|
+
input: JSON.stringify(coercedArgs)
|
|
1521
1636
|
});
|
|
1522
1637
|
} catch (e) {
|
|
1523
1638
|
const originalCallText = `<${currentToolCall.name}>${toolContent}${endTag}`;
|
|
@@ -1575,11 +1690,578 @@ var xmlProtocol = () => ({
|
|
|
1575
1690
|
}
|
|
1576
1691
|
}
|
|
1577
1692
|
});
|
|
1693
|
+
},
|
|
1694
|
+
extractToolCallSegments({ text, tools }) {
|
|
1695
|
+
const toolNames = tools.map((t) => t.name).filter(Boolean);
|
|
1696
|
+
if (toolNames.length === 0) return [];
|
|
1697
|
+
const names = toolNames.map((n) => escapeRegExp(String(n))).join("|");
|
|
1698
|
+
if (!names) return [];
|
|
1699
|
+
const regex = new RegExp(`<(${names})>[\\s\\S]*?<\\/\\1>`, "g");
|
|
1700
|
+
const segments = [];
|
|
1701
|
+
let m;
|
|
1702
|
+
while ((m = regex.exec(text)) != null) {
|
|
1703
|
+
segments.push(m[0]);
|
|
1704
|
+
}
|
|
1705
|
+
return segments;
|
|
1578
1706
|
}
|
|
1579
1707
|
});
|
|
1580
1708
|
|
|
1581
|
-
// src/
|
|
1709
|
+
// src/generate-handler.ts
|
|
1710
|
+
var import_provider_utils4 = require("@ai-sdk/provider-utils");
|
|
1711
|
+
async function wrapGenerate({
|
|
1712
|
+
protocol,
|
|
1713
|
+
doGenerate,
|
|
1714
|
+
params
|
|
1715
|
+
}) {
|
|
1716
|
+
var _a, _b;
|
|
1717
|
+
if (isToolChoiceActive(params)) {
|
|
1718
|
+
const result2 = await doGenerate();
|
|
1719
|
+
let parsed2 = {};
|
|
1720
|
+
const first = (_a = result2.content) == null ? void 0 : _a[0];
|
|
1721
|
+
if (first && first.type === "text") {
|
|
1722
|
+
const debugLevel2 = getDebugLevel();
|
|
1723
|
+
if (debugLevel2 === "parse") {
|
|
1724
|
+
logRawChunk(first.text);
|
|
1725
|
+
}
|
|
1726
|
+
try {
|
|
1727
|
+
parsed2 = JSON.parse(first.text);
|
|
1728
|
+
} catch (error) {
|
|
1729
|
+
const options = extractOnErrorOption(params.providerOptions);
|
|
1730
|
+
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
1731
|
+
options,
|
|
1732
|
+
"Failed to parse toolChoice JSON from generated model output",
|
|
1733
|
+
{
|
|
1734
|
+
text: first.text,
|
|
1735
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1736
|
+
}
|
|
1737
|
+
);
|
|
1738
|
+
parsed2 = {};
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
const toolCall = {
|
|
1742
|
+
type: "tool-call",
|
|
1743
|
+
toolCallId: (0, import_provider_utils4.generateId)(),
|
|
1744
|
+
toolName: parsed2.name || "unknown",
|
|
1745
|
+
input: JSON.stringify(parsed2.arguments || {})
|
|
1746
|
+
};
|
|
1747
|
+
const debugLevelToolChoice = getDebugLevel();
|
|
1748
|
+
const originText = first && first.type === "text" ? first.text : "";
|
|
1749
|
+
if (debugLevelToolChoice === "parse") {
|
|
1750
|
+
logParsedSummary({ toolCalls: [toolCall], originalText: originText });
|
|
1751
|
+
}
|
|
1752
|
+
return {
|
|
1753
|
+
...result2,
|
|
1754
|
+
content: [toolCall]
|
|
1755
|
+
};
|
|
1756
|
+
}
|
|
1757
|
+
const result = await doGenerate();
|
|
1758
|
+
if (result.content.length === 0) {
|
|
1759
|
+
return result;
|
|
1760
|
+
}
|
|
1761
|
+
const parsed = result.content.flatMap((contentItem) => {
|
|
1762
|
+
var _a2;
|
|
1763
|
+
if (contentItem.type !== "text") {
|
|
1764
|
+
return [contentItem];
|
|
1765
|
+
}
|
|
1766
|
+
const debugLevel2 = getDebugLevel();
|
|
1767
|
+
if (debugLevel2 === "stream") {
|
|
1768
|
+
logRawChunk(contentItem.text);
|
|
1769
|
+
}
|
|
1770
|
+
return protocol.parseGeneratedText({
|
|
1771
|
+
text: contentItem.text,
|
|
1772
|
+
tools: getFunctionTools(params),
|
|
1773
|
+
options: {
|
|
1774
|
+
...extractOnErrorOption(params.providerOptions),
|
|
1775
|
+
...(_a2 = params.providerOptions) == null ? void 0 : _a2.toolCallMiddleware
|
|
1776
|
+
}
|
|
1777
|
+
});
|
|
1778
|
+
});
|
|
1779
|
+
const tools = getFunctionTools(params);
|
|
1780
|
+
const newContent = parsed.map(
|
|
1781
|
+
(part) => coerceToolCallInput(part, tools)
|
|
1782
|
+
);
|
|
1783
|
+
const debugLevel = getDebugLevel();
|
|
1784
|
+
if (debugLevel === "stream") {
|
|
1785
|
+
newContent.forEach((part) => logParsedChunk(part));
|
|
1786
|
+
}
|
|
1787
|
+
if (debugLevel === "parse") {
|
|
1788
|
+
const allText = result.content.filter(
|
|
1789
|
+
(c) => c.type === "text"
|
|
1790
|
+
).map((c) => c.text).join("\n\n");
|
|
1791
|
+
const segments = protocol.extractToolCallSegments ? protocol.extractToolCallSegments({ text: allText, tools }) : [];
|
|
1792
|
+
const originalText = segments.join("\n\n");
|
|
1793
|
+
const toolCalls = newContent.filter(
|
|
1794
|
+
(p) => p.type === "tool-call"
|
|
1795
|
+
);
|
|
1796
|
+
logParsedSummary({ toolCalls, originalText });
|
|
1797
|
+
}
|
|
1798
|
+
return {
|
|
1799
|
+
...result,
|
|
1800
|
+
content: newContent
|
|
1801
|
+
};
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
// src/stream-handler.ts
|
|
1582
1805
|
var import_provider_utils5 = require("@ai-sdk/provider-utils");
|
|
1806
|
+
async function wrapStream({
|
|
1807
|
+
protocol,
|
|
1808
|
+
doStream,
|
|
1809
|
+
doGenerate,
|
|
1810
|
+
params
|
|
1811
|
+
}) {
|
|
1812
|
+
var _a;
|
|
1813
|
+
if (isToolChoiceActive(params)) {
|
|
1814
|
+
return toolChoiceStream({
|
|
1815
|
+
doGenerate,
|
|
1816
|
+
options: extractOnErrorOption(params.providerOptions)
|
|
1817
|
+
});
|
|
1818
|
+
}
|
|
1819
|
+
const { stream, ...rest } = await doStream();
|
|
1820
|
+
const debugLevel = getDebugLevel();
|
|
1821
|
+
const tools = getFunctionTools(params);
|
|
1822
|
+
const options = {
|
|
1823
|
+
...extractOnErrorOption(params.providerOptions),
|
|
1824
|
+
...(_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware
|
|
1825
|
+
};
|
|
1826
|
+
if (debugLevel === "off") {
|
|
1827
|
+
return {
|
|
1828
|
+
stream: stream.pipeThrough(
|
|
1829
|
+
protocol.createStreamParser({
|
|
1830
|
+
tools,
|
|
1831
|
+
options
|
|
1832
|
+
})
|
|
1833
|
+
),
|
|
1834
|
+
...rest
|
|
1835
|
+
};
|
|
1836
|
+
}
|
|
1837
|
+
if (debugLevel === "stream") {
|
|
1838
|
+
const withRawTap2 = stream.pipeThrough(
|
|
1839
|
+
new TransformStream(
|
|
1840
|
+
{
|
|
1841
|
+
transform(part, controller) {
|
|
1842
|
+
logRawChunk(part);
|
|
1843
|
+
controller.enqueue(part);
|
|
1844
|
+
}
|
|
1845
|
+
}
|
|
1846
|
+
)
|
|
1847
|
+
);
|
|
1848
|
+
const parsed2 = withRawTap2.pipeThrough(
|
|
1849
|
+
protocol.createStreamParser({
|
|
1850
|
+
tools,
|
|
1851
|
+
options
|
|
1852
|
+
})
|
|
1853
|
+
);
|
|
1854
|
+
const withParsedTap = parsed2.pipeThrough(
|
|
1855
|
+
new TransformStream(
|
|
1856
|
+
{
|
|
1857
|
+
transform(part, controller) {
|
|
1858
|
+
logParsedChunk(part);
|
|
1859
|
+
controller.enqueue(part);
|
|
1860
|
+
}
|
|
1861
|
+
}
|
|
1862
|
+
)
|
|
1863
|
+
);
|
|
1864
|
+
return {
|
|
1865
|
+
stream: withParsedTap,
|
|
1866
|
+
...rest
|
|
1867
|
+
};
|
|
1868
|
+
}
|
|
1869
|
+
let fullRawText = "";
|
|
1870
|
+
const withRawTap = stream.pipeThrough(
|
|
1871
|
+
new TransformStream({
|
|
1872
|
+
transform(part, controller) {
|
|
1873
|
+
if (part.type === "text-delta") {
|
|
1874
|
+
const delta = part.delta;
|
|
1875
|
+
if (typeof delta === "string" && delta.length > 0) {
|
|
1876
|
+
fullRawText += delta;
|
|
1877
|
+
}
|
|
1878
|
+
}
|
|
1879
|
+
controller.enqueue(part);
|
|
1880
|
+
}
|
|
1881
|
+
})
|
|
1882
|
+
);
|
|
1883
|
+
const parsed = withRawTap.pipeThrough(
|
|
1884
|
+
protocol.createStreamParser({
|
|
1885
|
+
tools,
|
|
1886
|
+
options
|
|
1887
|
+
})
|
|
1888
|
+
);
|
|
1889
|
+
const withSummary = parsed.pipeThrough(
|
|
1890
|
+
new TransformStream({
|
|
1891
|
+
transform: /* @__PURE__ */ (() => {
|
|
1892
|
+
const parsedToolCalls = [];
|
|
1893
|
+
return (part, controller) => {
|
|
1894
|
+
if (part.type === "tool-call") {
|
|
1895
|
+
parsedToolCalls.push(part);
|
|
1896
|
+
}
|
|
1897
|
+
if (part.type === "finish") {
|
|
1898
|
+
try {
|
|
1899
|
+
const segments = protocol.extractToolCallSegments ? protocol.extractToolCallSegments({
|
|
1900
|
+
text: fullRawText,
|
|
1901
|
+
tools
|
|
1902
|
+
}) : [];
|
|
1903
|
+
const origin = segments.join("\n\n");
|
|
1904
|
+
logParsedSummary({
|
|
1905
|
+
toolCalls: parsedToolCalls,
|
|
1906
|
+
originalText: origin
|
|
1907
|
+
});
|
|
1908
|
+
} catch (e) {
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
controller.enqueue(part);
|
|
1912
|
+
};
|
|
1913
|
+
})()
|
|
1914
|
+
})
|
|
1915
|
+
);
|
|
1916
|
+
return {
|
|
1917
|
+
stream: withSummary,
|
|
1918
|
+
...rest
|
|
1919
|
+
};
|
|
1920
|
+
}
|
|
1921
|
+
async function toolChoiceStream({
|
|
1922
|
+
doGenerate,
|
|
1923
|
+
options
|
|
1924
|
+
}) {
|
|
1925
|
+
var _a, _b;
|
|
1926
|
+
const result = await doGenerate();
|
|
1927
|
+
let toolJson = {};
|
|
1928
|
+
if ((result == null ? void 0 : result.content) && result.content.length > 0 && ((_a = result.content[0]) == null ? void 0 : _a.type) === "text") {
|
|
1929
|
+
try {
|
|
1930
|
+
toolJson = JSON.parse(result.content[0].text);
|
|
1931
|
+
} catch (error) {
|
|
1932
|
+
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
1933
|
+
options,
|
|
1934
|
+
"Failed to parse toolChoice JSON from streamed model output",
|
|
1935
|
+
{
|
|
1936
|
+
text: result.content[0].text,
|
|
1937
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1938
|
+
}
|
|
1939
|
+
);
|
|
1940
|
+
toolJson = {};
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1943
|
+
const toolCallChunk = {
|
|
1944
|
+
type: "tool-call",
|
|
1945
|
+
toolCallId: (0, import_provider_utils5.generateId)(),
|
|
1946
|
+
toolName: toolJson.name || "unknown",
|
|
1947
|
+
input: JSON.stringify(toolJson.arguments || {})
|
|
1948
|
+
};
|
|
1949
|
+
const finishChunk = {
|
|
1950
|
+
type: "finish",
|
|
1951
|
+
usage: (result == null ? void 0 : result.usage) || // TODO: If possible, try to return a certain amount of LLM usage.
|
|
1952
|
+
{
|
|
1953
|
+
inputTokens: 0,
|
|
1954
|
+
outputTokens: 0,
|
|
1955
|
+
totalTokens: 0
|
|
1956
|
+
},
|
|
1957
|
+
finishReason: "tool-calls"
|
|
1958
|
+
};
|
|
1959
|
+
const stream = new ReadableStream({
|
|
1960
|
+
start(controller) {
|
|
1961
|
+
controller.enqueue(toolCallChunk);
|
|
1962
|
+
controller.enqueue(finishChunk);
|
|
1963
|
+
controller.close();
|
|
1964
|
+
}
|
|
1965
|
+
});
|
|
1966
|
+
const debugLevel = getDebugLevel();
|
|
1967
|
+
const firstText = (result == null ? void 0 : result.content) && result.content[0] && result.content[0].type === "text" && result.content[0].text || "";
|
|
1968
|
+
const streamWithSummary = debugLevel === "parse" ? stream.pipeThrough(
|
|
1969
|
+
new TransformStream({
|
|
1970
|
+
transform(part, controller) {
|
|
1971
|
+
if (part.type === "finish") {
|
|
1972
|
+
try {
|
|
1973
|
+
logParsedSummary({
|
|
1974
|
+
toolCalls: [toolCallChunk],
|
|
1975
|
+
originalText: typeof firstText === "string" ? firstText : ""
|
|
1976
|
+
});
|
|
1977
|
+
} catch (e) {
|
|
1978
|
+
}
|
|
1979
|
+
}
|
|
1980
|
+
controller.enqueue(part);
|
|
1981
|
+
}
|
|
1982
|
+
})
|
|
1983
|
+
) : stream;
|
|
1984
|
+
return {
|
|
1985
|
+
request: (result == null ? void 0 : result.request) || {},
|
|
1986
|
+
response: (result == null ? void 0 : result.response) || {},
|
|
1987
|
+
stream: streamWithSummary
|
|
1988
|
+
};
|
|
1989
|
+
}
|
|
1990
|
+
|
|
1991
|
+
// src/transform-handler.ts
|
|
1992
|
+
async function transformParams({
|
|
1993
|
+
params,
|
|
1994
|
+
protocol,
|
|
1995
|
+
toolSystemPromptTemplate
|
|
1996
|
+
}) {
|
|
1997
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1998
|
+
const resolvedProtocol = isProtocolFactory(protocol) ? protocol() : protocol;
|
|
1999
|
+
const functionTools = ((_a = params.tools) != null ? _a : []).filter(
|
|
2000
|
+
(t) => t.type === "function"
|
|
2001
|
+
);
|
|
2002
|
+
const systemPrompt = resolvedProtocol.formatTools({
|
|
2003
|
+
tools: functionTools,
|
|
2004
|
+
toolSystemPromptTemplate
|
|
2005
|
+
});
|
|
2006
|
+
const processedPrompt = convertToolPrompt(
|
|
2007
|
+
(_b = params.prompt) != null ? _b : [],
|
|
2008
|
+
resolvedProtocol,
|
|
2009
|
+
extractOnErrorOption(params.providerOptions)
|
|
2010
|
+
);
|
|
2011
|
+
const finalPrompt = ((_c = processedPrompt[0]) == null ? void 0 : _c.role) === "system" ? [
|
|
2012
|
+
{
|
|
2013
|
+
role: "system",
|
|
2014
|
+
content: systemPrompt + "\n\n" + processedPrompt[0].content
|
|
2015
|
+
},
|
|
2016
|
+
...processedPrompt.slice(1)
|
|
2017
|
+
] : [
|
|
2018
|
+
{
|
|
2019
|
+
role: "system",
|
|
2020
|
+
content: systemPrompt
|
|
2021
|
+
},
|
|
2022
|
+
...processedPrompt
|
|
2023
|
+
];
|
|
2024
|
+
const baseReturnParams = {
|
|
2025
|
+
...params,
|
|
2026
|
+
prompt: finalPrompt,
|
|
2027
|
+
tools: [],
|
|
2028
|
+
toolChoice: void 0,
|
|
2029
|
+
providerOptions: {
|
|
2030
|
+
...params.providerOptions || {},
|
|
2031
|
+
toolCallMiddleware: {
|
|
2032
|
+
...params.providerOptions && typeof params.providerOptions === "object" && params.providerOptions.toolCallMiddleware || {},
|
|
2033
|
+
// INTERNAL: used by the middleware to propagate the names of custom
|
|
2034
|
+
// function tools into downstream handlers (stream/generate) when
|
|
2035
|
+
// providers strip or ignore `params.tools`. Not a stable public API.
|
|
2036
|
+
toolNames: functionTools.map((t) => t.name)
|
|
2037
|
+
}
|
|
2038
|
+
}
|
|
2039
|
+
};
|
|
2040
|
+
if (((_d = params.toolChoice) == null ? void 0 : _d.type) === "none") {
|
|
2041
|
+
throw new Error(
|
|
2042
|
+
"The 'none' toolChoice type is not supported by this middleware. Please use 'auto', 'required', or specify a tool name."
|
|
2043
|
+
);
|
|
2044
|
+
}
|
|
2045
|
+
if (((_e = params.toolChoice) == null ? void 0 : _e.type) === "tool") {
|
|
2046
|
+
const selectedToolName = params.toolChoice.toolName;
|
|
2047
|
+
const providerDefinedMatch = ((_f = params.tools) != null ? _f : []).find((t) => {
|
|
2048
|
+
if (t.type === "function") return false;
|
|
2049
|
+
const anyTool = t;
|
|
2050
|
+
return anyTool.id === selectedToolName || anyTool.name === selectedToolName;
|
|
2051
|
+
});
|
|
2052
|
+
if (providerDefinedMatch) {
|
|
2053
|
+
throw new Error(
|
|
2054
|
+
"Provider-defined tools are not supported by this middleware. Please use custom tools."
|
|
2055
|
+
);
|
|
2056
|
+
}
|
|
2057
|
+
const selectedTool = ((_g = params.tools) != null ? _g : []).find(
|
|
2058
|
+
(t) => t.type === "function" && t.name === selectedToolName
|
|
2059
|
+
);
|
|
2060
|
+
if (!selectedTool) {
|
|
2061
|
+
throw new Error(
|
|
2062
|
+
`Tool with name '${selectedToolName}' not found in params.tools.`
|
|
2063
|
+
);
|
|
2064
|
+
}
|
|
2065
|
+
return {
|
|
2066
|
+
...baseReturnParams,
|
|
2067
|
+
responseFormat: {
|
|
2068
|
+
type: "json",
|
|
2069
|
+
schema: {
|
|
2070
|
+
type: "object",
|
|
2071
|
+
properties: {
|
|
2072
|
+
name: {
|
|
2073
|
+
const: selectedTool.name
|
|
2074
|
+
},
|
|
2075
|
+
arguments: selectedTool.inputSchema
|
|
2076
|
+
},
|
|
2077
|
+
required: ["name", "arguments"]
|
|
2078
|
+
},
|
|
2079
|
+
name: selectedTool.name,
|
|
2080
|
+
description: typeof selectedTool.description === "string" ? selectedTool.description : void 0
|
|
2081
|
+
},
|
|
2082
|
+
providerOptions: {
|
|
2083
|
+
...baseReturnParams.providerOptions || {},
|
|
2084
|
+
toolCallMiddleware: {
|
|
2085
|
+
...baseReturnParams.providerOptions && typeof baseReturnParams.providerOptions === "object" && baseReturnParams.providerOptions.toolCallMiddleware || {},
|
|
2086
|
+
// INTERNAL: used by the middleware to activate the tool-choice
|
|
2087
|
+
// fast-path in handlers. Not a stable public API.
|
|
2088
|
+
toolChoice: params.toolChoice
|
|
2089
|
+
}
|
|
2090
|
+
}
|
|
2091
|
+
};
|
|
2092
|
+
}
|
|
2093
|
+
if (((_h = params.toolChoice) == null ? void 0 : _h.type) === "required") {
|
|
2094
|
+
if (!params.tools || params.tools.length === 0) {
|
|
2095
|
+
throw new Error(
|
|
2096
|
+
"Tool choice type 'required' is set, but no tools are provided in params.tools."
|
|
2097
|
+
);
|
|
2098
|
+
}
|
|
2099
|
+
return {
|
|
2100
|
+
...baseReturnParams,
|
|
2101
|
+
responseFormat: {
|
|
2102
|
+
type: "json",
|
|
2103
|
+
schema: createDynamicIfThenElseSchema(functionTools)
|
|
2104
|
+
},
|
|
2105
|
+
providerOptions: {
|
|
2106
|
+
...baseReturnParams.providerOptions || {},
|
|
2107
|
+
toolCallMiddleware: {
|
|
2108
|
+
...baseReturnParams.providerOptions && typeof baseReturnParams.providerOptions === "object" && baseReturnParams.providerOptions.toolCallMiddleware || {},
|
|
2109
|
+
// INTERNAL: used by the middleware to activate the tool-choice
|
|
2110
|
+
// fast-path in handlers. Not a stable public API.
|
|
2111
|
+
toolChoice: { type: "required" }
|
|
2112
|
+
}
|
|
2113
|
+
}
|
|
2114
|
+
};
|
|
2115
|
+
}
|
|
2116
|
+
return baseReturnParams;
|
|
2117
|
+
}
|
|
2118
|
+
function convertToolPrompt(prompt, resolvedProtocol, providerOptions) {
|
|
2119
|
+
const processedPrompt = prompt.map((message) => {
|
|
2120
|
+
var _a;
|
|
2121
|
+
if (message.role === "assistant") {
|
|
2122
|
+
const newContent = [];
|
|
2123
|
+
for (const content of message.content) {
|
|
2124
|
+
if (isToolCallContent(content)) {
|
|
2125
|
+
newContent.push({
|
|
2126
|
+
type: "text",
|
|
2127
|
+
text: resolvedProtocol.formatToolCall(content)
|
|
2128
|
+
});
|
|
2129
|
+
} else if (content.type === "text") {
|
|
2130
|
+
newContent.push(content);
|
|
2131
|
+
} else if (content.type === "reasoning") {
|
|
2132
|
+
newContent.push(content);
|
|
2133
|
+
} else {
|
|
2134
|
+
const options = extractOnErrorOption(providerOptions);
|
|
2135
|
+
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
2136
|
+
options,
|
|
2137
|
+
"tool-call-middleware: unknown assistant content; stringifying for provider compatibility",
|
|
2138
|
+
{ content }
|
|
2139
|
+
);
|
|
2140
|
+
newContent.push({
|
|
2141
|
+
type: "text",
|
|
2142
|
+
text: JSON.stringify(content)
|
|
2143
|
+
});
|
|
2144
|
+
}
|
|
2145
|
+
}
|
|
2146
|
+
const onlyText = newContent.every((c) => c.type === "text");
|
|
2147
|
+
const condensedAssistant = onlyText ? [
|
|
2148
|
+
{
|
|
2149
|
+
type: "text",
|
|
2150
|
+
text: newContent.map((c) => c.text).join("\n")
|
|
2151
|
+
}
|
|
2152
|
+
] : newContent;
|
|
2153
|
+
return { role: "assistant", content: condensedAssistant };
|
|
2154
|
+
}
|
|
2155
|
+
if (message.role === "tool") {
|
|
2156
|
+
return {
|
|
2157
|
+
role: "user",
|
|
2158
|
+
// Map tool results to text response blocks, then condense into a single text block
|
|
2159
|
+
content: [
|
|
2160
|
+
{
|
|
2161
|
+
type: "text",
|
|
2162
|
+
text: message.content.map(
|
|
2163
|
+
(toolResult) => isToolResultPart(toolResult) ? resolvedProtocol.formatToolResponse(toolResult) : resolvedProtocol.formatToolResponse(
|
|
2164
|
+
toolResult
|
|
2165
|
+
)
|
|
2166
|
+
).join("\n")
|
|
2167
|
+
}
|
|
2168
|
+
]
|
|
2169
|
+
};
|
|
2170
|
+
}
|
|
2171
|
+
return message;
|
|
2172
|
+
});
|
|
2173
|
+
for (let i = 0; i < processedPrompt.length; i++) {
|
|
2174
|
+
const msg = processedPrompt[i];
|
|
2175
|
+
if (Array.isArray(msg.content)) {
|
|
2176
|
+
const allText = msg.content.every(
|
|
2177
|
+
(c) => (c == null ? void 0 : c.type) === "text"
|
|
2178
|
+
);
|
|
2179
|
+
if (allText && msg.content.length > 1) {
|
|
2180
|
+
const joinedText = msg.content.map((c) => c.text).join("\n");
|
|
2181
|
+
if (msg.role === "system") {
|
|
2182
|
+
processedPrompt[i] = {
|
|
2183
|
+
role: "system",
|
|
2184
|
+
content: joinedText
|
|
2185
|
+
};
|
|
2186
|
+
} else if (msg.role === "assistant") {
|
|
2187
|
+
processedPrompt[i] = {
|
|
2188
|
+
role: "assistant",
|
|
2189
|
+
content: [
|
|
2190
|
+
{
|
|
2191
|
+
type: "text",
|
|
2192
|
+
text: joinedText
|
|
2193
|
+
}
|
|
2194
|
+
]
|
|
2195
|
+
};
|
|
2196
|
+
} else {
|
|
2197
|
+
processedPrompt[i] = {
|
|
2198
|
+
role: "user",
|
|
2199
|
+
content: [
|
|
2200
|
+
{
|
|
2201
|
+
type: "text",
|
|
2202
|
+
text: joinedText
|
|
2203
|
+
}
|
|
2204
|
+
]
|
|
2205
|
+
};
|
|
2206
|
+
}
|
|
2207
|
+
}
|
|
2208
|
+
}
|
|
2209
|
+
}
|
|
2210
|
+
for (let i = processedPrompt.length - 1; i > 0; i--) {
|
|
2211
|
+
const current = processedPrompt[i];
|
|
2212
|
+
const prev = processedPrompt[i - 1];
|
|
2213
|
+
if (current.role === "user" && prev.role === "user") {
|
|
2214
|
+
const prevContent = prev.content.map((c) => c.type === "text" ? c.text : "").join("\n");
|
|
2215
|
+
const currentContent = current.content.map((c) => c.type === "text" ? c.text : "").join("\n");
|
|
2216
|
+
processedPrompt[i - 1] = {
|
|
2217
|
+
role: "user",
|
|
2218
|
+
content: [{ type: "text", text: prevContent + "\n" + currentContent }]
|
|
2219
|
+
};
|
|
2220
|
+
processedPrompt.splice(i, 1);
|
|
2221
|
+
}
|
|
2222
|
+
}
|
|
2223
|
+
return processedPrompt;
|
|
2224
|
+
}
|
|
2225
|
+
|
|
2226
|
+
// src/tool-call-middleware.ts
|
|
2227
|
+
function createToolMiddleware({
|
|
2228
|
+
protocol,
|
|
2229
|
+
toolSystemPromptTemplate
|
|
2230
|
+
}) {
|
|
2231
|
+
const resolvedProtocol = isProtocolFactory(protocol) ? protocol() : protocol;
|
|
2232
|
+
return {
|
|
2233
|
+
middlewareVersion: "v2",
|
|
2234
|
+
wrapStream: async ({ doStream, doGenerate, params }) => {
|
|
2235
|
+
if (isToolChoiceActive(params)) {
|
|
2236
|
+
return toolChoiceStream({
|
|
2237
|
+
doGenerate,
|
|
2238
|
+
options: extractOnErrorOption(params.providerOptions)
|
|
2239
|
+
});
|
|
2240
|
+
} else {
|
|
2241
|
+
return wrapStream({
|
|
2242
|
+
protocol: resolvedProtocol,
|
|
2243
|
+
doStream,
|
|
2244
|
+
doGenerate,
|
|
2245
|
+
params
|
|
2246
|
+
});
|
|
2247
|
+
}
|
|
2248
|
+
},
|
|
2249
|
+
wrapGenerate: async ({ doGenerate, params }) => wrapGenerate({
|
|
2250
|
+
protocol: resolvedProtocol,
|
|
2251
|
+
doGenerate,
|
|
2252
|
+
params
|
|
2253
|
+
}),
|
|
2254
|
+
transformParams: async ({
|
|
2255
|
+
params
|
|
2256
|
+
}) => {
|
|
2257
|
+
return transformParams({
|
|
2258
|
+
protocol: resolvedProtocol,
|
|
2259
|
+
toolSystemPromptTemplate,
|
|
2260
|
+
params
|
|
2261
|
+
});
|
|
2262
|
+
}
|
|
2263
|
+
};
|
|
2264
|
+
}
|
|
1583
2265
|
|
|
1584
2266
|
// src/index.ts
|
|
1585
2267
|
var gemmaToolMiddleware = createToolMiddleware({
|
|
@@ -1587,8 +2269,9 @@ var gemmaToolMiddleware = createToolMiddleware({
|
|
|
1587
2269
|
// Customize the tool call delimiters to use markdown code fences
|
|
1588
2270
|
{
|
|
1589
2271
|
toolCallStart: "```tool_call\n",
|
|
1590
|
-
|
|
1591
|
-
//
|
|
2272
|
+
// TODO: Support specifying multiple possible tags,
|
|
2273
|
+
// e.g., for gemma, it would be nice to be able to set both `` and ``` at the same time.
|
|
2274
|
+
toolCallEnd: "\n```",
|
|
1592
2275
|
toolResponseStart: "```tool_response\n",
|
|
1593
2276
|
toolResponseEnd: "\n```"
|
|
1594
2277
|
}
|
|
@@ -1619,15 +2302,16 @@ For each function call return a json object with function name and arguments wit
|
|
|
1619
2302
|
}
|
|
1620
2303
|
});
|
|
1621
2304
|
var xmlToolMiddleware = createToolMiddleware({
|
|
1622
|
-
protocol:
|
|
2305
|
+
protocol: morphXmlProtocol,
|
|
1623
2306
|
toolSystemPromptTemplate(tools) {
|
|
1624
|
-
return `You are
|
|
2307
|
+
return `You are a function calling AI model.
|
|
1625
2308
|
You are provided with function signatures within <tools></tools> XML tags.
|
|
1626
2309
|
You may call one or more functions to assist with the user query.
|
|
1627
2310
|
Don't make assumptions about what values to plug into functions.
|
|
1628
2311
|
Here are the available tools: <tools>${tools}</tools>
|
|
1629
|
-
For
|
|
1630
|
-
|
|
2312
|
+
For a function call, return exactly one XML element whose tag name matches the tool's name, and nothing else.
|
|
2313
|
+
When an argument is an array, write each item inside a single element on one line separated by commas (or provide a JSON-like list). When an argument is an object, provide a JSON-like value.
|
|
2314
|
+
Examples:
|
|
1631
2315
|
<get_weather>
|
|
1632
2316
|
<location>
|
|
1633
2317
|
San Fransisco
|
|
@@ -1641,7 +2325,7 @@ San Fransisco
|
|
|
1641
2325
|
gemmaToolMiddleware,
|
|
1642
2326
|
hermesToolMiddleware,
|
|
1643
2327
|
jsonMixProtocol,
|
|
1644
|
-
|
|
2328
|
+
morphXmlProtocol,
|
|
1645
2329
|
xmlToolMiddleware
|
|
1646
2330
|
});
|
|
1647
2331
|
//# sourceMappingURL=index.cjs.map
|