@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.js
CHANGED
|
@@ -4,7 +4,10 @@ var __export = (target, all) => {
|
|
|
4
4
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
5
|
};
|
|
6
6
|
|
|
7
|
-
// src/
|
|
7
|
+
// src/protocols/dummy-protocol.ts
|
|
8
|
+
import { generateId } from "@ai-sdk/provider-utils";
|
|
9
|
+
|
|
10
|
+
// src/protocols/json-mix-protocol.ts
|
|
8
11
|
import { generateId as generateId2 } from "@ai-sdk/provider-utils";
|
|
9
12
|
|
|
10
13
|
// src/utils/dynamic-tool-schema.ts
|
|
@@ -81,6 +84,11 @@ function getPotentialStartIndex(text, searchedText) {
|
|
|
81
84
|
return null;
|
|
82
85
|
}
|
|
83
86
|
|
|
87
|
+
// src/utils/regex.ts
|
|
88
|
+
function escapeRegExp(literal) {
|
|
89
|
+
return literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
90
|
+
}
|
|
91
|
+
|
|
84
92
|
// src/utils/relaxed-json.ts
|
|
85
93
|
var relaxed_json_exports = {};
|
|
86
94
|
__export(relaxed_json_exports, {
|
|
@@ -415,7 +423,6 @@ function appendPair(state, obj, key, value) {
|
|
|
415
423
|
}
|
|
416
424
|
function parsePair(tokens, state, obj) {
|
|
417
425
|
let token = skipPunctuation(tokens, state, [":", "string", "number", "atom"]);
|
|
418
|
-
let key;
|
|
419
426
|
let value;
|
|
420
427
|
if (token.type !== "string") {
|
|
421
428
|
raiseUnexpected(state, token, "string key");
|
|
@@ -465,7 +472,7 @@ function parsePair(tokens, state, obj) {
|
|
|
465
472
|
}
|
|
466
473
|
}
|
|
467
474
|
checkDuplicates(state, obj, token);
|
|
468
|
-
key = String(token.value);
|
|
475
|
+
const key = String(token.value);
|
|
469
476
|
skipColon(tokens, state);
|
|
470
477
|
value = parseAny(tokens, state);
|
|
471
478
|
appendPair(state, obj, key, value);
|
|
@@ -636,7 +643,10 @@ function parse(text, optsOrReviver) {
|
|
|
636
643
|
if (!options.relaxed && !options.warnings && !options.tolerant) {
|
|
637
644
|
if (!options.duplicate) {
|
|
638
645
|
} else {
|
|
639
|
-
return JSON.parse(
|
|
646
|
+
return JSON.parse(
|
|
647
|
+
text,
|
|
648
|
+
options.reviver
|
|
649
|
+
);
|
|
640
650
|
}
|
|
641
651
|
}
|
|
642
652
|
const lexerToUse = options.relaxed ? lexer : strictLexer;
|
|
@@ -656,7 +666,7 @@ function parse(text, optsOrReviver) {
|
|
|
656
666
|
};
|
|
657
667
|
return parseAny(tokens, state, true);
|
|
658
668
|
} else {
|
|
659
|
-
|
|
669
|
+
tokens.reduce((str, token) => {
|
|
660
670
|
return str + token.match;
|
|
661
671
|
}, "");
|
|
662
672
|
if (!options.relaxed && !options.warnings && !options.tolerant && options.duplicate) {
|
|
@@ -680,8 +690,11 @@ function parse(text, optsOrReviver) {
|
|
|
680
690
|
} else {
|
|
681
691
|
tokens = lexer(text);
|
|
682
692
|
tokens = stripTrailingComma(tokens);
|
|
683
|
-
const
|
|
684
|
-
return JSON.parse(
|
|
693
|
+
const newtext = tokens.reduce((str, token) => str + token.match, "");
|
|
694
|
+
return JSON.parse(
|
|
695
|
+
newtext,
|
|
696
|
+
options.reviver
|
|
697
|
+
);
|
|
685
698
|
}
|
|
686
699
|
}
|
|
687
700
|
}
|
|
@@ -709,22 +722,300 @@ function stringify(obj) {
|
|
|
709
722
|
return "null";
|
|
710
723
|
}
|
|
711
724
|
|
|
712
|
-
// src/utils/
|
|
713
|
-
function
|
|
714
|
-
|
|
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);
|
|
715
927
|
}
|
|
716
928
|
|
|
717
|
-
// src/utils/
|
|
718
|
-
function
|
|
719
|
-
|
|
720
|
-
(
|
|
929
|
+
// src/utils/debug.ts
|
|
930
|
+
function normalizeBooleanString(value) {
|
|
931
|
+
const normalized = value.trim().toLowerCase();
|
|
932
|
+
if (normalized === "1" || normalized === "true" || normalized === "yes") {
|
|
933
|
+
return true;
|
|
934
|
+
}
|
|
935
|
+
if (normalized === "0" || normalized === "false" || normalized === "no") {
|
|
936
|
+
return false;
|
|
937
|
+
}
|
|
938
|
+
return void 0;
|
|
721
939
|
}
|
|
722
|
-
function
|
|
723
|
-
const
|
|
724
|
-
|
|
940
|
+
function getDebugLevel() {
|
|
941
|
+
const envVal = typeof process !== "undefined" && process.env && process.env.DEBUG_PARSER_MW || "off";
|
|
942
|
+
const envLower = String(envVal).toLowerCase();
|
|
943
|
+
if (envLower === "stream" || envLower === "parse" || envLower === "off") {
|
|
944
|
+
return envLower;
|
|
945
|
+
}
|
|
946
|
+
const boolEnv = normalizeBooleanString(envLower);
|
|
947
|
+
if (boolEnv === true) return "stream";
|
|
948
|
+
if (envLower === "2") return "parse";
|
|
949
|
+
return "off";
|
|
725
950
|
}
|
|
726
|
-
function
|
|
727
|
-
return
|
|
951
|
+
function color(code) {
|
|
952
|
+
return (text) => `\x1B[${code}m${text}\x1B[0m`;
|
|
953
|
+
}
|
|
954
|
+
var cGray = color(90);
|
|
955
|
+
var cYellow = color(33);
|
|
956
|
+
var cCyan = color(36);
|
|
957
|
+
var cBgBlue = color(44);
|
|
958
|
+
var cBgGreen = color(42);
|
|
959
|
+
var cInverse = color(7);
|
|
960
|
+
var cUnderline = color(4);
|
|
961
|
+
var cBold = color(1);
|
|
962
|
+
function safeStringify(value) {
|
|
963
|
+
try {
|
|
964
|
+
return `
|
|
965
|
+
${typeof value === "string" ? value : JSON.stringify(value, null, 2)}`;
|
|
966
|
+
} catch (e) {
|
|
967
|
+
return String(value);
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
function logRawChunk(part) {
|
|
971
|
+
console.log(cGray("[debug:mw:raw]"), cYellow(safeStringify(part)));
|
|
972
|
+
}
|
|
973
|
+
function logParsedChunk(part) {
|
|
974
|
+
console.log(cGray("[debug:mw:out]"), cCyan(safeStringify(part)));
|
|
975
|
+
}
|
|
976
|
+
function logParsedSummary({
|
|
977
|
+
toolCalls,
|
|
978
|
+
originalText
|
|
979
|
+
}) {
|
|
980
|
+
if (originalText) {
|
|
981
|
+
const style = (() => {
|
|
982
|
+
const envVal = typeof process !== "undefined" && process.env && process.env.DEBUG_PARSER_MW_STYLE || "bg";
|
|
983
|
+
const normalized = String(envVal).trim().toLowerCase();
|
|
984
|
+
if (normalized === "inverse" || normalized === "invert")
|
|
985
|
+
return "inverse";
|
|
986
|
+
if (normalized === "underline" || normalized === "ul")
|
|
987
|
+
return "underline";
|
|
988
|
+
if (normalized === "bold") return "bold";
|
|
989
|
+
if (normalized === "bg" || normalized === "background")
|
|
990
|
+
return "bg";
|
|
991
|
+
const asBool = normalizeBooleanString(normalized);
|
|
992
|
+
if (asBool === true) return "bg";
|
|
993
|
+
return "bg";
|
|
994
|
+
})();
|
|
995
|
+
const highlight = style === "inverse" ? cInverse : style === "underline" ? cUnderline : style === "bold" ? cBold : style === "bg" ? cBgGreen : cYellow;
|
|
996
|
+
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);
|
|
997
|
+
console.log(cGray("[debug:mw:origin]"), `
|
|
998
|
+
${rendered}`);
|
|
999
|
+
}
|
|
1000
|
+
if (toolCalls.length > 0) {
|
|
1001
|
+
const styledSummary = safeStringify(toolCalls).split(/\r?\n/).map((line) => line.length ? cBgBlue(line) : line).join("\n");
|
|
1002
|
+
console.log(cGray("[debug:mw:summary]"), styledSummary);
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
// src/utils/on-error.ts
|
|
1007
|
+
function extractOnErrorOption(providerOptions) {
|
|
1008
|
+
var _a;
|
|
1009
|
+
if (providerOptions && typeof providerOptions === "object") {
|
|
1010
|
+
const onError = (_a = providerOptions.toolCallMiddleware) == null ? void 0 : _a.onError;
|
|
1011
|
+
return onError ? { onError } : void 0;
|
|
1012
|
+
}
|
|
1013
|
+
return void 0;
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
// src/utils/protocol.ts
|
|
1017
|
+
function isProtocolFactory(protocol) {
|
|
1018
|
+
return typeof protocol === "function";
|
|
728
1019
|
}
|
|
729
1020
|
|
|
730
1021
|
// src/utils/tools.ts
|
|
@@ -735,7 +1026,11 @@ function isToolChoiceActive(params) {
|
|
|
735
1026
|
}
|
|
736
1027
|
function getFunctionTools(params) {
|
|
737
1028
|
var _a, _b;
|
|
738
|
-
const
|
|
1029
|
+
const functionTools = ((_a = params.tools) != null ? _a : []).filter(
|
|
1030
|
+
(t) => t.type === "function"
|
|
1031
|
+
);
|
|
1032
|
+
if (functionTools.length > 0) return functionTools;
|
|
1033
|
+
const rawToolNames = params.providerOptions && typeof params.providerOptions === "object" && ((_b = params.providerOptions.toolCallMiddleware) == null ? void 0 : _b.toolNames) || [];
|
|
739
1034
|
const toStringArray = (val) => Array.isArray(val) ? val.filter(
|
|
740
1035
|
(item) => typeof item === "string"
|
|
741
1036
|
) : [];
|
|
@@ -748,436 +1043,101 @@ function getFunctionTools(params) {
|
|
|
748
1043
|
inputSchema: { type: "object" }
|
|
749
1044
|
}));
|
|
750
1045
|
}
|
|
751
|
-
return
|
|
752
|
-
(t) => t.type === "function"
|
|
753
|
-
);
|
|
1046
|
+
return [];
|
|
754
1047
|
}
|
|
755
1048
|
|
|
756
|
-
// src/utils/
|
|
757
|
-
function
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
return
|
|
1049
|
+
// src/utils/type-guards.ts
|
|
1050
|
+
function isToolCallContent(content) {
|
|
1051
|
+
return content.type === "tool-call" && typeof content.toolName === "string" && // input may be a JSON string or an already-parsed object depending on provider/runtime
|
|
1052
|
+
(typeof content.input === "string" || typeof content.input === "object");
|
|
1053
|
+
}
|
|
1054
|
+
function isToolResultPart(content) {
|
|
1055
|
+
const c = content;
|
|
1056
|
+
return !!c && c.type === "tool-result" && typeof c.toolName === "string" && typeof c.toolCallId === "string" && "output" in c;
|
|
1057
|
+
}
|
|
1058
|
+
function hasInputProperty(obj) {
|
|
1059
|
+
return typeof obj === "object" && obj !== null && "input" in obj;
|
|
764
1060
|
}
|
|
765
1061
|
|
|
766
|
-
// src/
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
1062
|
+
// src/protocols/json-mix-protocol.ts
|
|
1063
|
+
var jsonMixProtocol = ({
|
|
1064
|
+
toolCallStart = "<tool_call>",
|
|
1065
|
+
toolCallEnd = "</tool_call>",
|
|
1066
|
+
toolResponseStart = "<tool_response>",
|
|
1067
|
+
toolResponseEnd = "</tool_response>"
|
|
1068
|
+
} = {}) => ({
|
|
1069
|
+
formatTools({ tools, toolSystemPromptTemplate }) {
|
|
1070
|
+
const toolsForPrompt = (tools || []).filter((tool) => tool.type === "function").map((tool) => ({
|
|
1071
|
+
name: tool.name,
|
|
1072
|
+
description: tool.type === "function" && typeof tool.description === "string" ? tool.description : void 0,
|
|
1073
|
+
parameters: tool.inputSchema
|
|
1074
|
+
}));
|
|
1075
|
+
return toolSystemPromptTemplate(JSON.stringify(toolsForPrompt));
|
|
1076
|
+
},
|
|
1077
|
+
formatToolCall(toolCall) {
|
|
1078
|
+
let args = {};
|
|
776
1079
|
try {
|
|
777
|
-
|
|
778
|
-
} catch (
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
1080
|
+
args = JSON.parse(toolCall.input);
|
|
1081
|
+
} catch (e) {
|
|
1082
|
+
args = toolCall.input;
|
|
1083
|
+
}
|
|
1084
|
+
return `${toolCallStart}${JSON.stringify({
|
|
1085
|
+
name: toolCall.toolName,
|
|
1086
|
+
arguments: args
|
|
1087
|
+
})}${toolCallEnd}`;
|
|
1088
|
+
},
|
|
1089
|
+
formatToolResponse(toolResult) {
|
|
1090
|
+
return `${toolResponseStart}${JSON.stringify({
|
|
1091
|
+
toolName: toolResult.toolName,
|
|
1092
|
+
result: toolResult.output
|
|
1093
|
+
})}${toolResponseEnd}`;
|
|
1094
|
+
},
|
|
1095
|
+
parseGeneratedText({ text, options }) {
|
|
1096
|
+
var _a;
|
|
1097
|
+
const startEsc = escapeRegExp(toolCallStart);
|
|
1098
|
+
const endEsc = escapeRegExp(toolCallEnd);
|
|
1099
|
+
const toolCallRegex = new RegExp(
|
|
1100
|
+
`${startEsc}([\0-\uFFFF]*?)${endEsc}`,
|
|
1101
|
+
"gs"
|
|
1102
|
+
);
|
|
1103
|
+
const processedElements = [];
|
|
1104
|
+
let currentIndex = 0;
|
|
1105
|
+
let match;
|
|
1106
|
+
while ((match = toolCallRegex.exec(text)) !== null) {
|
|
1107
|
+
const startIndex = match.index;
|
|
1108
|
+
const toolCallJson = match[1];
|
|
1109
|
+
if (startIndex > currentIndex) {
|
|
1110
|
+
const textSegment = text.substring(currentIndex, startIndex);
|
|
1111
|
+
if (textSegment.trim()) {
|
|
1112
|
+
processedElements.push({ type: "text", text: textSegment });
|
|
785
1113
|
}
|
|
786
|
-
|
|
787
|
-
|
|
1114
|
+
}
|
|
1115
|
+
if (toolCallJson) {
|
|
1116
|
+
try {
|
|
1117
|
+
const parsedToolCall = relaxed_json_exports.parse(toolCallJson);
|
|
1118
|
+
processedElements.push({
|
|
1119
|
+
type: "tool-call",
|
|
1120
|
+
toolCallId: generateId2(),
|
|
1121
|
+
toolName: parsedToolCall.name,
|
|
1122
|
+
input: JSON.stringify((_a = parsedToolCall.arguments) != null ? _a : {})
|
|
1123
|
+
});
|
|
1124
|
+
} catch (error) {
|
|
1125
|
+
if (options == null ? void 0 : options.onError) {
|
|
1126
|
+
options.onError(
|
|
1127
|
+
"Could not process JSON tool call, keeping original text.",
|
|
1128
|
+
{ toolCall: match[0], error }
|
|
1129
|
+
);
|
|
1130
|
+
}
|
|
1131
|
+
processedElements.push({ type: "text", text: match[0] });
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
currentIndex = startIndex + match[0].length;
|
|
788
1135
|
}
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
input: JSON.stringify(toolJson.arguments || {})
|
|
795
|
-
};
|
|
796
|
-
const finishChunk = {
|
|
797
|
-
type: "finish",
|
|
798
|
-
usage: (result == null ? void 0 : result.usage) || // TODO: If possible, try to return a certain amount of LLM usage.
|
|
799
|
-
{
|
|
800
|
-
inputTokens: 0,
|
|
801
|
-
outputTokens: 0,
|
|
802
|
-
totalTokens: 0
|
|
803
|
-
},
|
|
804
|
-
finishReason: "tool-calls"
|
|
805
|
-
};
|
|
806
|
-
const stream = new ReadableStream({
|
|
807
|
-
start(controller) {
|
|
808
|
-
controller.enqueue(toolCallChunk);
|
|
809
|
-
controller.enqueue(finishChunk);
|
|
810
|
-
controller.close();
|
|
811
|
-
}
|
|
812
|
-
});
|
|
813
|
-
return {
|
|
814
|
-
request: (result == null ? void 0 : result.request) || {},
|
|
815
|
-
response: (result == null ? void 0 : result.response) || {},
|
|
816
|
-
stream
|
|
817
|
-
};
|
|
818
|
-
}
|
|
819
|
-
|
|
820
|
-
// src/tool-call-middleware.ts
|
|
821
|
-
function isProtocolFactory(protocol) {
|
|
822
|
-
return typeof protocol === "function";
|
|
823
|
-
}
|
|
824
|
-
function createToolMiddleware({
|
|
825
|
-
protocol,
|
|
826
|
-
toolSystemPromptTemplate
|
|
827
|
-
}) {
|
|
828
|
-
const resolvedProtocol = isProtocolFactory(protocol) ? protocol() : protocol;
|
|
829
|
-
return {
|
|
830
|
-
middlewareVersion: "v2",
|
|
831
|
-
wrapStream: async ({ doStream, doGenerate, params }) => {
|
|
832
|
-
if (isToolChoiceActive(params)) {
|
|
833
|
-
return toolChoiceStream({
|
|
834
|
-
doGenerate,
|
|
835
|
-
options: extractOnErrorOption(params.providerOptions)
|
|
836
|
-
});
|
|
837
|
-
}
|
|
838
|
-
const { stream, ...rest } = await doStream();
|
|
839
|
-
return {
|
|
840
|
-
stream: stream.pipeThrough(
|
|
841
|
-
resolvedProtocol.createStreamParser({
|
|
842
|
-
tools: getFunctionTools(params),
|
|
843
|
-
options: extractOnErrorOption(params.providerOptions)
|
|
844
|
-
})
|
|
845
|
-
),
|
|
846
|
-
...rest
|
|
847
|
-
};
|
|
848
|
-
},
|
|
849
|
-
wrapGenerate: async ({ doGenerate, params }) => {
|
|
850
|
-
var _a, _b;
|
|
851
|
-
if (isToolChoiceActive(params)) {
|
|
852
|
-
const result2 = await doGenerate();
|
|
853
|
-
let parsed = {};
|
|
854
|
-
const first = (_a = result2.content) == null ? void 0 : _a[0];
|
|
855
|
-
if (first && first.type === "text") {
|
|
856
|
-
try {
|
|
857
|
-
parsed = JSON.parse(first.text);
|
|
858
|
-
} catch (error) {
|
|
859
|
-
const options = extractOnErrorOption(params.providerOptions);
|
|
860
|
-
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
861
|
-
options,
|
|
862
|
-
"Failed to parse toolChoice JSON from generated model output",
|
|
863
|
-
{
|
|
864
|
-
text: first.text,
|
|
865
|
-
error: error instanceof Error ? error.message : String(error)
|
|
866
|
-
}
|
|
867
|
-
);
|
|
868
|
-
parsed = {};
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
return {
|
|
872
|
-
...result2,
|
|
873
|
-
content: [
|
|
874
|
-
{
|
|
875
|
-
type: "tool-call",
|
|
876
|
-
toolCallId: generateId2(),
|
|
877
|
-
toolName: parsed.name || "unknown",
|
|
878
|
-
input: JSON.stringify(parsed.arguments || {})
|
|
879
|
-
}
|
|
880
|
-
]
|
|
881
|
-
};
|
|
882
|
-
}
|
|
883
|
-
const result = await doGenerate();
|
|
884
|
-
if (result.content.length === 0) {
|
|
885
|
-
return result;
|
|
886
|
-
}
|
|
887
|
-
const newContent = result.content.flatMap((contentItem) => {
|
|
888
|
-
if (contentItem.type !== "text") {
|
|
889
|
-
return [contentItem];
|
|
890
|
-
}
|
|
891
|
-
return resolvedProtocol.parseGeneratedText({
|
|
892
|
-
text: contentItem.text,
|
|
893
|
-
tools: getFunctionTools(params),
|
|
894
|
-
options: extractOnErrorOption(params.providerOptions)
|
|
895
|
-
});
|
|
896
|
-
});
|
|
897
|
-
return {
|
|
898
|
-
...result,
|
|
899
|
-
content: newContent
|
|
900
|
-
};
|
|
901
|
-
},
|
|
902
|
-
transformParams: async ({ params }) => {
|
|
903
|
-
var _a, _b, _c, _d, _e, _f;
|
|
904
|
-
const convertToolPrompt = (prompt) => {
|
|
905
|
-
const processedPrompt2 = prompt.map((message) => {
|
|
906
|
-
var _a2;
|
|
907
|
-
if (message.role === "assistant") {
|
|
908
|
-
const newContent = [];
|
|
909
|
-
for (const content of message.content) {
|
|
910
|
-
if (isToolCallContent(content)) {
|
|
911
|
-
newContent.push({
|
|
912
|
-
type: "text",
|
|
913
|
-
text: resolvedProtocol.formatToolCall(content)
|
|
914
|
-
});
|
|
915
|
-
} else if (content.type === "text") {
|
|
916
|
-
newContent.push(content);
|
|
917
|
-
} else if (content.type === "reasoning") {
|
|
918
|
-
newContent.push(content);
|
|
919
|
-
} else {
|
|
920
|
-
const options = extractOnErrorOption(params.providerOptions);
|
|
921
|
-
(_a2 = options == null ? void 0 : options.onError) == null ? void 0 : _a2.call(
|
|
922
|
-
options,
|
|
923
|
-
"tool-call-middleware: unknown assistant content; stringifying for provider compatibility",
|
|
924
|
-
{ content }
|
|
925
|
-
);
|
|
926
|
-
newContent.push({
|
|
927
|
-
type: "text",
|
|
928
|
-
text: JSON.stringify(content)
|
|
929
|
-
});
|
|
930
|
-
}
|
|
931
|
-
}
|
|
932
|
-
const onlyText = newContent.every((c) => c.type === "text");
|
|
933
|
-
const condensedAssistant = onlyText ? [
|
|
934
|
-
{
|
|
935
|
-
type: "text",
|
|
936
|
-
text: newContent.map((c) => c.text).join("\n")
|
|
937
|
-
}
|
|
938
|
-
] : newContent;
|
|
939
|
-
return { role: "assistant", content: condensedAssistant };
|
|
940
|
-
}
|
|
941
|
-
if (message.role === "tool") {
|
|
942
|
-
return {
|
|
943
|
-
role: "user",
|
|
944
|
-
// Map tool results to text response blocks, then condense into a single text block
|
|
945
|
-
content: [
|
|
946
|
-
{
|
|
947
|
-
type: "text",
|
|
948
|
-
text: message.content.map(
|
|
949
|
-
(toolResult) => isToolResultPart(toolResult) ? resolvedProtocol.formatToolResponse(toolResult) : resolvedProtocol.formatToolResponse(
|
|
950
|
-
toolResult
|
|
951
|
-
)
|
|
952
|
-
).join("\n")
|
|
953
|
-
}
|
|
954
|
-
]
|
|
955
|
-
};
|
|
956
|
-
}
|
|
957
|
-
return message;
|
|
958
|
-
});
|
|
959
|
-
for (let i = 0; i < processedPrompt2.length; i++) {
|
|
960
|
-
const msg = processedPrompt2[i];
|
|
961
|
-
if (Array.isArray(msg.content)) {
|
|
962
|
-
const allText = msg.content.every((c) => (c == null ? void 0 : c.type) === "text");
|
|
963
|
-
if (allText && msg.content.length > 1) {
|
|
964
|
-
processedPrompt2[i] = {
|
|
965
|
-
role: msg.role,
|
|
966
|
-
content: [
|
|
967
|
-
{
|
|
968
|
-
type: "text",
|
|
969
|
-
text: msg.content.map((c) => c.text).join("\n")
|
|
970
|
-
}
|
|
971
|
-
]
|
|
972
|
-
};
|
|
973
|
-
}
|
|
974
|
-
}
|
|
975
|
-
}
|
|
976
|
-
for (let i = processedPrompt2.length - 1; i > 0; i--) {
|
|
977
|
-
const current = processedPrompt2[i];
|
|
978
|
-
const prev = processedPrompt2[i - 1];
|
|
979
|
-
if (current.role === "user" && prev.role === "user") {
|
|
980
|
-
const prevContent = prev.content.map((c) => c.type === "text" ? c.text : "").join("\n");
|
|
981
|
-
const currentContent = current.content.map((c) => c.type === "text" ? c.text : "").join("\n");
|
|
982
|
-
processedPrompt2[i - 1] = {
|
|
983
|
-
role: "user",
|
|
984
|
-
content: [
|
|
985
|
-
{ type: "text", text: prevContent + "\n" + currentContent }
|
|
986
|
-
]
|
|
987
|
-
};
|
|
988
|
-
processedPrompt2.splice(i, 1);
|
|
989
|
-
}
|
|
990
|
-
}
|
|
991
|
-
return processedPrompt2;
|
|
992
|
-
};
|
|
993
|
-
const functionTools = ((_a = params.tools) != null ? _a : []).filter(
|
|
994
|
-
(t) => t.type === "function"
|
|
995
|
-
);
|
|
996
|
-
const systemPrompt = resolvedProtocol.formatTools({
|
|
997
|
-
tools: functionTools,
|
|
998
|
-
toolSystemPromptTemplate
|
|
999
|
-
});
|
|
1000
|
-
const processedPrompt = convertToolPrompt(params.prompt);
|
|
1001
|
-
const finalPrompt = ((_b = processedPrompt[0]) == null ? void 0 : _b.role) === "system" ? [
|
|
1002
|
-
{
|
|
1003
|
-
role: "system",
|
|
1004
|
-
content: systemPrompt + "\n\n" + processedPrompt[0].content
|
|
1005
|
-
},
|
|
1006
|
-
...processedPrompt.slice(1)
|
|
1007
|
-
] : [
|
|
1008
|
-
{
|
|
1009
|
-
role: "system",
|
|
1010
|
-
content: systemPrompt
|
|
1011
|
-
},
|
|
1012
|
-
...processedPrompt
|
|
1013
|
-
];
|
|
1014
|
-
const baseReturnParams = {
|
|
1015
|
-
...params,
|
|
1016
|
-
prompt: finalPrompt,
|
|
1017
|
-
tools: [],
|
|
1018
|
-
toolChoice: void 0,
|
|
1019
|
-
providerOptions: {
|
|
1020
|
-
...params.providerOptions || {},
|
|
1021
|
-
toolCallMiddleware: {
|
|
1022
|
-
...params.providerOptions && typeof params.providerOptions === "object" && params.providerOptions.toolCallMiddleware || {},
|
|
1023
|
-
toolNames: functionTools.map((t) => t.name)
|
|
1024
|
-
}
|
|
1025
|
-
}
|
|
1026
|
-
};
|
|
1027
|
-
if (((_c = params.toolChoice) == null ? void 0 : _c.type) === "none") {
|
|
1028
|
-
throw new Error(
|
|
1029
|
-
"The 'none' toolChoice type is not supported by this middleware. Please use 'auto', 'required', or specify a tool name."
|
|
1030
|
-
);
|
|
1031
|
-
}
|
|
1032
|
-
if (((_d = params.toolChoice) == null ? void 0 : _d.type) === "tool") {
|
|
1033
|
-
const selectedToolName = params.toolChoice.toolName;
|
|
1034
|
-
const selectedTool = (_e = params.tools) == null ? void 0 : _e.find(
|
|
1035
|
-
(tool) => tool.type === "function" ? tool.name === selectedToolName : tool.id === selectedToolName
|
|
1036
|
-
);
|
|
1037
|
-
if (!selectedTool) {
|
|
1038
|
-
throw new Error(
|
|
1039
|
-
`Tool with name '${selectedToolName}' not found in params.tools.`
|
|
1040
|
-
);
|
|
1041
|
-
}
|
|
1042
|
-
if (selectedTool.type === "provider-defined") {
|
|
1043
|
-
throw new Error(
|
|
1044
|
-
"Provider-defined tools are not supported by this middleware. Please use custom tools."
|
|
1045
|
-
);
|
|
1046
|
-
}
|
|
1047
|
-
return {
|
|
1048
|
-
...baseReturnParams,
|
|
1049
|
-
responseFormat: {
|
|
1050
|
-
type: "json",
|
|
1051
|
-
schema: {
|
|
1052
|
-
type: "object",
|
|
1053
|
-
properties: {
|
|
1054
|
-
name: {
|
|
1055
|
-
const: selectedTool.name
|
|
1056
|
-
},
|
|
1057
|
-
arguments: selectedTool.inputSchema
|
|
1058
|
-
},
|
|
1059
|
-
required: ["name", "arguments"]
|
|
1060
|
-
},
|
|
1061
|
-
name: selectedTool.name,
|
|
1062
|
-
description: selectedTool.type === "function" && typeof selectedTool.description === "string" ? selectedTool.description : void 0
|
|
1063
|
-
},
|
|
1064
|
-
providerOptions: {
|
|
1065
|
-
...baseReturnParams.providerOptions || {},
|
|
1066
|
-
toolCallMiddleware: {
|
|
1067
|
-
...baseReturnParams.providerOptions && typeof baseReturnParams.providerOptions === "object" && baseReturnParams.providerOptions.toolCallMiddleware || {},
|
|
1068
|
-
toolChoice: params.toolChoice
|
|
1069
|
-
}
|
|
1070
|
-
}
|
|
1071
|
-
};
|
|
1072
|
-
}
|
|
1073
|
-
if (((_f = params.toolChoice) == null ? void 0 : _f.type) === "required") {
|
|
1074
|
-
if (!params.tools || params.tools.length === 0) {
|
|
1075
|
-
throw new Error(
|
|
1076
|
-
"Tool choice type 'required' is set, but no tools are provided in params.tools."
|
|
1077
|
-
);
|
|
1078
|
-
}
|
|
1079
|
-
return {
|
|
1080
|
-
...baseReturnParams,
|
|
1081
|
-
responseFormat: {
|
|
1082
|
-
type: "json",
|
|
1083
|
-
schema: createDynamicIfThenElseSchema(
|
|
1084
|
-
params.tools.filter((t) => t.type === "function")
|
|
1085
|
-
)
|
|
1086
|
-
},
|
|
1087
|
-
providerOptions: {
|
|
1088
|
-
...baseReturnParams.providerOptions || {},
|
|
1089
|
-
toolCallMiddleware: {
|
|
1090
|
-
...baseReturnParams.providerOptions && typeof baseReturnParams.providerOptions === "object" && baseReturnParams.providerOptions.toolCallMiddleware || {},
|
|
1091
|
-
toolChoice: { type: "required" }
|
|
1092
|
-
}
|
|
1093
|
-
}
|
|
1094
|
-
};
|
|
1095
|
-
}
|
|
1096
|
-
return baseReturnParams;
|
|
1097
|
-
}
|
|
1098
|
-
};
|
|
1099
|
-
}
|
|
1100
|
-
|
|
1101
|
-
// src/protocols/json-mix-protocol.ts
|
|
1102
|
-
import { generateId as generateId3 } from "@ai-sdk/provider-utils";
|
|
1103
|
-
var jsonMixProtocol = ({
|
|
1104
|
-
toolCallStart = "<tool_call>",
|
|
1105
|
-
toolCallEnd = "</tool_call>",
|
|
1106
|
-
toolResponseStart = "<tool_response>",
|
|
1107
|
-
toolResponseEnd = "</tool_response>"
|
|
1108
|
-
} = {}) => ({
|
|
1109
|
-
formatTools({ tools, toolSystemPromptTemplate }) {
|
|
1110
|
-
const toolsForPrompt = (tools || []).filter((tool) => tool.type === "function").map((tool) => ({
|
|
1111
|
-
name: tool.name,
|
|
1112
|
-
description: tool.type === "function" && typeof tool.description === "string" ? tool.description : void 0,
|
|
1113
|
-
parameters: tool.inputSchema
|
|
1114
|
-
}));
|
|
1115
|
-
return toolSystemPromptTemplate(JSON.stringify(toolsForPrompt));
|
|
1116
|
-
},
|
|
1117
|
-
formatToolCall(toolCall) {
|
|
1118
|
-
let args = {};
|
|
1119
|
-
try {
|
|
1120
|
-
args = JSON.parse(toolCall.input);
|
|
1121
|
-
} catch (e) {
|
|
1122
|
-
args = toolCall.input;
|
|
1123
|
-
}
|
|
1124
|
-
return `${toolCallStart}${JSON.stringify({
|
|
1125
|
-
name: toolCall.toolName,
|
|
1126
|
-
arguments: args
|
|
1127
|
-
})}${toolCallEnd}`;
|
|
1128
|
-
},
|
|
1129
|
-
formatToolResponse(toolResult) {
|
|
1130
|
-
return `${toolResponseStart}${JSON.stringify({
|
|
1131
|
-
toolName: toolResult.toolName,
|
|
1132
|
-
result: toolResult.output
|
|
1133
|
-
})}${toolResponseEnd}`;
|
|
1134
|
-
},
|
|
1135
|
-
parseGeneratedText({ text, options }) {
|
|
1136
|
-
var _a;
|
|
1137
|
-
const startEsc = escapeRegExp(toolCallStart);
|
|
1138
|
-
const endEsc = escapeRegExp(toolCallEnd);
|
|
1139
|
-
const toolCallRegex = new RegExp(
|
|
1140
|
-
`${startEsc}([\0-\uFFFF]*?)${endEsc}`,
|
|
1141
|
-
"gs"
|
|
1142
|
-
);
|
|
1143
|
-
const processedElements = [];
|
|
1144
|
-
let currentIndex = 0;
|
|
1145
|
-
let match;
|
|
1146
|
-
while ((match = toolCallRegex.exec(text)) !== null) {
|
|
1147
|
-
const startIndex = match.index;
|
|
1148
|
-
const toolCallJson = match[1];
|
|
1149
|
-
if (startIndex > currentIndex) {
|
|
1150
|
-
const textSegment = text.substring(currentIndex, startIndex);
|
|
1151
|
-
if (textSegment.trim()) {
|
|
1152
|
-
processedElements.push({ type: "text", text: textSegment });
|
|
1153
|
-
}
|
|
1154
|
-
}
|
|
1155
|
-
if (toolCallJson) {
|
|
1156
|
-
try {
|
|
1157
|
-
const parsedToolCall = relaxed_json_exports.parse(toolCallJson);
|
|
1158
|
-
processedElements.push({
|
|
1159
|
-
type: "tool-call",
|
|
1160
|
-
toolCallId: generateId3(),
|
|
1161
|
-
toolName: parsedToolCall.name,
|
|
1162
|
-
input: JSON.stringify((_a = parsedToolCall.arguments) != null ? _a : {})
|
|
1163
|
-
});
|
|
1164
|
-
} catch (error) {
|
|
1165
|
-
if (options == null ? void 0 : options.onError) {
|
|
1166
|
-
options.onError(
|
|
1167
|
-
"Could not process JSON tool call, keeping original text.",
|
|
1168
|
-
{ toolCall: match[0], error }
|
|
1169
|
-
);
|
|
1170
|
-
}
|
|
1171
|
-
processedElements.push({ type: "text", text: match[0] });
|
|
1172
|
-
}
|
|
1173
|
-
}
|
|
1174
|
-
currentIndex = startIndex + match[0].length;
|
|
1175
|
-
}
|
|
1176
|
-
if (currentIndex < text.length) {
|
|
1177
|
-
const remainingText = text.substring(currentIndex);
|
|
1178
|
-
if (remainingText.trim()) {
|
|
1179
|
-
processedElements.push({ type: "text", text: remainingText });
|
|
1180
|
-
}
|
|
1136
|
+
if (currentIndex < text.length) {
|
|
1137
|
+
const remainingText = text.substring(currentIndex);
|
|
1138
|
+
if (remainingText.trim()) {
|
|
1139
|
+
processedElements.push({ type: "text", text: remainingText });
|
|
1140
|
+
}
|
|
1181
1141
|
}
|
|
1182
1142
|
return processedElements;
|
|
1183
1143
|
},
|
|
@@ -1193,7 +1153,7 @@ var jsonMixProtocol = ({
|
|
|
1193
1153
|
if (chunk.type === "finish") {
|
|
1194
1154
|
if (isInsideToolCall && buffer.length > 0) {
|
|
1195
1155
|
if (!currentTextId) {
|
|
1196
|
-
currentTextId =
|
|
1156
|
+
currentTextId = generateId2();
|
|
1197
1157
|
controller.enqueue({ type: "text-start", id: currentTextId });
|
|
1198
1158
|
hasEmittedTextStart = true;
|
|
1199
1159
|
}
|
|
@@ -1205,7 +1165,7 @@ var jsonMixProtocol = ({
|
|
|
1205
1165
|
buffer = "";
|
|
1206
1166
|
} else if (!isInsideToolCall && buffer.length > 0) {
|
|
1207
1167
|
if (!currentTextId) {
|
|
1208
|
-
currentTextId =
|
|
1168
|
+
currentTextId = generateId2();
|
|
1209
1169
|
controller.enqueue({ type: "text-start", id: currentTextId });
|
|
1210
1170
|
hasEmittedTextStart = true;
|
|
1211
1171
|
}
|
|
@@ -1222,7 +1182,7 @@ var jsonMixProtocol = ({
|
|
|
1222
1182
|
hasEmittedTextStart = false;
|
|
1223
1183
|
}
|
|
1224
1184
|
if (currentToolCallJson) {
|
|
1225
|
-
const errorId =
|
|
1185
|
+
const errorId = generateId2();
|
|
1226
1186
|
controller.enqueue({ type: "text-start", id: errorId });
|
|
1227
1187
|
controller.enqueue({
|
|
1228
1188
|
type: "text-delta",
|
|
@@ -1250,7 +1210,7 @@ var jsonMixProtocol = ({
|
|
|
1250
1210
|
currentToolCallJson += text;
|
|
1251
1211
|
} else if (text.length > 0) {
|
|
1252
1212
|
if (!currentTextId) {
|
|
1253
|
-
currentTextId =
|
|
1213
|
+
currentTextId = generateId2();
|
|
1254
1214
|
controller.enqueue({ type: "text-start", id: currentTextId });
|
|
1255
1215
|
hasEmittedTextStart = true;
|
|
1256
1216
|
}
|
|
@@ -1285,12 +1245,12 @@ var jsonMixProtocol = ({
|
|
|
1285
1245
|
}
|
|
1286
1246
|
controller.enqueue({
|
|
1287
1247
|
type: "tool-call",
|
|
1288
|
-
toolCallId:
|
|
1248
|
+
toolCallId: generateId2(),
|
|
1289
1249
|
toolName: parsedToolCall.name,
|
|
1290
1250
|
input: JSON.stringify((_a = parsedToolCall.arguments) != null ? _a : {})
|
|
1291
1251
|
});
|
|
1292
1252
|
} catch (e) {
|
|
1293
|
-
const errorId =
|
|
1253
|
+
const errorId = generateId2();
|
|
1294
1254
|
controller.enqueue({ type: "text-start", id: errorId });
|
|
1295
1255
|
controller.enqueue({
|
|
1296
1256
|
type: "text-delta",
|
|
@@ -1323,18 +1283,29 @@ var jsonMixProtocol = ({
|
|
|
1323
1283
|
}
|
|
1324
1284
|
}
|
|
1325
1285
|
});
|
|
1286
|
+
},
|
|
1287
|
+
extractToolCallSegments({ text }) {
|
|
1288
|
+
const startEsc = escapeRegExp(toolCallStart);
|
|
1289
|
+
const endEsc = escapeRegExp(toolCallEnd);
|
|
1290
|
+
const regex = new RegExp(`${startEsc}([\0-\uFFFF]*?)${endEsc}`, "gs");
|
|
1291
|
+
const segments = [];
|
|
1292
|
+
let m;
|
|
1293
|
+
while ((m = regex.exec(text)) != null) {
|
|
1294
|
+
segments.push(m[0]);
|
|
1295
|
+
}
|
|
1296
|
+
return segments;
|
|
1326
1297
|
}
|
|
1327
1298
|
});
|
|
1328
1299
|
|
|
1329
|
-
// src/protocols/xml-protocol.ts
|
|
1330
|
-
import { generateId as
|
|
1331
|
-
import {
|
|
1332
|
-
var
|
|
1300
|
+
// src/protocols/morph-xml-protocol.ts
|
|
1301
|
+
import { generateId as generateId3 } from "@ai-sdk/provider-utils";
|
|
1302
|
+
import { XMLBuilder, XMLParser } from "fast-xml-parser";
|
|
1303
|
+
var morphXmlProtocol = () => ({
|
|
1333
1304
|
formatTools({ tools, toolSystemPromptTemplate }) {
|
|
1334
1305
|
const toolsForPrompt = (tools || []).map((tool) => ({
|
|
1335
1306
|
name: tool.name,
|
|
1336
1307
|
description: tool.description,
|
|
1337
|
-
parameters: tool.inputSchema
|
|
1308
|
+
parameters: unwrapJsonSchema(tool.inputSchema)
|
|
1338
1309
|
}));
|
|
1339
1310
|
return toolSystemPromptTemplate(JSON.stringify(toolsForPrompt));
|
|
1340
1311
|
},
|
|
@@ -1367,7 +1338,8 @@ var xmlProtocol = () => ({
|
|
|
1367
1338
|
return xmlContent;
|
|
1368
1339
|
},
|
|
1369
1340
|
parseGeneratedText({ text, tools, options }) {
|
|
1370
|
-
var _a, _b;
|
|
1341
|
+
var _a, _b, _c;
|
|
1342
|
+
const originalSchemas = (options == null ? void 0 : options.originalToolSchemas) || {};
|
|
1371
1343
|
const toolNames = tools.map((t) => t.name).filter((name) => name != null);
|
|
1372
1344
|
if (toolNames.length === 0) {
|
|
1373
1345
|
return [{ type: "text", text }];
|
|
@@ -1405,17 +1377,87 @@ var xmlProtocol = () => ({
|
|
|
1405
1377
|
if (v && typeof v === "object" && Object.prototype.hasOwnProperty.call(v, "#text")) {
|
|
1406
1378
|
val = v == null ? void 0 : v["#text"];
|
|
1407
1379
|
}
|
|
1380
|
+
if (Array.isArray(v)) {
|
|
1381
|
+
val = v.map((item) => {
|
|
1382
|
+
if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
|
|
1383
|
+
const textVal = item == null ? void 0 : item["#text"];
|
|
1384
|
+
return typeof textVal === "string" ? textVal.trim() : textVal;
|
|
1385
|
+
}
|
|
1386
|
+
return typeof item === "string" ? item.trim() : item;
|
|
1387
|
+
});
|
|
1388
|
+
} else if (v && typeof v === "object" && !Object.prototype.hasOwnProperty.call(v, "#text")) {
|
|
1389
|
+
const obj = v;
|
|
1390
|
+
const keys = Object.keys(obj);
|
|
1391
|
+
if (keys.length === 1 && keys[0] === "item") {
|
|
1392
|
+
const itemValue = obj.item;
|
|
1393
|
+
if (Array.isArray(itemValue)) {
|
|
1394
|
+
val = itemValue.map((item) => {
|
|
1395
|
+
if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
|
|
1396
|
+
const textVal = item == null ? void 0 : item["#text"];
|
|
1397
|
+
const trimmed2 = typeof textVal === "string" ? textVal.trim() : textVal;
|
|
1398
|
+
if (typeof trimmed2 === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed2)) {
|
|
1399
|
+
const num = Number(trimmed2);
|
|
1400
|
+
if (Number.isFinite(num)) return num;
|
|
1401
|
+
}
|
|
1402
|
+
return trimmed2;
|
|
1403
|
+
}
|
|
1404
|
+
const trimmed = typeof item === "string" ? item.trim() : item;
|
|
1405
|
+
if (typeof trimmed === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed)) {
|
|
1406
|
+
const num = Number(trimmed);
|
|
1407
|
+
if (Number.isFinite(num)) return num;
|
|
1408
|
+
}
|
|
1409
|
+
return trimmed;
|
|
1410
|
+
});
|
|
1411
|
+
} else {
|
|
1412
|
+
const trimmed = typeof itemValue === "string" ? itemValue.trim() : itemValue;
|
|
1413
|
+
if (typeof trimmed === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed)) {
|
|
1414
|
+
const num = Number(trimmed);
|
|
1415
|
+
if (Number.isFinite(num)) {
|
|
1416
|
+
val = num;
|
|
1417
|
+
} else {
|
|
1418
|
+
val = trimmed;
|
|
1419
|
+
}
|
|
1420
|
+
} else {
|
|
1421
|
+
val = trimmed;
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
} else {
|
|
1425
|
+
const isIndexedTuple = keys.length > 0 && keys.every((key) => /^\d+$/.test(key)) && (() => {
|
|
1426
|
+
const indices = keys.map((k2) => parseInt(k2)).sort((a, b) => a - b);
|
|
1427
|
+
return indices[0] === 0 && indices.every((val2, idx) => val2 === idx);
|
|
1428
|
+
})();
|
|
1429
|
+
if (isIndexedTuple) {
|
|
1430
|
+
const sortedKeys = keys.sort(
|
|
1431
|
+
(a, b) => parseInt(a) - parseInt(b)
|
|
1432
|
+
);
|
|
1433
|
+
val = sortedKeys.map((key) => {
|
|
1434
|
+
const item = obj[key];
|
|
1435
|
+
if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
|
|
1436
|
+
const textVal = item == null ? void 0 : item["#text"];
|
|
1437
|
+
return typeof textVal === "string" ? textVal.trim() : textVal;
|
|
1438
|
+
}
|
|
1439
|
+
return typeof item === "string" ? item.trim() : item;
|
|
1440
|
+
});
|
|
1441
|
+
} else {
|
|
1442
|
+
val = v;
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1408
1446
|
args[k] = typeof val === "string" ? val.trim() : val;
|
|
1409
1447
|
}
|
|
1448
|
+
const originalSchema = originalSchemas[toolName];
|
|
1449
|
+
const fallbackSchema = (_b = tools.find((t) => t.name === toolName)) == null ? void 0 : _b.inputSchema;
|
|
1450
|
+
const schema = originalSchema || fallbackSchema;
|
|
1451
|
+
const coercedArgs = coerceBySchema(args, schema);
|
|
1410
1452
|
processedElements.push({
|
|
1411
1453
|
type: "tool-call",
|
|
1412
|
-
toolCallId:
|
|
1454
|
+
toolCallId: generateId3(),
|
|
1413
1455
|
toolName,
|
|
1414
|
-
input: JSON.stringify(
|
|
1456
|
+
input: JSON.stringify(coercedArgs)
|
|
1415
1457
|
});
|
|
1416
1458
|
} catch (error) {
|
|
1417
1459
|
const message = `Could not process XML tool call, keeping original text: ${match[0]}`;
|
|
1418
|
-
(
|
|
1460
|
+
(_c = options == null ? void 0 : options.onError) == null ? void 0 : _c.call(options, message, { toolCall: match[0], toolName, error });
|
|
1419
1461
|
processedElements.push({ type: "text", text: match[0] });
|
|
1420
1462
|
}
|
|
1421
1463
|
currentIndex = startIndex + match[0].length;
|
|
@@ -1429,6 +1471,7 @@ var xmlProtocol = () => ({
|
|
|
1429
1471
|
return processedElements;
|
|
1430
1472
|
},
|
|
1431
1473
|
createStreamParser({ tools, options }) {
|
|
1474
|
+
const originalSchemas = (options == null ? void 0 : options.originalToolSchemas) || {};
|
|
1432
1475
|
const toolNames = tools.map((t) => t.name).filter((name) => name != null);
|
|
1433
1476
|
let buffer = "";
|
|
1434
1477
|
let currentToolCall = null;
|
|
@@ -1437,7 +1480,7 @@ var xmlProtocol = () => ({
|
|
|
1437
1480
|
const content = text != null ? text : buffer;
|
|
1438
1481
|
if (content) {
|
|
1439
1482
|
if (!currentTextId) {
|
|
1440
|
-
currentTextId =
|
|
1483
|
+
currentTextId = generateId3();
|
|
1441
1484
|
controller.enqueue({ type: "text-start", id: currentTextId });
|
|
1442
1485
|
}
|
|
1443
1486
|
controller.enqueue({
|
|
@@ -1456,7 +1499,7 @@ var xmlProtocol = () => ({
|
|
|
1456
1499
|
};
|
|
1457
1500
|
return new TransformStream({
|
|
1458
1501
|
transform(chunk, controller) {
|
|
1459
|
-
var _a;
|
|
1502
|
+
var _a, _b;
|
|
1460
1503
|
if (chunk.type !== "text-delta") {
|
|
1461
1504
|
if (buffer) flushText(controller);
|
|
1462
1505
|
controller.enqueue(chunk);
|
|
@@ -1485,14 +1528,86 @@ var xmlProtocol = () => ({
|
|
|
1485
1528
|
if (v && typeof v === "object" && Object.prototype.hasOwnProperty.call(v, "#text")) {
|
|
1486
1529
|
val = v == null ? void 0 : v["#text"];
|
|
1487
1530
|
}
|
|
1531
|
+
if (Array.isArray(v)) {
|
|
1532
|
+
val = v.map((item) => {
|
|
1533
|
+
if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
|
|
1534
|
+
const textVal = item == null ? void 0 : item["#text"];
|
|
1535
|
+
return typeof textVal === "string" ? textVal.trim() : textVal;
|
|
1536
|
+
}
|
|
1537
|
+
return typeof item === "string" ? item.trim() : item;
|
|
1538
|
+
});
|
|
1539
|
+
} else if (v && typeof v === "object" && !Object.prototype.hasOwnProperty.call(v, "#text")) {
|
|
1540
|
+
const obj = v;
|
|
1541
|
+
const keys = Object.keys(obj);
|
|
1542
|
+
if (keys.length === 1 && keys[0] === "item") {
|
|
1543
|
+
const itemValue = obj.item;
|
|
1544
|
+
if (Array.isArray(itemValue)) {
|
|
1545
|
+
val = itemValue.map((item) => {
|
|
1546
|
+
if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
|
|
1547
|
+
const textVal = item == null ? void 0 : item["#text"];
|
|
1548
|
+
const trimmed2 = typeof textVal === "string" ? textVal.trim() : textVal;
|
|
1549
|
+
if (typeof trimmed2 === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed2)) {
|
|
1550
|
+
const num = Number(trimmed2);
|
|
1551
|
+
if (Number.isFinite(num)) return num;
|
|
1552
|
+
}
|
|
1553
|
+
return trimmed2;
|
|
1554
|
+
}
|
|
1555
|
+
const trimmed = typeof item === "string" ? item.trim() : item;
|
|
1556
|
+
if (typeof trimmed === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed)) {
|
|
1557
|
+
const num = Number(trimmed);
|
|
1558
|
+
if (Number.isFinite(num)) return num;
|
|
1559
|
+
}
|
|
1560
|
+
return trimmed;
|
|
1561
|
+
});
|
|
1562
|
+
} else {
|
|
1563
|
+
const trimmed = typeof itemValue === "string" ? itemValue.trim() : itemValue;
|
|
1564
|
+
if (typeof trimmed === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed)) {
|
|
1565
|
+
const num = Number(trimmed);
|
|
1566
|
+
if (Number.isFinite(num)) {
|
|
1567
|
+
val = num;
|
|
1568
|
+
} else {
|
|
1569
|
+
val = trimmed;
|
|
1570
|
+
}
|
|
1571
|
+
} else {
|
|
1572
|
+
val = trimmed;
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
} else {
|
|
1576
|
+
const isIndexedTuple = keys.length > 0 && keys.every((key) => /^\d+$/.test(key)) && (() => {
|
|
1577
|
+
const indices = keys.map((k2) => parseInt(k2)).sort((a, b) => a - b);
|
|
1578
|
+
return indices[0] === 0 && indices.every((val2, idx) => val2 === idx);
|
|
1579
|
+
})();
|
|
1580
|
+
if (isIndexedTuple) {
|
|
1581
|
+
const sortedKeys = keys.sort(
|
|
1582
|
+
(a, b) => parseInt(a) - parseInt(b)
|
|
1583
|
+
);
|
|
1584
|
+
val = sortedKeys.map((key) => {
|
|
1585
|
+
const item = obj[key];
|
|
1586
|
+
if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
|
|
1587
|
+
const textVal = item == null ? void 0 : item["#text"];
|
|
1588
|
+
return typeof textVal === "string" ? textVal.trim() : textVal;
|
|
1589
|
+
}
|
|
1590
|
+
return typeof item === "string" ? item.trim() : item;
|
|
1591
|
+
});
|
|
1592
|
+
} else {
|
|
1593
|
+
val = v;
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1488
1597
|
args[k] = typeof val === "string" ? val.trim() : val;
|
|
1489
1598
|
}
|
|
1599
|
+
const originalSchema = originalSchemas[currentToolCall.name];
|
|
1600
|
+
const fallbackSchema = (_b = tools.find(
|
|
1601
|
+
(t) => t.name === currentToolCall.name
|
|
1602
|
+
)) == null ? void 0 : _b.inputSchema;
|
|
1603
|
+
const toolSchema = originalSchema || fallbackSchema;
|
|
1604
|
+
const coercedArgs = coerceBySchema(args, toolSchema);
|
|
1490
1605
|
flushText(controller);
|
|
1491
1606
|
controller.enqueue({
|
|
1492
1607
|
type: "tool-call",
|
|
1493
|
-
toolCallId:
|
|
1608
|
+
toolCallId: generateId3(),
|
|
1494
1609
|
toolName: currentToolCall.name,
|
|
1495
|
-
input: JSON.stringify(
|
|
1610
|
+
input: JSON.stringify(coercedArgs)
|
|
1496
1611
|
});
|
|
1497
1612
|
} catch (e) {
|
|
1498
1613
|
const originalCallText = `<${currentToolCall.name}>${toolContent}${endTag}`;
|
|
@@ -1550,11 +1665,578 @@ var xmlProtocol = () => ({
|
|
|
1550
1665
|
}
|
|
1551
1666
|
}
|
|
1552
1667
|
});
|
|
1668
|
+
},
|
|
1669
|
+
extractToolCallSegments({ text, tools }) {
|
|
1670
|
+
const toolNames = tools.map((t) => t.name).filter(Boolean);
|
|
1671
|
+
if (toolNames.length === 0) return [];
|
|
1672
|
+
const names = toolNames.map((n) => escapeRegExp(String(n))).join("|");
|
|
1673
|
+
if (!names) return [];
|
|
1674
|
+
const regex = new RegExp(`<(${names})>[\\s\\S]*?<\\/\\1>`, "g");
|
|
1675
|
+
const segments = [];
|
|
1676
|
+
let m;
|
|
1677
|
+
while ((m = regex.exec(text)) != null) {
|
|
1678
|
+
segments.push(m[0]);
|
|
1679
|
+
}
|
|
1680
|
+
return segments;
|
|
1553
1681
|
}
|
|
1554
1682
|
});
|
|
1555
1683
|
|
|
1556
|
-
// src/
|
|
1684
|
+
// src/generate-handler.ts
|
|
1685
|
+
import { generateId as generateId4 } from "@ai-sdk/provider-utils";
|
|
1686
|
+
async function wrapGenerate({
|
|
1687
|
+
protocol,
|
|
1688
|
+
doGenerate,
|
|
1689
|
+
params
|
|
1690
|
+
}) {
|
|
1691
|
+
var _a, _b;
|
|
1692
|
+
if (isToolChoiceActive(params)) {
|
|
1693
|
+
const result2 = await doGenerate();
|
|
1694
|
+
let parsed2 = {};
|
|
1695
|
+
const first = (_a = result2.content) == null ? void 0 : _a[0];
|
|
1696
|
+
if (first && first.type === "text") {
|
|
1697
|
+
const debugLevel2 = getDebugLevel();
|
|
1698
|
+
if (debugLevel2 === "parse") {
|
|
1699
|
+
logRawChunk(first.text);
|
|
1700
|
+
}
|
|
1701
|
+
try {
|
|
1702
|
+
parsed2 = JSON.parse(first.text);
|
|
1703
|
+
} catch (error) {
|
|
1704
|
+
const options = extractOnErrorOption(params.providerOptions);
|
|
1705
|
+
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
1706
|
+
options,
|
|
1707
|
+
"Failed to parse toolChoice JSON from generated model output",
|
|
1708
|
+
{
|
|
1709
|
+
text: first.text,
|
|
1710
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1711
|
+
}
|
|
1712
|
+
);
|
|
1713
|
+
parsed2 = {};
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
const toolCall = {
|
|
1717
|
+
type: "tool-call",
|
|
1718
|
+
toolCallId: generateId4(),
|
|
1719
|
+
toolName: parsed2.name || "unknown",
|
|
1720
|
+
input: JSON.stringify(parsed2.arguments || {})
|
|
1721
|
+
};
|
|
1722
|
+
const debugLevelToolChoice = getDebugLevel();
|
|
1723
|
+
const originText = first && first.type === "text" ? first.text : "";
|
|
1724
|
+
if (debugLevelToolChoice === "parse") {
|
|
1725
|
+
logParsedSummary({ toolCalls: [toolCall], originalText: originText });
|
|
1726
|
+
}
|
|
1727
|
+
return {
|
|
1728
|
+
...result2,
|
|
1729
|
+
content: [toolCall]
|
|
1730
|
+
};
|
|
1731
|
+
}
|
|
1732
|
+
const result = await doGenerate();
|
|
1733
|
+
if (result.content.length === 0) {
|
|
1734
|
+
return result;
|
|
1735
|
+
}
|
|
1736
|
+
const parsed = result.content.flatMap((contentItem) => {
|
|
1737
|
+
var _a2;
|
|
1738
|
+
if (contentItem.type !== "text") {
|
|
1739
|
+
return [contentItem];
|
|
1740
|
+
}
|
|
1741
|
+
const debugLevel2 = getDebugLevel();
|
|
1742
|
+
if (debugLevel2 === "stream") {
|
|
1743
|
+
logRawChunk(contentItem.text);
|
|
1744
|
+
}
|
|
1745
|
+
return protocol.parseGeneratedText({
|
|
1746
|
+
text: contentItem.text,
|
|
1747
|
+
tools: getFunctionTools(params),
|
|
1748
|
+
options: {
|
|
1749
|
+
...extractOnErrorOption(params.providerOptions),
|
|
1750
|
+
...(_a2 = params.providerOptions) == null ? void 0 : _a2.toolCallMiddleware
|
|
1751
|
+
}
|
|
1752
|
+
});
|
|
1753
|
+
});
|
|
1754
|
+
const tools = getFunctionTools(params);
|
|
1755
|
+
const newContent = parsed.map(
|
|
1756
|
+
(part) => coerceToolCallInput(part, tools)
|
|
1757
|
+
);
|
|
1758
|
+
const debugLevel = getDebugLevel();
|
|
1759
|
+
if (debugLevel === "stream") {
|
|
1760
|
+
newContent.forEach((part) => logParsedChunk(part));
|
|
1761
|
+
}
|
|
1762
|
+
if (debugLevel === "parse") {
|
|
1763
|
+
const allText = result.content.filter(
|
|
1764
|
+
(c) => c.type === "text"
|
|
1765
|
+
).map((c) => c.text).join("\n\n");
|
|
1766
|
+
const segments = protocol.extractToolCallSegments ? protocol.extractToolCallSegments({ text: allText, tools }) : [];
|
|
1767
|
+
const originalText = segments.join("\n\n");
|
|
1768
|
+
const toolCalls = newContent.filter(
|
|
1769
|
+
(p) => p.type === "tool-call"
|
|
1770
|
+
);
|
|
1771
|
+
logParsedSummary({ toolCalls, originalText });
|
|
1772
|
+
}
|
|
1773
|
+
return {
|
|
1774
|
+
...result,
|
|
1775
|
+
content: newContent
|
|
1776
|
+
};
|
|
1777
|
+
}
|
|
1778
|
+
|
|
1779
|
+
// src/stream-handler.ts
|
|
1557
1780
|
import { generateId as generateId5 } from "@ai-sdk/provider-utils";
|
|
1781
|
+
async function wrapStream({
|
|
1782
|
+
protocol,
|
|
1783
|
+
doStream,
|
|
1784
|
+
doGenerate,
|
|
1785
|
+
params
|
|
1786
|
+
}) {
|
|
1787
|
+
var _a;
|
|
1788
|
+
if (isToolChoiceActive(params)) {
|
|
1789
|
+
return toolChoiceStream({
|
|
1790
|
+
doGenerate,
|
|
1791
|
+
options: extractOnErrorOption(params.providerOptions)
|
|
1792
|
+
});
|
|
1793
|
+
}
|
|
1794
|
+
const { stream, ...rest } = await doStream();
|
|
1795
|
+
const debugLevel = getDebugLevel();
|
|
1796
|
+
const tools = getFunctionTools(params);
|
|
1797
|
+
const options = {
|
|
1798
|
+
...extractOnErrorOption(params.providerOptions),
|
|
1799
|
+
...(_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware
|
|
1800
|
+
};
|
|
1801
|
+
if (debugLevel === "off") {
|
|
1802
|
+
return {
|
|
1803
|
+
stream: stream.pipeThrough(
|
|
1804
|
+
protocol.createStreamParser({
|
|
1805
|
+
tools,
|
|
1806
|
+
options
|
|
1807
|
+
})
|
|
1808
|
+
),
|
|
1809
|
+
...rest
|
|
1810
|
+
};
|
|
1811
|
+
}
|
|
1812
|
+
if (debugLevel === "stream") {
|
|
1813
|
+
const withRawTap2 = stream.pipeThrough(
|
|
1814
|
+
new TransformStream(
|
|
1815
|
+
{
|
|
1816
|
+
transform(part, controller) {
|
|
1817
|
+
logRawChunk(part);
|
|
1818
|
+
controller.enqueue(part);
|
|
1819
|
+
}
|
|
1820
|
+
}
|
|
1821
|
+
)
|
|
1822
|
+
);
|
|
1823
|
+
const parsed2 = withRawTap2.pipeThrough(
|
|
1824
|
+
protocol.createStreamParser({
|
|
1825
|
+
tools,
|
|
1826
|
+
options
|
|
1827
|
+
})
|
|
1828
|
+
);
|
|
1829
|
+
const withParsedTap = parsed2.pipeThrough(
|
|
1830
|
+
new TransformStream(
|
|
1831
|
+
{
|
|
1832
|
+
transform(part, controller) {
|
|
1833
|
+
logParsedChunk(part);
|
|
1834
|
+
controller.enqueue(part);
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1837
|
+
)
|
|
1838
|
+
);
|
|
1839
|
+
return {
|
|
1840
|
+
stream: withParsedTap,
|
|
1841
|
+
...rest
|
|
1842
|
+
};
|
|
1843
|
+
}
|
|
1844
|
+
let fullRawText = "";
|
|
1845
|
+
const withRawTap = stream.pipeThrough(
|
|
1846
|
+
new TransformStream({
|
|
1847
|
+
transform(part, controller) {
|
|
1848
|
+
if (part.type === "text-delta") {
|
|
1849
|
+
const delta = part.delta;
|
|
1850
|
+
if (typeof delta === "string" && delta.length > 0) {
|
|
1851
|
+
fullRawText += delta;
|
|
1852
|
+
}
|
|
1853
|
+
}
|
|
1854
|
+
controller.enqueue(part);
|
|
1855
|
+
}
|
|
1856
|
+
})
|
|
1857
|
+
);
|
|
1858
|
+
const parsed = withRawTap.pipeThrough(
|
|
1859
|
+
protocol.createStreamParser({
|
|
1860
|
+
tools,
|
|
1861
|
+
options
|
|
1862
|
+
})
|
|
1863
|
+
);
|
|
1864
|
+
const withSummary = parsed.pipeThrough(
|
|
1865
|
+
new TransformStream({
|
|
1866
|
+
transform: /* @__PURE__ */ (() => {
|
|
1867
|
+
const parsedToolCalls = [];
|
|
1868
|
+
return (part, controller) => {
|
|
1869
|
+
if (part.type === "tool-call") {
|
|
1870
|
+
parsedToolCalls.push(part);
|
|
1871
|
+
}
|
|
1872
|
+
if (part.type === "finish") {
|
|
1873
|
+
try {
|
|
1874
|
+
const segments = protocol.extractToolCallSegments ? protocol.extractToolCallSegments({
|
|
1875
|
+
text: fullRawText,
|
|
1876
|
+
tools
|
|
1877
|
+
}) : [];
|
|
1878
|
+
const origin = segments.join("\n\n");
|
|
1879
|
+
logParsedSummary({
|
|
1880
|
+
toolCalls: parsedToolCalls,
|
|
1881
|
+
originalText: origin
|
|
1882
|
+
});
|
|
1883
|
+
} catch (e) {
|
|
1884
|
+
}
|
|
1885
|
+
}
|
|
1886
|
+
controller.enqueue(part);
|
|
1887
|
+
};
|
|
1888
|
+
})()
|
|
1889
|
+
})
|
|
1890
|
+
);
|
|
1891
|
+
return {
|
|
1892
|
+
stream: withSummary,
|
|
1893
|
+
...rest
|
|
1894
|
+
};
|
|
1895
|
+
}
|
|
1896
|
+
async function toolChoiceStream({
|
|
1897
|
+
doGenerate,
|
|
1898
|
+
options
|
|
1899
|
+
}) {
|
|
1900
|
+
var _a, _b;
|
|
1901
|
+
const result = await doGenerate();
|
|
1902
|
+
let toolJson = {};
|
|
1903
|
+
if ((result == null ? void 0 : result.content) && result.content.length > 0 && ((_a = result.content[0]) == null ? void 0 : _a.type) === "text") {
|
|
1904
|
+
try {
|
|
1905
|
+
toolJson = JSON.parse(result.content[0].text);
|
|
1906
|
+
} catch (error) {
|
|
1907
|
+
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
1908
|
+
options,
|
|
1909
|
+
"Failed to parse toolChoice JSON from streamed model output",
|
|
1910
|
+
{
|
|
1911
|
+
text: result.content[0].text,
|
|
1912
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1913
|
+
}
|
|
1914
|
+
);
|
|
1915
|
+
toolJson = {};
|
|
1916
|
+
}
|
|
1917
|
+
}
|
|
1918
|
+
const toolCallChunk = {
|
|
1919
|
+
type: "tool-call",
|
|
1920
|
+
toolCallId: generateId5(),
|
|
1921
|
+
toolName: toolJson.name || "unknown",
|
|
1922
|
+
input: JSON.stringify(toolJson.arguments || {})
|
|
1923
|
+
};
|
|
1924
|
+
const finishChunk = {
|
|
1925
|
+
type: "finish",
|
|
1926
|
+
usage: (result == null ? void 0 : result.usage) || // TODO: If possible, try to return a certain amount of LLM usage.
|
|
1927
|
+
{
|
|
1928
|
+
inputTokens: 0,
|
|
1929
|
+
outputTokens: 0,
|
|
1930
|
+
totalTokens: 0
|
|
1931
|
+
},
|
|
1932
|
+
finishReason: "tool-calls"
|
|
1933
|
+
};
|
|
1934
|
+
const stream = new ReadableStream({
|
|
1935
|
+
start(controller) {
|
|
1936
|
+
controller.enqueue(toolCallChunk);
|
|
1937
|
+
controller.enqueue(finishChunk);
|
|
1938
|
+
controller.close();
|
|
1939
|
+
}
|
|
1940
|
+
});
|
|
1941
|
+
const debugLevel = getDebugLevel();
|
|
1942
|
+
const firstText = (result == null ? void 0 : result.content) && result.content[0] && result.content[0].type === "text" && result.content[0].text || "";
|
|
1943
|
+
const streamWithSummary = debugLevel === "parse" ? stream.pipeThrough(
|
|
1944
|
+
new TransformStream({
|
|
1945
|
+
transform(part, controller) {
|
|
1946
|
+
if (part.type === "finish") {
|
|
1947
|
+
try {
|
|
1948
|
+
logParsedSummary({
|
|
1949
|
+
toolCalls: [toolCallChunk],
|
|
1950
|
+
originalText: typeof firstText === "string" ? firstText : ""
|
|
1951
|
+
});
|
|
1952
|
+
} catch (e) {
|
|
1953
|
+
}
|
|
1954
|
+
}
|
|
1955
|
+
controller.enqueue(part);
|
|
1956
|
+
}
|
|
1957
|
+
})
|
|
1958
|
+
) : stream;
|
|
1959
|
+
return {
|
|
1960
|
+
request: (result == null ? void 0 : result.request) || {},
|
|
1961
|
+
response: (result == null ? void 0 : result.response) || {},
|
|
1962
|
+
stream: streamWithSummary
|
|
1963
|
+
};
|
|
1964
|
+
}
|
|
1965
|
+
|
|
1966
|
+
// src/transform-handler.ts
|
|
1967
|
+
async function transformParams({
|
|
1968
|
+
params,
|
|
1969
|
+
protocol,
|
|
1970
|
+
toolSystemPromptTemplate
|
|
1971
|
+
}) {
|
|
1972
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1973
|
+
const resolvedProtocol = isProtocolFactory(protocol) ? protocol() : protocol;
|
|
1974
|
+
const functionTools = ((_a = params.tools) != null ? _a : []).filter(
|
|
1975
|
+
(t) => t.type === "function"
|
|
1976
|
+
);
|
|
1977
|
+
const systemPrompt = resolvedProtocol.formatTools({
|
|
1978
|
+
tools: functionTools,
|
|
1979
|
+
toolSystemPromptTemplate
|
|
1980
|
+
});
|
|
1981
|
+
const processedPrompt = convertToolPrompt(
|
|
1982
|
+
(_b = params.prompt) != null ? _b : [],
|
|
1983
|
+
resolvedProtocol,
|
|
1984
|
+
extractOnErrorOption(params.providerOptions)
|
|
1985
|
+
);
|
|
1986
|
+
const finalPrompt = ((_c = processedPrompt[0]) == null ? void 0 : _c.role) === "system" ? [
|
|
1987
|
+
{
|
|
1988
|
+
role: "system",
|
|
1989
|
+
content: systemPrompt + "\n\n" + processedPrompt[0].content
|
|
1990
|
+
},
|
|
1991
|
+
...processedPrompt.slice(1)
|
|
1992
|
+
] : [
|
|
1993
|
+
{
|
|
1994
|
+
role: "system",
|
|
1995
|
+
content: systemPrompt
|
|
1996
|
+
},
|
|
1997
|
+
...processedPrompt
|
|
1998
|
+
];
|
|
1999
|
+
const baseReturnParams = {
|
|
2000
|
+
...params,
|
|
2001
|
+
prompt: finalPrompt,
|
|
2002
|
+
tools: [],
|
|
2003
|
+
toolChoice: void 0,
|
|
2004
|
+
providerOptions: {
|
|
2005
|
+
...params.providerOptions || {},
|
|
2006
|
+
toolCallMiddleware: {
|
|
2007
|
+
...params.providerOptions && typeof params.providerOptions === "object" && params.providerOptions.toolCallMiddleware || {},
|
|
2008
|
+
// INTERNAL: used by the middleware to propagate the names of custom
|
|
2009
|
+
// function tools into downstream handlers (stream/generate) when
|
|
2010
|
+
// providers strip or ignore `params.tools`. Not a stable public API.
|
|
2011
|
+
toolNames: functionTools.map((t) => t.name)
|
|
2012
|
+
}
|
|
2013
|
+
}
|
|
2014
|
+
};
|
|
2015
|
+
if (((_d = params.toolChoice) == null ? void 0 : _d.type) === "none") {
|
|
2016
|
+
throw new Error(
|
|
2017
|
+
"The 'none' toolChoice type is not supported by this middleware. Please use 'auto', 'required', or specify a tool name."
|
|
2018
|
+
);
|
|
2019
|
+
}
|
|
2020
|
+
if (((_e = params.toolChoice) == null ? void 0 : _e.type) === "tool") {
|
|
2021
|
+
const selectedToolName = params.toolChoice.toolName;
|
|
2022
|
+
const providerDefinedMatch = ((_f = params.tools) != null ? _f : []).find((t) => {
|
|
2023
|
+
if (t.type === "function") return false;
|
|
2024
|
+
const anyTool = t;
|
|
2025
|
+
return anyTool.id === selectedToolName || anyTool.name === selectedToolName;
|
|
2026
|
+
});
|
|
2027
|
+
if (providerDefinedMatch) {
|
|
2028
|
+
throw new Error(
|
|
2029
|
+
"Provider-defined tools are not supported by this middleware. Please use custom tools."
|
|
2030
|
+
);
|
|
2031
|
+
}
|
|
2032
|
+
const selectedTool = ((_g = params.tools) != null ? _g : []).find(
|
|
2033
|
+
(t) => t.type === "function" && t.name === selectedToolName
|
|
2034
|
+
);
|
|
2035
|
+
if (!selectedTool) {
|
|
2036
|
+
throw new Error(
|
|
2037
|
+
`Tool with name '${selectedToolName}' not found in params.tools.`
|
|
2038
|
+
);
|
|
2039
|
+
}
|
|
2040
|
+
return {
|
|
2041
|
+
...baseReturnParams,
|
|
2042
|
+
responseFormat: {
|
|
2043
|
+
type: "json",
|
|
2044
|
+
schema: {
|
|
2045
|
+
type: "object",
|
|
2046
|
+
properties: {
|
|
2047
|
+
name: {
|
|
2048
|
+
const: selectedTool.name
|
|
2049
|
+
},
|
|
2050
|
+
arguments: selectedTool.inputSchema
|
|
2051
|
+
},
|
|
2052
|
+
required: ["name", "arguments"]
|
|
2053
|
+
},
|
|
2054
|
+
name: selectedTool.name,
|
|
2055
|
+
description: typeof selectedTool.description === "string" ? selectedTool.description : void 0
|
|
2056
|
+
},
|
|
2057
|
+
providerOptions: {
|
|
2058
|
+
...baseReturnParams.providerOptions || {},
|
|
2059
|
+
toolCallMiddleware: {
|
|
2060
|
+
...baseReturnParams.providerOptions && typeof baseReturnParams.providerOptions === "object" && baseReturnParams.providerOptions.toolCallMiddleware || {},
|
|
2061
|
+
// INTERNAL: used by the middleware to activate the tool-choice
|
|
2062
|
+
// fast-path in handlers. Not a stable public API.
|
|
2063
|
+
toolChoice: params.toolChoice
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
2066
|
+
};
|
|
2067
|
+
}
|
|
2068
|
+
if (((_h = params.toolChoice) == null ? void 0 : _h.type) === "required") {
|
|
2069
|
+
if (!params.tools || params.tools.length === 0) {
|
|
2070
|
+
throw new Error(
|
|
2071
|
+
"Tool choice type 'required' is set, but no tools are provided in params.tools."
|
|
2072
|
+
);
|
|
2073
|
+
}
|
|
2074
|
+
return {
|
|
2075
|
+
...baseReturnParams,
|
|
2076
|
+
responseFormat: {
|
|
2077
|
+
type: "json",
|
|
2078
|
+
schema: createDynamicIfThenElseSchema(functionTools)
|
|
2079
|
+
},
|
|
2080
|
+
providerOptions: {
|
|
2081
|
+
...baseReturnParams.providerOptions || {},
|
|
2082
|
+
toolCallMiddleware: {
|
|
2083
|
+
...baseReturnParams.providerOptions && typeof baseReturnParams.providerOptions === "object" && baseReturnParams.providerOptions.toolCallMiddleware || {},
|
|
2084
|
+
// INTERNAL: used by the middleware to activate the tool-choice
|
|
2085
|
+
// fast-path in handlers. Not a stable public API.
|
|
2086
|
+
toolChoice: { type: "required" }
|
|
2087
|
+
}
|
|
2088
|
+
}
|
|
2089
|
+
};
|
|
2090
|
+
}
|
|
2091
|
+
return baseReturnParams;
|
|
2092
|
+
}
|
|
2093
|
+
function convertToolPrompt(prompt, resolvedProtocol, providerOptions) {
|
|
2094
|
+
const processedPrompt = prompt.map((message) => {
|
|
2095
|
+
var _a;
|
|
2096
|
+
if (message.role === "assistant") {
|
|
2097
|
+
const newContent = [];
|
|
2098
|
+
for (const content of message.content) {
|
|
2099
|
+
if (isToolCallContent(content)) {
|
|
2100
|
+
newContent.push({
|
|
2101
|
+
type: "text",
|
|
2102
|
+
text: resolvedProtocol.formatToolCall(content)
|
|
2103
|
+
});
|
|
2104
|
+
} else if (content.type === "text") {
|
|
2105
|
+
newContent.push(content);
|
|
2106
|
+
} else if (content.type === "reasoning") {
|
|
2107
|
+
newContent.push(content);
|
|
2108
|
+
} else {
|
|
2109
|
+
const options = extractOnErrorOption(providerOptions);
|
|
2110
|
+
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
|
|
2111
|
+
options,
|
|
2112
|
+
"tool-call-middleware: unknown assistant content; stringifying for provider compatibility",
|
|
2113
|
+
{ content }
|
|
2114
|
+
);
|
|
2115
|
+
newContent.push({
|
|
2116
|
+
type: "text",
|
|
2117
|
+
text: JSON.stringify(content)
|
|
2118
|
+
});
|
|
2119
|
+
}
|
|
2120
|
+
}
|
|
2121
|
+
const onlyText = newContent.every((c) => c.type === "text");
|
|
2122
|
+
const condensedAssistant = onlyText ? [
|
|
2123
|
+
{
|
|
2124
|
+
type: "text",
|
|
2125
|
+
text: newContent.map((c) => c.text).join("\n")
|
|
2126
|
+
}
|
|
2127
|
+
] : newContent;
|
|
2128
|
+
return { role: "assistant", content: condensedAssistant };
|
|
2129
|
+
}
|
|
2130
|
+
if (message.role === "tool") {
|
|
2131
|
+
return {
|
|
2132
|
+
role: "user",
|
|
2133
|
+
// Map tool results to text response blocks, then condense into a single text block
|
|
2134
|
+
content: [
|
|
2135
|
+
{
|
|
2136
|
+
type: "text",
|
|
2137
|
+
text: message.content.map(
|
|
2138
|
+
(toolResult) => isToolResultPart(toolResult) ? resolvedProtocol.formatToolResponse(toolResult) : resolvedProtocol.formatToolResponse(
|
|
2139
|
+
toolResult
|
|
2140
|
+
)
|
|
2141
|
+
).join("\n")
|
|
2142
|
+
}
|
|
2143
|
+
]
|
|
2144
|
+
};
|
|
2145
|
+
}
|
|
2146
|
+
return message;
|
|
2147
|
+
});
|
|
2148
|
+
for (let i = 0; i < processedPrompt.length; i++) {
|
|
2149
|
+
const msg = processedPrompt[i];
|
|
2150
|
+
if (Array.isArray(msg.content)) {
|
|
2151
|
+
const allText = msg.content.every(
|
|
2152
|
+
(c) => (c == null ? void 0 : c.type) === "text"
|
|
2153
|
+
);
|
|
2154
|
+
if (allText && msg.content.length > 1) {
|
|
2155
|
+
const joinedText = msg.content.map((c) => c.text).join("\n");
|
|
2156
|
+
if (msg.role === "system") {
|
|
2157
|
+
processedPrompt[i] = {
|
|
2158
|
+
role: "system",
|
|
2159
|
+
content: joinedText
|
|
2160
|
+
};
|
|
2161
|
+
} else if (msg.role === "assistant") {
|
|
2162
|
+
processedPrompt[i] = {
|
|
2163
|
+
role: "assistant",
|
|
2164
|
+
content: [
|
|
2165
|
+
{
|
|
2166
|
+
type: "text",
|
|
2167
|
+
text: joinedText
|
|
2168
|
+
}
|
|
2169
|
+
]
|
|
2170
|
+
};
|
|
2171
|
+
} else {
|
|
2172
|
+
processedPrompt[i] = {
|
|
2173
|
+
role: "user",
|
|
2174
|
+
content: [
|
|
2175
|
+
{
|
|
2176
|
+
type: "text",
|
|
2177
|
+
text: joinedText
|
|
2178
|
+
}
|
|
2179
|
+
]
|
|
2180
|
+
};
|
|
2181
|
+
}
|
|
2182
|
+
}
|
|
2183
|
+
}
|
|
2184
|
+
}
|
|
2185
|
+
for (let i = processedPrompt.length - 1; i > 0; i--) {
|
|
2186
|
+
const current = processedPrompt[i];
|
|
2187
|
+
const prev = processedPrompt[i - 1];
|
|
2188
|
+
if (current.role === "user" && prev.role === "user") {
|
|
2189
|
+
const prevContent = prev.content.map((c) => c.type === "text" ? c.text : "").join("\n");
|
|
2190
|
+
const currentContent = current.content.map((c) => c.type === "text" ? c.text : "").join("\n");
|
|
2191
|
+
processedPrompt[i - 1] = {
|
|
2192
|
+
role: "user",
|
|
2193
|
+
content: [{ type: "text", text: prevContent + "\n" + currentContent }]
|
|
2194
|
+
};
|
|
2195
|
+
processedPrompt.splice(i, 1);
|
|
2196
|
+
}
|
|
2197
|
+
}
|
|
2198
|
+
return processedPrompt;
|
|
2199
|
+
}
|
|
2200
|
+
|
|
2201
|
+
// src/tool-call-middleware.ts
|
|
2202
|
+
function createToolMiddleware({
|
|
2203
|
+
protocol,
|
|
2204
|
+
toolSystemPromptTemplate
|
|
2205
|
+
}) {
|
|
2206
|
+
const resolvedProtocol = isProtocolFactory(protocol) ? protocol() : protocol;
|
|
2207
|
+
return {
|
|
2208
|
+
middlewareVersion: "v2",
|
|
2209
|
+
wrapStream: async ({ doStream, doGenerate, params }) => {
|
|
2210
|
+
if (isToolChoiceActive(params)) {
|
|
2211
|
+
return toolChoiceStream({
|
|
2212
|
+
doGenerate,
|
|
2213
|
+
options: extractOnErrorOption(params.providerOptions)
|
|
2214
|
+
});
|
|
2215
|
+
} else {
|
|
2216
|
+
return wrapStream({
|
|
2217
|
+
protocol: resolvedProtocol,
|
|
2218
|
+
doStream,
|
|
2219
|
+
doGenerate,
|
|
2220
|
+
params
|
|
2221
|
+
});
|
|
2222
|
+
}
|
|
2223
|
+
},
|
|
2224
|
+
wrapGenerate: async ({ doGenerate, params }) => wrapGenerate({
|
|
2225
|
+
protocol: resolvedProtocol,
|
|
2226
|
+
doGenerate,
|
|
2227
|
+
params
|
|
2228
|
+
}),
|
|
2229
|
+
transformParams: async ({
|
|
2230
|
+
params
|
|
2231
|
+
}) => {
|
|
2232
|
+
return transformParams({
|
|
2233
|
+
protocol: resolvedProtocol,
|
|
2234
|
+
toolSystemPromptTemplate,
|
|
2235
|
+
params
|
|
2236
|
+
});
|
|
2237
|
+
}
|
|
2238
|
+
};
|
|
2239
|
+
}
|
|
1558
2240
|
|
|
1559
2241
|
// src/index.ts
|
|
1560
2242
|
var gemmaToolMiddleware = createToolMiddleware({
|
|
@@ -1562,8 +2244,9 @@ var gemmaToolMiddleware = createToolMiddleware({
|
|
|
1562
2244
|
// Customize the tool call delimiters to use markdown code fences
|
|
1563
2245
|
{
|
|
1564
2246
|
toolCallStart: "```tool_call\n",
|
|
1565
|
-
|
|
1566
|
-
//
|
|
2247
|
+
// TODO: Support specifying multiple possible tags,
|
|
2248
|
+
// e.g., for gemma, it would be nice to be able to set both `` and ``` at the same time.
|
|
2249
|
+
toolCallEnd: "\n```",
|
|
1567
2250
|
toolResponseStart: "```tool_response\n",
|
|
1568
2251
|
toolResponseEnd: "\n```"
|
|
1569
2252
|
}
|
|
@@ -1594,15 +2277,16 @@ For each function call return a json object with function name and arguments wit
|
|
|
1594
2277
|
}
|
|
1595
2278
|
});
|
|
1596
2279
|
var xmlToolMiddleware = createToolMiddleware({
|
|
1597
|
-
protocol:
|
|
2280
|
+
protocol: morphXmlProtocol,
|
|
1598
2281
|
toolSystemPromptTemplate(tools) {
|
|
1599
|
-
return `You are
|
|
2282
|
+
return `You are a function calling AI model.
|
|
1600
2283
|
You are provided with function signatures within <tools></tools> XML tags.
|
|
1601
2284
|
You may call one or more functions to assist with the user query.
|
|
1602
2285
|
Don't make assumptions about what values to plug into functions.
|
|
1603
2286
|
Here are the available tools: <tools>${tools}</tools>
|
|
1604
|
-
For
|
|
1605
|
-
|
|
2287
|
+
For a function call, return exactly one XML element whose tag name matches the tool's name, and nothing else.
|
|
2288
|
+
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.
|
|
2289
|
+
Examples:
|
|
1606
2290
|
<get_weather>
|
|
1607
2291
|
<location>
|
|
1608
2292
|
San Fransisco
|
|
@@ -1615,7 +2299,7 @@ export {
|
|
|
1615
2299
|
gemmaToolMiddleware,
|
|
1616
2300
|
hermesToolMiddleware,
|
|
1617
2301
|
jsonMixProtocol,
|
|
1618
|
-
|
|
2302
|
+
morphXmlProtocol,
|
|
1619
2303
|
xmlToolMiddleware
|
|
1620
2304
|
};
|
|
1621
2305
|
//# sourceMappingURL=index.js.map
|