@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/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/tool-call-middleware.ts
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(text, options.reviver);
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
- const newtext = tokens.reduce((str, token) => {
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 newtext2 = tokens.reduce((str, token) => str + token.match, "");
684
- return JSON.parse(newtext2, options.reviver);
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/regex.ts
713
- function escapeRegExp(literal) {
714
- return literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
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/type-guards.ts
718
- function isToolCallContent(content) {
719
- return content.type === "tool-call" && typeof content.toolName === "string" && // input may be a JSON string or an already-parsed object depending on provider/runtime
720
- (typeof content.input === "string" || typeof content.input === "object");
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 isToolResultPart(content) {
723
- const c = content;
724
- return !!c && c.type === "tool-result" && typeof c.toolName === "string" && typeof c.toolCallId === "string" && "output" in c;
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 hasInputProperty(obj) {
727
- return typeof obj === "object" && obj !== null && "input" in obj;
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 rawToolNames = params.providerOptions && typeof params.providerOptions === "object" && ((_a = params.providerOptions.toolCallMiddleware) == null ? void 0 : _a.toolNames) || [];
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 ((_b = params.tools) != null ? _b : []).filter(
752
- (t) => t.type === "function"
753
- );
1046
+ return [];
754
1047
  }
755
1048
 
756
- // src/utils/on-error.ts
757
- function extractOnErrorOption(providerOptions) {
758
- var _a;
759
- if (providerOptions && typeof providerOptions === "object") {
760
- const onError = (_a = providerOptions.toolCallMiddleware) == null ? void 0 : _a.onError;
761
- return onError ? { onError } : void 0;
762
- }
763
- return void 0;
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/stream-handler.ts
767
- import { generateId } from "@ai-sdk/provider-utils";
768
- async function toolChoiceStream({
769
- doGenerate,
770
- options
771
- }) {
772
- var _a, _b;
773
- const result = await doGenerate();
774
- let toolJson = {};
775
- if ((result == null ? void 0 : result.content) && result.content.length > 0 && ((_a = result.content[0]) == null ? void 0 : _a.type) === "text") {
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
- toolJson = JSON.parse(result.content[0].text);
778
- } catch (error) {
779
- (_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
780
- options,
781
- "Failed to parse toolChoice JSON from streamed model output",
782
- {
783
- text: result.content[0].text,
784
- error: error instanceof Error ? error.message : String(error)
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
- toolJson = {};
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
- const toolCallChunk = {
791
- type: "tool-call",
792
- toolCallId: generateId(),
793
- toolName: toolJson.name || "unknown",
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 = generateId3();
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 = generateId3();
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 = generateId3();
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 = generateId3();
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: generateId3(),
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 = generateId3();
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 generateId4 } from "@ai-sdk/provider-utils";
1331
- import { XMLParser, XMLBuilder } from "fast-xml-parser";
1332
- var xmlProtocol = () => ({
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: generateId4(),
1454
+ toolCallId: generateId3(),
1413
1455
  toolName,
1414
- input: JSON.stringify(args)
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
- (_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(options, message, { toolCall: match[0], toolName, error });
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 = generateId4();
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: generateId4(),
1608
+ toolCallId: generateId3(),
1494
1609
  toolName: currentToolCall.name,
1495
- input: JSON.stringify(args)
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/protocols/dummy-protocol.ts
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
- toolCallEnd: "\n``",
1566
- // two backticks are more common in gemma output @
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: xmlProtocol,
2280
+ protocol: morphXmlProtocol,
1598
2281
  toolSystemPromptTemplate(tools) {
1599
- return `You are KorinAI, a function-calling AI model.
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 each function call return a tool call in an XML tag that matches the tool's name, and nothing else.
1605
- Example KorinAI-style call (text form):
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
- xmlProtocol,
2302
+ morphXmlProtocol,
1619
2303
  xmlToolMiddleware
1620
2304
  };
1621
2305
  //# sourceMappingURL=index.js.map