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