@ai-sdk-tool/parser 2.0.15 → 2.1.0

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
@@ -7,91 +7,6 @@ var __export = (target, all) => {
7
7
  // src/tool-call-middleware.ts
8
8
  import { generateId as generateId2 } from "@ai-sdk/provider-utils";
9
9
 
10
- // src/utils/conv-tool-prompt.ts
11
- function convertToolPrompt({
12
- paramsPrompt,
13
- paramsTools,
14
- toolSystemPromptTemplate,
15
- toolCallTag,
16
- toolCallEndTag,
17
- toolResponseTag,
18
- toolResponseEndTag
19
- }) {
20
- const processedPrompt = paramsPrompt.map((message) => {
21
- if (message.role === "assistant") {
22
- const mergedContents = [];
23
- for (const content of message.content) {
24
- if (content.type === "tool-call") {
25
- mergedContents.push({
26
- type: "text",
27
- text: `${toolCallTag}${JSON.stringify({
28
- arguments: content.input,
29
- name: content.toolName
30
- })}${toolCallEndTag}`
31
- });
32
- } else {
33
- mergedContents.push(content);
34
- }
35
- }
36
- const finalContents = [];
37
- for (const item of mergedContents) {
38
- if (finalContents.length > 0 && item.type === "text" && finalContents[finalContents.length - 1].type === "text") {
39
- const last = finalContents[finalContents.length - 1];
40
- if (last.type === "text" && item.type === "text") {
41
- finalContents[finalContents.length - 1] = {
42
- type: "text",
43
- text: last.text + "\n" + item.text
44
- };
45
- }
46
- } else {
47
- finalContents.push(item);
48
- }
49
- }
50
- return {
51
- role: "assistant",
52
- content: finalContents
53
- };
54
- } else if (message.role === "tool") {
55
- return {
56
- role: "user",
57
- content: [
58
- {
59
- type: "text",
60
- text: message.content.map(
61
- (content) => `${toolResponseTag}${JSON.stringify({
62
- toolName: content.toolName,
63
- // TODO: If the tool result part contains content, modify to respect and include it.
64
- result: content.output
65
- })}${toolResponseEndTag}`
66
- ).join("\n")
67
- }
68
- ]
69
- };
70
- }
71
- return message;
72
- });
73
- const toolsForPrompt = (paramsTools || []).filter((tool) => tool.type === "function").map((tool) => ({
74
- name: tool.name,
75
- description: tool.type === "function" && typeof tool.description === "string" ? tool.description : void 0,
76
- parameters: tool.inputSchema
77
- }));
78
- const HermesPrompt = toolSystemPromptTemplate(JSON.stringify(toolsForPrompt));
79
- const toolSystemPrompt = processedPrompt[0].role === "system" ? [
80
- {
81
- role: "system",
82
- content: HermesPrompt + "\n\n" + processedPrompt[0].content
83
- },
84
- ...processedPrompt.slice(1)
85
- ] : [
86
- {
87
- role: "system",
88
- content: HermesPrompt
89
- },
90
- ...processedPrompt
91
- ];
92
- return toolSystemPrompt;
93
- }
94
-
95
10
  // src/utils/dynamic-tool-schema.ts
96
11
  function createDynamicIfThenElseSchema(tools) {
97
12
  let currentSchema = {};
@@ -794,161 +709,84 @@ function stringify(obj) {
794
709
  return "null";
795
710
  }
796
711
 
797
- // src/stream-handler.ts
798
- import { generateId } from "@ai-sdk/provider-utils";
799
- async function normalToolStream({
800
- doStream,
801
- toolCallTag,
802
- toolCallEndTag
803
- }) {
712
+ // src/utils/regex.ts
713
+ function escapeRegExp(literal) {
714
+ return literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
715
+ }
716
+
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");
721
+ }
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;
725
+ }
726
+ function hasInputProperty(obj) {
727
+ return typeof obj === "object" && obj !== null && "input" in obj;
728
+ }
729
+
730
+ // src/utils/tools.ts
731
+ function isToolChoiceActive(params) {
732
+ var _a, _b, _c;
733
+ const toolChoice = (_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.toolChoice;
734
+ return !!(typeof params.providerOptions === "object" && params.providerOptions !== null && typeof ((_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware) === "object" && toolChoice && typeof toolChoice === "object" && (toolChoice.type === "tool" || toolChoice.type === "required"));
735
+ }
736
+ function getFunctionTools(params) {
737
+ var _a, _b;
738
+ const rawToolNames = params.providerOptions && typeof params.providerOptions === "object" && ((_a = params.providerOptions.toolCallMiddleware) == null ? void 0 : _a.toolNames) || [];
739
+ const toStringArray = (val) => Array.isArray(val) ? val.filter(
740
+ (item) => typeof item === "string"
741
+ ) : [];
742
+ const toolNames = toStringArray(rawToolNames);
743
+ if (toolNames.length > 0) {
744
+ return toolNames.map((name) => ({
745
+ type: "function",
746
+ name,
747
+ description: "",
748
+ inputSchema: { type: "object" }
749
+ }));
750
+ }
751
+ return ((_b = params.tools) != null ? _b : []).filter(
752
+ (t) => t.type === "function"
753
+ );
754
+ }
755
+
756
+ // src/utils/on-error.ts
757
+ function extractOnErrorOption(providerOptions) {
804
758
  var _a;
805
- const { stream, ...rest } = await doStream();
806
- let isFirstToolCall = true;
807
- let isFirstText = true;
808
- let afterSwitch = false;
809
- let isToolCall = false;
810
- let buffer = "";
811
- let toolCallIndex = -1;
812
- let toolCallBuffer = [];
813
- let currentTextId = null;
814
- let hasEmittedTextStart = false;
815
- const transformStream = new TransformStream({
816
- transform(chunk, controller) {
817
- if (chunk.type === "finish") {
818
- if (isToolCall && (buffer.length > 0 || toolCallIndex >= 0 && toolCallBuffer[toolCallIndex])) {
819
- if (!currentTextId) {
820
- currentTextId = generateId();
821
- controller.enqueue({
822
- type: "text-start",
823
- id: currentTextId
824
- });
825
- hasEmittedTextStart = true;
826
- }
827
- const incompleteContent = (toolCallBuffer[toolCallIndex] || "") + buffer;
828
- controller.enqueue({
829
- type: "text-delta",
830
- id: currentTextId,
831
- delta: toolCallTag + incompleteContent
832
- });
833
- if (toolCallIndex >= 0) {
834
- toolCallBuffer = toolCallBuffer.slice(0, toolCallIndex);
835
- }
836
- }
837
- if (currentTextId && hasEmittedTextStart) {
838
- controller.enqueue({
839
- type: "text-end",
840
- id: currentTextId
841
- });
842
- currentTextId = null;
843
- hasEmittedTextStart = false;
844
- }
845
- if (toolCallBuffer.length > 0) {
846
- toolCallBuffer.forEach((toolCall) => {
847
- try {
848
- const parsedToolCall = relaxed_json_exports.parse(toolCall);
849
- controller.enqueue({
850
- type: "tool-call",
851
- toolCallId: generateId(),
852
- toolName: parsedToolCall.name,
853
- input: JSON.stringify(parsedToolCall.arguments)
854
- });
855
- } catch (e) {
856
- console.error(`Error parsing tool call: ${toolCall}`, e);
857
- const errorId = generateId();
858
- controller.enqueue({
859
- type: "text-start",
860
- id: errorId
861
- });
862
- controller.enqueue({
863
- type: "text-delta",
864
- id: errorId,
865
- delta: `${toolCallTag}${toolCall}${toolCallEndTag}`
866
- });
867
- controller.enqueue({
868
- type: "text-end",
869
- id: errorId
870
- });
871
- }
872
- });
873
- }
874
- controller.enqueue(chunk);
875
- return;
876
- } else if (chunk.type !== "text-delta") {
877
- controller.enqueue(chunk);
878
- return;
879
- }
880
- buffer += chunk.delta;
881
- function publish(text) {
882
- if (text.length > 0 || isToolCall) {
883
- const prefix = afterSwitch && (isToolCall ? !isFirstToolCall : !isFirstText) ? "\n" : "";
884
- if (isToolCall) {
885
- if (currentTextId && hasEmittedTextStart) {
886
- controller.enqueue({
887
- type: "text-end",
888
- id: currentTextId
889
- });
890
- currentTextId = null;
891
- hasEmittedTextStart = false;
892
- }
893
- if (!toolCallBuffer[toolCallIndex]) {
894
- toolCallBuffer[toolCallIndex] = "";
895
- }
896
- toolCallBuffer[toolCallIndex] += text;
897
- } else if (text.length > 0) {
898
- if (!currentTextId) {
899
- currentTextId = generateId();
900
- controller.enqueue({
901
- type: "text-start",
902
- id: currentTextId
903
- });
904
- hasEmittedTextStart = true;
905
- }
906
- controller.enqueue({
907
- type: "text-delta",
908
- id: currentTextId,
909
- delta: prefix + text
910
- });
911
- }
912
- afterSwitch = false;
913
- if (isToolCall) {
914
- isFirstToolCall = false;
915
- } else {
916
- isFirstText = false;
917
- }
918
- }
919
- }
920
- do {
921
- const nextTag = isToolCall ? toolCallEndTag : toolCallTag;
922
- const startIndex = getPotentialStartIndex(buffer, nextTag);
923
- if (startIndex == null) {
924
- publish(buffer);
925
- buffer = "";
926
- break;
927
- }
928
- const foundFullMatch = startIndex + nextTag.length <= buffer.length;
929
- if (foundFullMatch) {
930
- publish(buffer.slice(0, startIndex));
931
- buffer = buffer.slice(startIndex + nextTag.length);
932
- toolCallIndex++;
933
- isToolCall = !isToolCall;
934
- afterSwitch = true;
935
- } else {
936
- break;
937
- }
938
- } while (true);
939
- }
940
- });
941
- return {
942
- stream: (_a = stream == null ? void 0 : stream.pipeThrough(transformStream)) != null ? _a : new ReadableStream(),
943
- ...rest
944
- };
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;
945
764
  }
765
+
766
+ // src/stream-handler.ts
767
+ import { generateId } from "@ai-sdk/provider-utils";
946
768
  async function toolChoiceStream({
947
- doGenerate
769
+ doGenerate,
770
+ options
948
771
  }) {
949
- var _a;
772
+ var _a, _b;
950
773
  const result = await doGenerate();
951
- const toolJson = (result == null ? void 0 : result.content) && result.content.length > 0 && ((_a = result.content[0]) == null ? void 0 : _a.type) === "text" ? JSON.parse(result.content[0].text) : {};
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") {
776
+ 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)
785
+ }
786
+ );
787
+ toolJson = {};
788
+ }
789
+ }
952
790
  const toolCallChunk = {
953
791
  type: "tool-call",
954
792
  toolCallId: generateId(),
@@ -980,156 +818,220 @@ async function toolChoiceStream({
980
818
  }
981
819
 
982
820
  // src/tool-call-middleware.ts
983
- function isToolChoiceActive(params) {
984
- var _a, _b;
985
- const toolChoice = (_b = (_a = params == null ? void 0 : params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.toolChoice;
986
- return typeof params.providerOptions === "object" && params.providerOptions !== null && typeof params.providerOptions.toolCallMiddleware === "object" && toolChoice && typeof toolChoice === "object" && (toolChoice.type === "tool" || toolChoice.type === "required");
821
+ function isProtocolFactory(protocol) {
822
+ return typeof protocol === "function";
987
823
  }
988
824
  function createToolMiddleware({
989
- toolCallTag,
990
- toolCallEndTag,
991
- toolResponseTag,
992
- toolResponseEndTag,
825
+ protocol,
993
826
  toolSystemPromptTemplate
994
827
  }) {
828
+ const resolvedProtocol = isProtocolFactory(protocol) ? protocol() : protocol;
995
829
  return {
996
830
  middlewareVersion: "v2",
997
831
  wrapStream: async ({ doStream, doGenerate, params }) => {
998
832
  if (isToolChoiceActive(params)) {
999
833
  return toolChoiceStream({
1000
- doGenerate
1001
- });
1002
- } else {
1003
- return normalToolStream({
1004
- doStream,
1005
- toolCallTag,
1006
- toolCallEndTag
834
+ doGenerate,
835
+ options: extractOnErrorOption(params.providerOptions)
1007
836
  });
1008
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
+ };
1009
848
  },
1010
849
  wrapGenerate: async ({ doGenerate, params }) => {
1011
- const result = await doGenerate();
1012
- if (result.content.length === 0) {
1013
- return result;
1014
- }
850
+ var _a, _b;
1015
851
  if (isToolChoiceActive(params)) {
1016
- const toolJson = result.content[0].type === "text" ? JSON.parse(result.content[0].text) : {};
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
+ }
1017
871
  return {
1018
- ...result,
872
+ ...result2,
1019
873
  content: [
1020
874
  {
1021
875
  type: "tool-call",
1022
- toolCallType: "function",
1023
876
  toolCallId: generateId2(),
1024
- toolName: toolJson.name || "unknown",
1025
- input: JSON.stringify(toolJson.arguments || {})
877
+ toolName: parsed.name || "unknown",
878
+ input: JSON.stringify(parsed.arguments || {})
1026
879
  }
1027
880
  ]
1028
881
  };
1029
882
  }
1030
- const toolCallRegex = new RegExp(
1031
- `${toolCallTag}(.*?)(?:${toolCallEndTag}|$)`,
1032
- "gs"
1033
- );
1034
- const newContent = result.content.flatMap(
1035
- (contentItem) => {
1036
- if (contentItem.type !== "text" || !contentItem.text.includes(toolCallTag)) {
1037
- return [contentItem];
1038
- }
1039
- const text = contentItem.text;
1040
- const processedElements = [];
1041
- let currentIndex = 0;
1042
- let match;
1043
- const parseAndCreateToolCall = (toolCallJson) => {
1044
- try {
1045
- const parsedToolCall = relaxed_json_exports.parse(toolCallJson);
1046
- if (!parsedToolCall || typeof parsedToolCall.name !== "string" || typeof parsedToolCall.arguments === "undefined") {
1047
- console.error(
1048
- "Failed to parse tool call: Invalid structure",
1049
- toolCallJson
1050
- );
1051
- return null;
1052
- }
1053
- return {
1054
- type: "tool-call",
1055
- toolCallId: generateId2(),
1056
- toolName: parsedToolCall.name,
1057
- // Ensure args is always a JSON string
1058
- input: typeof parsedToolCall.arguments === "string" ? parsedToolCall.arguments : JSON.stringify(parsedToolCall.arguments)
1059
- };
1060
- } catch (error) {
1061
- console.error(
1062
- "Failed to parse tool call JSON:",
1063
- error,
1064
- "JSON:",
1065
- toolCallJson
1066
- );
1067
- return null;
1068
- }
1069
- };
1070
- while ((match = toolCallRegex.exec(text)) !== null) {
1071
- const startIndex = match.index;
1072
- const endIndex = startIndex + match[0].length;
1073
- const toolCallJson = match[1];
1074
- if (startIndex > currentIndex) {
1075
- const textSegment = text.substring(currentIndex, startIndex);
1076
- if (textSegment.trim()) {
1077
- processedElements.push({ type: "text", text: textSegment });
1078
- }
1079
- }
1080
- if (toolCallJson) {
1081
- const toolCallObject = parseAndCreateToolCall(toolCallJson);
1082
- if (toolCallObject) {
1083
- processedElements.push(toolCallObject);
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);
1084
919
  } else {
1085
- console.warn(
1086
- `Could not process tool call, keeping original text: ${match[0]}`
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 }
1087
925
  );
1088
- processedElements.push({ type: "text", text: match[0] });
926
+ newContent.push({
927
+ type: "text",
928
+ text: JSON.stringify(content)
929
+ });
1089
930
  }
1090
931
  }
1091
- currentIndex = endIndex;
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 };
1092
940
  }
1093
- if (currentIndex < text.length) {
1094
- const remainingText = text.substring(currentIndex);
1095
- if (remainingText.trim()) {
1096
- processedElements.push({ type: "text", text: remainingText });
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
+ };
1097
973
  }
1098
974
  }
1099
- return processedElements;
1100
975
  }
1101
- );
1102
- return {
1103
- ...result,
1104
- content: newContent
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;
1105
992
  };
1106
- },
1107
- transformParams: async ({ params }) => {
1108
- var _a, _b, _c, _d;
1109
- const toolSystemPrompt = convertToolPrompt({
1110
- paramsPrompt: params.prompt,
1111
- paramsTools: params.tools,
1112
- toolSystemPromptTemplate,
1113
- toolCallTag,
1114
- toolCallEndTag,
1115
- toolResponseTag,
1116
- toolResponseEndTag
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
1117
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
+ ];
1118
1014
  const baseReturnParams = {
1119
1015
  ...params,
1120
- prompt: toolSystemPrompt,
1121
- // Reset tools and toolChoice to default after prompt transformation
1016
+ prompt: finalPrompt,
1122
1017
  tools: [],
1123
- toolChoice: void 0
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
+ }
1124
1026
  };
1125
- if (((_a = params.toolChoice) == null ? void 0 : _a.type) === "none") {
1027
+ if (((_c = params.toolChoice) == null ? void 0 : _c.type) === "none") {
1126
1028
  throw new Error(
1127
1029
  "The 'none' toolChoice type is not supported by this middleware. Please use 'auto', 'required', or specify a tool name."
1128
1030
  );
1129
1031
  }
1130
- if (((_b = params.toolChoice) == null ? void 0 : _b.type) === "tool") {
1032
+ if (((_d = params.toolChoice) == null ? void 0 : _d.type) === "tool") {
1131
1033
  const selectedToolName = params.toolChoice.toolName;
1132
- const selectedTool = (_c = params.tools) == null ? void 0 : _c.find(
1034
+ const selectedTool = (_e = params.tools) == null ? void 0 : _e.find(
1133
1035
  (tool) => tool.type === "function" ? tool.name === selectedToolName : tool.id === selectedToolName
1134
1036
  );
1135
1037
  if (!selectedTool) {
@@ -1160,13 +1062,15 @@ function createToolMiddleware({
1160
1062
  description: selectedTool.type === "function" && typeof selectedTool.description === "string" ? selectedTool.description : void 0
1161
1063
  },
1162
1064
  providerOptions: {
1065
+ ...baseReturnParams.providerOptions || {},
1163
1066
  toolCallMiddleware: {
1067
+ ...baseReturnParams.providerOptions && typeof baseReturnParams.providerOptions === "object" && baseReturnParams.providerOptions.toolCallMiddleware || {},
1164
1068
  toolChoice: params.toolChoice
1165
1069
  }
1166
1070
  }
1167
1071
  };
1168
1072
  }
1169
- if (((_d = params.toolChoice) == null ? void 0 : _d.type) === "required") {
1073
+ if (((_f = params.toolChoice) == null ? void 0 : _f.type) === "required") {
1170
1074
  if (!params.tools || params.tools.length === 0) {
1171
1075
  throw new Error(
1172
1076
  "Tool choice type 'required' is set, but no tools are provided in params.tools."
@@ -1176,10 +1080,14 @@ function createToolMiddleware({
1176
1080
  ...baseReturnParams,
1177
1081
  responseFormat: {
1178
1082
  type: "json",
1179
- schema: createDynamicIfThenElseSchema(params.tools)
1083
+ schema: createDynamicIfThenElseSchema(
1084
+ params.tools.filter((t) => t.type === "function")
1085
+ )
1180
1086
  },
1181
1087
  providerOptions: {
1088
+ ...baseReturnParams.providerOptions || {},
1182
1089
  toolCallMiddleware: {
1090
+ ...baseReturnParams.providerOptions && typeof baseReturnParams.providerOptions === "object" && baseReturnParams.providerOptions.toolCallMiddleware || {},
1183
1091
  toolChoice: { type: "required" }
1184
1092
  }
1185
1093
  }
@@ -1190,8 +1098,476 @@ function createToolMiddleware({
1190
1098
  };
1191
1099
  }
1192
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
+ }
1181
+ }
1182
+ return processedElements;
1183
+ },
1184
+ createStreamParser({ tools: _tools, options } = { tools: [] }) {
1185
+ let isInsideToolCall = false;
1186
+ let buffer = "";
1187
+ let currentToolCallJson = "";
1188
+ let currentTextId = null;
1189
+ let hasEmittedTextStart = false;
1190
+ return new TransformStream({
1191
+ transform(chunk, controller) {
1192
+ var _a;
1193
+ if (chunk.type === "finish") {
1194
+ if (isInsideToolCall && buffer.length > 0) {
1195
+ if (!currentTextId) {
1196
+ currentTextId = generateId3();
1197
+ controller.enqueue({ type: "text-start", id: currentTextId });
1198
+ hasEmittedTextStart = true;
1199
+ }
1200
+ controller.enqueue({
1201
+ type: "text-delta",
1202
+ id: currentTextId,
1203
+ delta: `${toolCallStart}${buffer}`
1204
+ });
1205
+ buffer = "";
1206
+ } else if (!isInsideToolCall && buffer.length > 0) {
1207
+ if (!currentTextId) {
1208
+ currentTextId = generateId3();
1209
+ controller.enqueue({ type: "text-start", id: currentTextId });
1210
+ hasEmittedTextStart = true;
1211
+ }
1212
+ controller.enqueue({
1213
+ type: "text-delta",
1214
+ id: currentTextId,
1215
+ delta: buffer
1216
+ });
1217
+ buffer = "";
1218
+ }
1219
+ if (currentTextId && hasEmittedTextStart) {
1220
+ controller.enqueue({ type: "text-end", id: currentTextId });
1221
+ currentTextId = null;
1222
+ hasEmittedTextStart = false;
1223
+ }
1224
+ if (currentToolCallJson) {
1225
+ const errorId = generateId3();
1226
+ controller.enqueue({ type: "text-start", id: errorId });
1227
+ controller.enqueue({
1228
+ type: "text-delta",
1229
+ id: errorId,
1230
+ delta: `${toolCallStart}${currentToolCallJson}`
1231
+ });
1232
+ controller.enqueue({ type: "text-end", id: errorId });
1233
+ currentToolCallJson = "";
1234
+ }
1235
+ controller.enqueue(chunk);
1236
+ return;
1237
+ }
1238
+ if (chunk.type !== "text-delta") {
1239
+ controller.enqueue(chunk);
1240
+ return;
1241
+ }
1242
+ buffer += chunk.delta;
1243
+ const publish = (text) => {
1244
+ if (isInsideToolCall) {
1245
+ if (currentTextId && hasEmittedTextStart) {
1246
+ controller.enqueue({ type: "text-end", id: currentTextId });
1247
+ currentTextId = null;
1248
+ hasEmittedTextStart = false;
1249
+ }
1250
+ currentToolCallJson += text;
1251
+ } else if (text.length > 0) {
1252
+ if (!currentTextId) {
1253
+ currentTextId = generateId3();
1254
+ controller.enqueue({ type: "text-start", id: currentTextId });
1255
+ hasEmittedTextStart = true;
1256
+ }
1257
+ controller.enqueue({
1258
+ type: "text-delta",
1259
+ id: currentTextId,
1260
+ delta: text
1261
+ });
1262
+ }
1263
+ };
1264
+ let startIndex;
1265
+ while ((startIndex = getPotentialStartIndex(
1266
+ buffer,
1267
+ isInsideToolCall ? toolCallEnd : toolCallStart
1268
+ )) != null) {
1269
+ const tag = isInsideToolCall ? toolCallEnd : toolCallStart;
1270
+ if (startIndex + tag.length > buffer.length) {
1271
+ break;
1272
+ }
1273
+ publish(buffer.slice(0, startIndex));
1274
+ buffer = buffer.slice(startIndex + tag.length);
1275
+ if (!isInsideToolCall) {
1276
+ currentToolCallJson = "";
1277
+ isInsideToolCall = true;
1278
+ } else {
1279
+ try {
1280
+ const parsedToolCall = relaxed_json_exports.parse(currentToolCallJson);
1281
+ if (currentTextId && hasEmittedTextStart) {
1282
+ controller.enqueue({ type: "text-end", id: currentTextId });
1283
+ currentTextId = null;
1284
+ hasEmittedTextStart = false;
1285
+ }
1286
+ controller.enqueue({
1287
+ type: "tool-call",
1288
+ toolCallId: generateId3(),
1289
+ toolName: parsedToolCall.name,
1290
+ input: JSON.stringify((_a = parsedToolCall.arguments) != null ? _a : {})
1291
+ });
1292
+ } catch (e) {
1293
+ const errorId = generateId3();
1294
+ controller.enqueue({ type: "text-start", id: errorId });
1295
+ controller.enqueue({
1296
+ type: "text-delta",
1297
+ id: errorId,
1298
+ delta: `${toolCallStart}${currentToolCallJson}${toolCallEnd}`
1299
+ });
1300
+ controller.enqueue({ type: "text-end", id: errorId });
1301
+ if (options == null ? void 0 : options.onError) {
1302
+ options.onError(
1303
+ "Could not process streaming JSON tool call; emitting original text.",
1304
+ {
1305
+ toolCall: `${toolCallStart}${currentToolCallJson}${toolCallEnd}`
1306
+ }
1307
+ );
1308
+ }
1309
+ }
1310
+ currentToolCallJson = "";
1311
+ isInsideToolCall = false;
1312
+ }
1313
+ }
1314
+ if (!isInsideToolCall) {
1315
+ const potentialIndex = getPotentialStartIndex(buffer, toolCallStart);
1316
+ if (potentialIndex != null && potentialIndex + toolCallStart.length > buffer.length) {
1317
+ publish(buffer.slice(0, potentialIndex));
1318
+ buffer = buffer.slice(potentialIndex);
1319
+ } else {
1320
+ publish(buffer);
1321
+ buffer = "";
1322
+ }
1323
+ }
1324
+ }
1325
+ });
1326
+ }
1327
+ });
1328
+
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 = () => ({
1333
+ formatTools({ tools, toolSystemPromptTemplate }) {
1334
+ const toolsForPrompt = (tools || []).map((tool) => ({
1335
+ name: tool.name,
1336
+ description: tool.description,
1337
+ parameters: tool.inputSchema
1338
+ }));
1339
+ return toolSystemPromptTemplate(JSON.stringify(toolsForPrompt));
1340
+ },
1341
+ formatToolCall(toolCall) {
1342
+ const builder = new XMLBuilder({ format: true, suppressEmptyNode: true });
1343
+ let args = {};
1344
+ const inputValue = hasInputProperty(toolCall) ? toolCall.input : void 0;
1345
+ if (typeof inputValue === "string") {
1346
+ try {
1347
+ args = JSON.parse(inputValue);
1348
+ } catch (e) {
1349
+ args = inputValue;
1350
+ }
1351
+ } else {
1352
+ args = inputValue;
1353
+ }
1354
+ const xmlContent = builder.build({
1355
+ [toolCall.toolName]: args
1356
+ });
1357
+ return xmlContent;
1358
+ },
1359
+ formatToolResponse(toolResult) {
1360
+ const builder = new XMLBuilder({ format: true });
1361
+ const xmlContent = builder.build({
1362
+ tool_response: {
1363
+ tool_name: toolResult.toolName,
1364
+ result: toolResult.output
1365
+ }
1366
+ });
1367
+ return xmlContent;
1368
+ },
1369
+ parseGeneratedText({ text, tools, options }) {
1370
+ var _a, _b;
1371
+ const toolNames = tools.map((t) => t.name).filter((name) => name != null);
1372
+ if (toolNames.length === 0) {
1373
+ return [{ type: "text", text }];
1374
+ }
1375
+ const toolNamesPattern = toolNames.map((n) => escapeRegExp(n)).join("|");
1376
+ const toolCallRegex = new RegExp(
1377
+ String.raw`<(${toolNamesPattern})>([\s\S]*?)<\/\1>`,
1378
+ "g"
1379
+ );
1380
+ const processedElements = [];
1381
+ let currentIndex = 0;
1382
+ let match;
1383
+ while ((match = toolCallRegex.exec(text)) !== null) {
1384
+ const startIndex = match.index;
1385
+ const toolName = match[1];
1386
+ const toolContent = match[2].trim();
1387
+ if (startIndex > currentIndex) {
1388
+ const textSegment = text.substring(currentIndex, startIndex);
1389
+ if (textSegment.trim()) {
1390
+ processedElements.push({ type: "text", text: textSegment });
1391
+ }
1392
+ }
1393
+ try {
1394
+ const parser = new XMLParser({
1395
+ ignoreAttributes: false,
1396
+ parseTagValue: false,
1397
+ ignoreDeclaration: true,
1398
+ textNodeName: "#text"
1399
+ });
1400
+ const parsedArgs = ((_a = parser.parse(`<root>${toolContent}</root>`)) == null ? void 0 : _a.root) || {};
1401
+ const args = {};
1402
+ for (const k of Object.keys(parsedArgs || {})) {
1403
+ const v = parsedArgs[k];
1404
+ let val = v;
1405
+ if (v && typeof v === "object" && Object.prototype.hasOwnProperty.call(v, "#text")) {
1406
+ val = v == null ? void 0 : v["#text"];
1407
+ }
1408
+ args[k] = typeof val === "string" ? val.trim() : val;
1409
+ }
1410
+ processedElements.push({
1411
+ type: "tool-call",
1412
+ toolCallId: generateId4(),
1413
+ toolName,
1414
+ input: JSON.stringify(args)
1415
+ });
1416
+ } catch (error) {
1417
+ 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 });
1419
+ processedElements.push({ type: "text", text: match[0] });
1420
+ }
1421
+ currentIndex = startIndex + match[0].length;
1422
+ }
1423
+ if (currentIndex < text.length) {
1424
+ const remainingText = text.substring(currentIndex);
1425
+ if (remainingText.trim()) {
1426
+ processedElements.push({ type: "text", text: remainingText });
1427
+ }
1428
+ }
1429
+ return processedElements;
1430
+ },
1431
+ createStreamParser({ tools, options }) {
1432
+ const toolNames = tools.map((t) => t.name).filter((name) => name != null);
1433
+ let buffer = "";
1434
+ let currentToolCall = null;
1435
+ let currentTextId = null;
1436
+ const flushText = (controller, text) => {
1437
+ const content = text != null ? text : buffer;
1438
+ if (content) {
1439
+ if (!currentTextId) {
1440
+ currentTextId = generateId4();
1441
+ controller.enqueue({ type: "text-start", id: currentTextId });
1442
+ }
1443
+ controller.enqueue({
1444
+ type: "text-delta",
1445
+ id: currentTextId,
1446
+ delta: content
1447
+ });
1448
+ if (text === void 0) {
1449
+ buffer = "";
1450
+ }
1451
+ }
1452
+ if (currentTextId && !text) {
1453
+ controller.enqueue({ type: "text-end", id: currentTextId });
1454
+ currentTextId = null;
1455
+ }
1456
+ };
1457
+ return new TransformStream({
1458
+ transform(chunk, controller) {
1459
+ var _a;
1460
+ if (chunk.type !== "text-delta") {
1461
+ if (buffer) flushText(controller);
1462
+ controller.enqueue(chunk);
1463
+ return;
1464
+ }
1465
+ buffer += chunk.delta;
1466
+ while (true) {
1467
+ if (currentToolCall) {
1468
+ const endTag = `</${currentToolCall.name}>`;
1469
+ const endTagIndex = buffer.indexOf(endTag);
1470
+ if (endTagIndex !== -1) {
1471
+ const toolContent = buffer.substring(0, endTagIndex);
1472
+ buffer = buffer.substring(endTagIndex + endTag.length);
1473
+ try {
1474
+ const parser = new XMLParser({
1475
+ ignoreAttributes: false,
1476
+ parseTagValue: false,
1477
+ ignoreDeclaration: true,
1478
+ textNodeName: "#text"
1479
+ });
1480
+ const parsedArgs = ((_a = parser.parse(`<root>${toolContent}</root>`)) == null ? void 0 : _a.root) || {};
1481
+ const args = {};
1482
+ for (const k of Object.keys(parsedArgs || {})) {
1483
+ const v = parsedArgs[k];
1484
+ let val = v;
1485
+ if (v && typeof v === "object" && Object.prototype.hasOwnProperty.call(v, "#text")) {
1486
+ val = v == null ? void 0 : v["#text"];
1487
+ }
1488
+ args[k] = typeof val === "string" ? val.trim() : val;
1489
+ }
1490
+ flushText(controller);
1491
+ controller.enqueue({
1492
+ type: "tool-call",
1493
+ toolCallId: generateId4(),
1494
+ toolName: currentToolCall.name,
1495
+ input: JSON.stringify(args)
1496
+ });
1497
+ } catch (e) {
1498
+ const originalCallText = `<${currentToolCall.name}>${toolContent}${endTag}`;
1499
+ if (options == null ? void 0 : options.onError) {
1500
+ options.onError(
1501
+ "Could not process streaming XML tool call; emitting original text.",
1502
+ {
1503
+ toolCall: originalCallText,
1504
+ toolName: currentToolCall.name
1505
+ }
1506
+ );
1507
+ }
1508
+ flushText(controller, originalCallText);
1509
+ }
1510
+ currentToolCall = null;
1511
+ } else {
1512
+ break;
1513
+ }
1514
+ } else {
1515
+ let earliestStartTagIndex = -1;
1516
+ let earliestToolName = "";
1517
+ if (toolNames.length > 0) {
1518
+ for (const name of toolNames) {
1519
+ const startTag = `<${name}>`;
1520
+ const index = buffer.indexOf(startTag);
1521
+ if (index !== -1 && (earliestStartTagIndex === -1 || index < earliestStartTagIndex)) {
1522
+ earliestStartTagIndex = index;
1523
+ earliestToolName = name;
1524
+ }
1525
+ }
1526
+ }
1527
+ if (earliestStartTagIndex !== -1) {
1528
+ const textBeforeTag = buffer.substring(0, earliestStartTagIndex);
1529
+ flushText(controller, textBeforeTag);
1530
+ const startTag = `<${earliestToolName}>`;
1531
+ buffer = buffer.substring(
1532
+ earliestStartTagIndex + startTag.length
1533
+ );
1534
+ currentToolCall = { name: earliestToolName, content: "" };
1535
+ } else {
1536
+ break;
1537
+ }
1538
+ }
1539
+ }
1540
+ },
1541
+ flush(controller) {
1542
+ if (currentToolCall) {
1543
+ const unfinishedCall = `<${currentToolCall.name}>${buffer}`;
1544
+ flushText(controller, unfinishedCall);
1545
+ } else if (buffer) {
1546
+ flushText(controller);
1547
+ }
1548
+ if (currentTextId) {
1549
+ controller.enqueue({ type: "text-end", id: currentTextId });
1550
+ }
1551
+ }
1552
+ });
1553
+ }
1554
+ });
1555
+
1556
+ // src/protocols/dummy-protocol.ts
1557
+ import { generateId as generateId5 } from "@ai-sdk/provider-utils";
1558
+
1193
1559
  // src/index.ts
1194
1560
  var gemmaToolMiddleware = createToolMiddleware({
1561
+ protocol: jsonMixProtocol(
1562
+ // Customize the tool call delimiters to use markdown code fences
1563
+ {
1564
+ toolCallStart: "```tool_call\n",
1565
+ toolCallEnd: "\n``",
1566
+ // two backticks are more common in gemma output @
1567
+ toolResponseStart: "```tool_response\n",
1568
+ toolResponseEnd: "\n```"
1569
+ }
1570
+ ),
1195
1571
  toolSystemPromptTemplate(tools) {
1196
1572
  return `You have access to functions. If you decide to invoke any of the function(s),
1197
1573
  you MUST put it in the format of markdown code fence block with the language name of tool_call , e.g.
@@ -1200,34 +1576,46 @@ you MUST put it in the format of markdown code fence block with the language nam
1200
1576
  \`\`\`
1201
1577
  You SHOULD NOT include any other text in the response if you call a function
1202
1578
  ${tools}`;
1203
- },
1204
- toolCallTag: "```tool_call\n",
1205
- toolCallEndTag: "\n``",
1206
- // two backticks are more common in gemma output
1207
- toolResponseTag: "```tool_response\n",
1208
- toolResponseEndTag: "\n```"
1579
+ }
1209
1580
  });
1210
1581
  var hermesToolMiddleware = createToolMiddleware({
1582
+ protocol: jsonMixProtocol,
1211
1583
  toolSystemPromptTemplate(tools) {
1212
1584
  return `You are a function calling AI model.
1213
1585
  You are provided with function signatures within <tools></tools> XML tags.
1214
1586
  You may call one or more functions to assist with the user query.
1215
1587
  Don't make assumptions about what values to plug into functions.
1216
1588
  Here are the available tools: <tools>${tools}</tools>
1217
- Use the following pydantic model json schema for each tool call you will make: {'title': 'FunctionCall', 'type': 'object', 'properties': {'arguments': {'title': 'Arguments', 'type': 'object'}, 'name': {'title': 'Name', 'type': 'string'}}, 'required': ['arguments', 'name']}
1589
+ Use the following pydantic model json schema for each tool call you will make: {"title": "FunctionCall", "type": "object", "properties": {"arguments": {"title": "Arguments", "type": "object"}, "name": {"title": "Name", "type": "string"}}, "required": ["arguments", "name"]}
1218
1590
  For each function call return a json object with function name and arguments within <tool_call></tool_call> XML tags as follows:
1219
1591
  <tool_call>
1220
- {'arguments': <args-dict>, 'name': <function-name>}
1592
+ {"name": "<function-name>", "arguments": <args-dict>}
1221
1593
  </tool_call>`;
1222
- },
1223
- toolCallTag: "<tool_call>",
1224
- toolCallEndTag: "</tool_call>",
1225
- toolResponseTag: "<tool_response>",
1226
- toolResponseEndTag: "</tool_response>"
1594
+ }
1595
+ });
1596
+ var xmlToolMiddleware = createToolMiddleware({
1597
+ protocol: xmlProtocol,
1598
+ toolSystemPromptTemplate(tools) {
1599
+ return `You are KorinAI, a function-calling AI model.
1600
+ You are provided with function signatures within <tools></tools> XML tags.
1601
+ You may call one or more functions to assist with the user query.
1602
+ Don't make assumptions about what values to plug into functions.
1603
+ 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):
1606
+ <get_weather>
1607
+ <location>
1608
+ San Fransisco
1609
+ </location>
1610
+ </get_weather>`;
1611
+ }
1227
1612
  });
1228
1613
  export {
1229
1614
  createToolMiddleware,
1230
1615
  gemmaToolMiddleware,
1231
- hermesToolMiddleware
1616
+ hermesToolMiddleware,
1617
+ jsonMixProtocol,
1618
+ xmlProtocol,
1619
+ xmlToolMiddleware
1232
1620
  };
1233
1621
  //# sourceMappingURL=index.js.map