@ai-sdk-tool/parser 2.0.16 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4,93 +4,8 @@ var __export = (target, all) => {
4
4
  __defProp(target, name, { get: all[name], enumerable: true });
5
5
  };
6
6
 
7
- // src/tool-call-middleware.ts
8
- import { generateId as generateId2 } from "@ai-sdk/provider-utils";
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
- }
7
+ // src/stream-handler.ts
8
+ import { generateId } from "@ai-sdk/provider-utils";
94
9
 
95
10
  // src/utils/dynamic-tool-schema.ts
96
11
  function createDynamicIfThenElseSchema(tools) {
@@ -500,7 +415,6 @@ function appendPair(state, obj, key, value) {
500
415
  }
501
416
  function parsePair(tokens, state, obj) {
502
417
  let token = skipPunctuation(tokens, state, [":", "string", "number", "atom"]);
503
- let key;
504
418
  let value;
505
419
  if (token.type !== "string") {
506
420
  raiseUnexpected(state, token, "string key");
@@ -550,7 +464,7 @@ function parsePair(tokens, state, obj) {
550
464
  }
551
465
  }
552
466
  checkDuplicates(state, obj, token);
553
- key = String(token.value);
467
+ const key = String(token.value);
554
468
  skipColon(tokens, state);
555
469
  value = parseAny(tokens, state);
556
470
  appendPair(state, obj, key, value);
@@ -721,7 +635,10 @@ function parse(text, optsOrReviver) {
721
635
  if (!options.relaxed && !options.warnings && !options.tolerant) {
722
636
  if (!options.duplicate) {
723
637
  } else {
724
- return JSON.parse(text, options.reviver);
638
+ return JSON.parse(
639
+ text,
640
+ options.reviver
641
+ );
725
642
  }
726
643
  }
727
644
  const lexerToUse = options.relaxed ? lexer : strictLexer;
@@ -741,7 +658,7 @@ function parse(text, optsOrReviver) {
741
658
  };
742
659
  return parseAny(tokens, state, true);
743
660
  } else {
744
- const newtext = tokens.reduce((str, token) => {
661
+ tokens.reduce((str, token) => {
745
662
  return str + token.match;
746
663
  }, "");
747
664
  if (!options.relaxed && !options.warnings && !options.tolerant && options.duplicate) {
@@ -765,8 +682,11 @@ function parse(text, optsOrReviver) {
765
682
  } else {
766
683
  tokens = lexer(text);
767
684
  tokens = stripTrailingComma(tokens);
768
- const newtext2 = tokens.reduce((str, token) => str + token.match, "");
769
- return JSON.parse(newtext2, options.reviver);
685
+ const newtext = tokens.reduce((str, token) => str + token.match, "");
686
+ return JSON.parse(
687
+ newtext,
688
+ options.reviver
689
+ );
770
690
  }
771
691
  }
772
692
  }
@@ -794,161 +714,321 @@ function stringify(obj) {
794
714
  return "null";
795
715
  }
796
716
 
797
- // src/stream-handler.ts
798
- import { generateId } from "@ai-sdk/provider-utils";
799
- async function normalToolStream({
800
- doStream,
801
- toolCallTag,
802
- toolCallEndTag
803
- }) {
717
+ // src/utils/regex.ts
718
+ function escapeRegExp(literal) {
719
+ return literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
720
+ }
721
+
722
+ // src/utils/type-guards.ts
723
+ function isToolCallContent(content) {
724
+ return content.type === "tool-call" && typeof content.toolName === "string" && // input may be a JSON string or an already-parsed object depending on provider/runtime
725
+ (typeof content.input === "string" || typeof content.input === "object");
726
+ }
727
+ function isToolResultPart(content) {
728
+ const c = content;
729
+ return !!c && c.type === "tool-result" && typeof c.toolName === "string" && typeof c.toolCallId === "string" && "output" in c;
730
+ }
731
+ function hasInputProperty(obj) {
732
+ return typeof obj === "object" && obj !== null && "input" in obj;
733
+ }
734
+
735
+ // src/utils/tools.ts
736
+ function isToolChoiceActive(params) {
737
+ var _a, _b, _c;
738
+ const toolChoice = (_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.toolChoice;
739
+ 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"));
740
+ }
741
+ function getFunctionTools(params) {
742
+ var _a, _b;
743
+ const functionTools = ((_a = params.tools) != null ? _a : []).filter(
744
+ (t) => t.type === "function"
745
+ );
746
+ if (functionTools.length > 0) return functionTools;
747
+ const rawToolNames = params.providerOptions && typeof params.providerOptions === "object" && ((_b = params.providerOptions.toolCallMiddleware) == null ? void 0 : _b.toolNames) || [];
748
+ const toStringArray = (val) => Array.isArray(val) ? val.filter(
749
+ (item) => typeof item === "string"
750
+ ) : [];
751
+ const toolNames = toStringArray(rawToolNames);
752
+ if (toolNames.length > 0) {
753
+ return toolNames.map((name) => ({
754
+ type: "function",
755
+ name,
756
+ description: "",
757
+ inputSchema: { type: "object" }
758
+ }));
759
+ }
760
+ return [];
761
+ }
762
+
763
+ // src/utils/on-error.ts
764
+ function extractOnErrorOption(providerOptions) {
804
765
  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);
766
+ if (providerOptions && typeof providerOptions === "object") {
767
+ const onError = (_a = providerOptions.toolCallMiddleware) == null ? void 0 : _a.onError;
768
+ return onError ? { onError } : void 0;
769
+ }
770
+ return void 0;
771
+ }
772
+
773
+ // src/utils/coercion.ts
774
+ function unwrapJsonSchema(schema) {
775
+ if (!schema || typeof schema !== "object") return schema;
776
+ const s = schema;
777
+ if (s.jsonSchema && typeof s.jsonSchema === "object") {
778
+ return unwrapJsonSchema(s.jsonSchema);
779
+ }
780
+ return schema;
781
+ }
782
+ function getSchemaType(schema) {
783
+ const unwrapped = unwrapJsonSchema(schema);
784
+ if (!unwrapped || typeof unwrapped !== "object") return void 0;
785
+ const t = unwrapped.type;
786
+ if (typeof t === "string") return t;
787
+ if (Array.isArray(t)) {
788
+ const preferred = [
789
+ "object",
790
+ "array",
791
+ "boolean",
792
+ "number",
793
+ "integer",
794
+ "string"
795
+ ];
796
+ for (const p of preferred) if (t.includes(p)) return p;
797
+ }
798
+ const s = unwrapped;
799
+ if (s && typeof s === "object" && (s.properties || s.additionalProperties)) {
800
+ return "object";
801
+ }
802
+ if (s && typeof s === "object" && (s.items || s.prefixItems)) {
803
+ return "array";
804
+ }
805
+ return void 0;
806
+ }
807
+ function coerceBySchema(value, schema) {
808
+ const unwrapped = unwrapJsonSchema(schema);
809
+ if (!unwrapped || typeof unwrapped !== "object") {
810
+ if (typeof value === "string") {
811
+ const s = value.trim();
812
+ const lower = s.toLowerCase();
813
+ if (lower === "true") return true;
814
+ if (lower === "false") return false;
815
+ if (/^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(s)) {
816
+ const num = Number(s);
817
+ if (Number.isFinite(num)) return num;
818
+ }
819
+ if (s.startsWith("{") && s.endsWith("}") || s.startsWith("[") && s.endsWith("]")) {
820
+ try {
821
+ const parsed = JSON.parse(s);
822
+ return coerceBySchema(parsed, void 0);
823
+ } catch (e) {
824
+ }
825
+ }
826
+ }
827
+ return value;
828
+ }
829
+ const schemaType = getSchemaType(unwrapped);
830
+ if (typeof value === "string") {
831
+ const s = value.trim();
832
+ if (schemaType === "object") {
833
+ try {
834
+ let normalized = s.replace(/'/g, '"');
835
+ normalized = normalized.replace(/^\{\s*\}$/s, "{}");
836
+ const obj = JSON.parse(normalized);
837
+ if (obj && typeof obj === "object" && !Array.isArray(obj)) {
838
+ const props = unwrapped.properties;
839
+ const out = {};
840
+ for (const [k, v] of Object.entries(obj)) {
841
+ const propSchema = props ? props[k] : void 0;
842
+ out[k] = typeof propSchema === "boolean" ? v : coerceBySchema(v, propSchema);
835
843
  }
844
+ return out;
836
845
  }
837
- if (currentTextId && hasEmittedTextStart) {
838
- controller.enqueue({
839
- type: "text-end",
840
- id: currentTextId
841
- });
842
- currentTextId = null;
843
- hasEmittedTextStart = false;
846
+ } catch (e) {
847
+ }
848
+ }
849
+ if (schemaType === "array") {
850
+ try {
851
+ const normalized = s.replace(/'/g, '"');
852
+ const arr = JSON.parse(normalized);
853
+ if (Array.isArray(arr)) {
854
+ const u = unwrapped;
855
+ const prefixItems = Array.isArray(
856
+ u.prefixItems
857
+ ) ? u.prefixItems : void 0;
858
+ const itemsSchema = u.items;
859
+ if (prefixItems && arr.length === prefixItems.length) {
860
+ return arr.map((v, i) => coerceBySchema(v, prefixItems[i]));
861
+ }
862
+ return arr.map((v) => coerceBySchema(v, itemsSchema));
844
863
  }
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
- });
864
+ } catch (e) {
865
+ const csv = s.includes("\n") ? s.split(/\n+/) : s.split(/,\s*/);
866
+ const trimmed = csv.map((x) => x.trim()).filter((x) => x.length > 0);
867
+ const u = unwrapped;
868
+ const prefixItems = Array.isArray(
869
+ u.prefixItems
870
+ ) ? u.prefixItems : void 0;
871
+ const itemsSchema = u.items;
872
+ if (prefixItems && trimmed.length === prefixItems.length) {
873
+ return trimmed.map((x, i) => coerceBySchema(x, prefixItems[i]));
873
874
  }
874
- controller.enqueue(chunk);
875
- return;
876
- } else if (chunk.type !== "text-delta") {
877
- controller.enqueue(chunk);
878
- return;
875
+ return trimmed.map((x) => coerceBySchema(x, itemsSchema));
879
876
  }
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
- }
877
+ }
878
+ }
879
+ if (schemaType === "object" && value && typeof value === "object" && !Array.isArray(value)) {
880
+ const out = {};
881
+ const props = unwrapped.properties;
882
+ for (const [k, v] of Object.entries(value)) {
883
+ const propSchema = props ? props[k] : void 0;
884
+ out[k] = typeof propSchema === "boolean" ? v : coerceBySchema(v, propSchema);
885
+ }
886
+ return out;
887
+ }
888
+ if (schemaType === "array") {
889
+ const u = unwrapped;
890
+ const itemsSchema = u.items;
891
+ const prefixItems = Array.isArray(
892
+ u.prefixItems
893
+ ) ? u.prefixItems : void 0;
894
+ if (Array.isArray(value)) {
895
+ if (prefixItems && value.length === prefixItems.length) {
896
+ return value.map((v, i) => coerceBySchema(v, prefixItems[i]));
897
+ }
898
+ return value.map((v) => coerceBySchema(v, itemsSchema));
899
+ }
900
+ if (value && typeof value === "object") {
901
+ const maybe = value;
902
+ if (Object.prototype.hasOwnProperty.call(maybe, "item")) {
903
+ const items = maybe.item;
904
+ const arr = Array.isArray(items) ? items : [items];
905
+ if (prefixItems && arr.length === prefixItems.length) {
906
+ return arr.map((v, i) => coerceBySchema(v, prefixItems[i]));
918
907
  }
908
+ return arr.map((v) => coerceBySchema(v, itemsSchema));
919
909
  }
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;
910
+ const keys = Object.keys(maybe);
911
+ if (keys.length === 1) {
912
+ const singleKey = keys[0];
913
+ const singleValue = maybe[singleKey];
914
+ if (Array.isArray(singleValue)) {
915
+ const coercedArray = singleValue.map(
916
+ (v) => coerceBySchema(v, itemsSchema)
917
+ );
918
+ return coercedArray;
927
919
  }
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;
920
+ }
921
+ if (keys.length > 0 && keys.every((k) => /^\d+$/.test(k))) {
922
+ const arr = keys.sort((a, b) => Number(a) - Number(b)).map((k) => maybe[k]);
923
+ if (prefixItems && arr.length === prefixItems.length) {
924
+ return arr.map((v, i) => coerceBySchema(v, prefixItems[i]));
937
925
  }
938
- } while (true);
926
+ return arr.map((v) => coerceBySchema(v, itemsSchema));
927
+ }
939
928
  }
940
- });
929
+ if (value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
930
+ if (prefixItems && prefixItems.length > 0) {
931
+ return [coerceBySchema(value, prefixItems[0])];
932
+ }
933
+ return [coerceBySchema(value, itemsSchema)];
934
+ }
935
+ }
936
+ if (typeof value === "string") {
937
+ const s = value.trim();
938
+ if (schemaType === "boolean") {
939
+ const lower = s.toLowerCase();
940
+ if (lower === "true") return true;
941
+ if (lower === "false") return false;
942
+ }
943
+ if (schemaType === "number" || schemaType === "integer") {
944
+ if (/^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(s)) {
945
+ const num = Number(s);
946
+ if (Number.isFinite(num)) return num;
947
+ }
948
+ }
949
+ }
950
+ return value;
951
+ }
952
+ function fixToolCallWithSchema(part, tools) {
953
+ var _a;
954
+ if (part.type !== "tool-call") return part;
955
+ const tc = part;
956
+ let args = {};
957
+ if (typeof tc.input === "string") {
958
+ try {
959
+ args = JSON.parse(tc.input);
960
+ } catch (e) {
961
+ return part;
962
+ }
963
+ } else if (tc.input && typeof tc.input === "object") {
964
+ args = tc.input;
965
+ }
966
+ const schema = (_a = tools.find((t) => t.name === tc.toolName)) == null ? void 0 : _a.inputSchema;
967
+ const coerced = coerceBySchema(args, schema);
968
+ return {
969
+ ...part,
970
+ input: JSON.stringify(coerced != null ? coerced : {})
971
+ };
972
+ }
973
+ function coerceToolCallInput(part, tools) {
974
+ return fixToolCallWithSchema(part, tools);
975
+ }
976
+
977
+ // src/utils/protocol.ts
978
+ function isProtocolFactory(protocol) {
979
+ return typeof protocol === "function";
980
+ }
981
+
982
+ // src/stream-handler.ts
983
+ async function wrapStream({
984
+ protocol,
985
+ doStream,
986
+ doGenerate,
987
+ params
988
+ }) {
989
+ var _a;
990
+ if (isToolChoiceActive(params)) {
991
+ return toolChoiceStream({
992
+ doGenerate,
993
+ options: extractOnErrorOption(params.providerOptions)
994
+ });
995
+ }
996
+ const { stream, ...rest } = await doStream();
941
997
  return {
942
- stream: (_a = stream == null ? void 0 : stream.pipeThrough(transformStream)) != null ? _a : new ReadableStream(),
998
+ stream: stream.pipeThrough(
999
+ protocol.createStreamParser({
1000
+ tools: getFunctionTools(params),
1001
+ options: {
1002
+ ...extractOnErrorOption(params.providerOptions),
1003
+ ...(_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware
1004
+ }
1005
+ })
1006
+ ),
943
1007
  ...rest
944
1008
  };
945
1009
  }
946
1010
  async function toolChoiceStream({
947
- doGenerate
1011
+ doGenerate,
1012
+ options
948
1013
  }) {
949
- var _a;
1014
+ var _a, _b;
950
1015
  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) : {};
1016
+ let toolJson = {};
1017
+ if ((result == null ? void 0 : result.content) && result.content.length > 0 && ((_a = result.content[0]) == null ? void 0 : _a.type) === "text") {
1018
+ try {
1019
+ toolJson = JSON.parse(result.content[0].text);
1020
+ } catch (error) {
1021
+ (_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
1022
+ options,
1023
+ "Failed to parse toolChoice JSON from streamed model output",
1024
+ {
1025
+ text: result.content[0].text,
1026
+ error: error instanceof Error ? error.message : String(error)
1027
+ }
1028
+ );
1029
+ toolJson = {};
1030
+ }
1031
+ }
952
1032
  const toolCallChunk = {
953
1033
  type: "tool-call",
954
1034
  toolCallId: generateId(),
@@ -979,219 +1059,955 @@ async function toolChoiceStream({
979
1059
  };
980
1060
  }
981
1061
 
982
- // src/tool-call-middleware.ts
983
- function isToolChoiceActive(params) {
1062
+ // src/generate-handler.ts
1063
+ import { generateId as generateId2 } from "@ai-sdk/provider-utils";
1064
+ async function wrapGenerate({
1065
+ protocol,
1066
+ doGenerate,
1067
+ params
1068
+ }) {
984
1069
  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");
1070
+ if (isToolChoiceActive(params)) {
1071
+ const result2 = await doGenerate();
1072
+ let parsed2 = {};
1073
+ const first = (_a = result2.content) == null ? void 0 : _a[0];
1074
+ if (first && first.type === "text") {
1075
+ try {
1076
+ parsed2 = JSON.parse(first.text);
1077
+ } catch (error) {
1078
+ const options = extractOnErrorOption(params.providerOptions);
1079
+ (_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
1080
+ options,
1081
+ "Failed to parse toolChoice JSON from generated model output",
1082
+ {
1083
+ text: first.text,
1084
+ error: error instanceof Error ? error.message : String(error)
1085
+ }
1086
+ );
1087
+ parsed2 = {};
1088
+ }
1089
+ }
1090
+ const toolCall = {
1091
+ type: "tool-call",
1092
+ toolCallId: generateId2(),
1093
+ toolName: parsed2.name || "unknown",
1094
+ input: JSON.stringify(parsed2.arguments || {})
1095
+ };
1096
+ return {
1097
+ ...result2,
1098
+ content: [toolCall]
1099
+ };
1100
+ }
1101
+ const result = await doGenerate();
1102
+ if (result.content.length === 0) {
1103
+ return result;
1104
+ }
1105
+ const parsed = result.content.flatMap((contentItem) => {
1106
+ var _a2;
1107
+ if (contentItem.type !== "text") {
1108
+ return [contentItem];
1109
+ }
1110
+ return protocol.parseGeneratedText({
1111
+ text: contentItem.text,
1112
+ tools: getFunctionTools(params),
1113
+ options: {
1114
+ ...extractOnErrorOption(params.providerOptions),
1115
+ ...(_a2 = params.providerOptions) == null ? void 0 : _a2.toolCallMiddleware
1116
+ }
1117
+ });
1118
+ });
1119
+ const tools = getFunctionTools(params);
1120
+ const newContent = parsed.map(
1121
+ (part) => coerceToolCallInput(part, tools)
1122
+ );
1123
+ return {
1124
+ ...result,
1125
+ content: newContent
1126
+ };
987
1127
  }
1128
+
1129
+ // src/transform-handler.ts
1130
+ async function transformParams({
1131
+ params,
1132
+ protocol,
1133
+ toolSystemPromptTemplate
1134
+ }) {
1135
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1136
+ const resolvedProtocol = isProtocolFactory(protocol) ? protocol() : protocol;
1137
+ const functionTools = ((_a = params.tools) != null ? _a : []).filter(
1138
+ (t) => t.type === "function"
1139
+ );
1140
+ const systemPrompt = resolvedProtocol.formatTools({
1141
+ tools: functionTools,
1142
+ toolSystemPromptTemplate
1143
+ });
1144
+ const processedPrompt = convertToolPrompt(
1145
+ (_b = params.prompt) != null ? _b : [],
1146
+ resolvedProtocol,
1147
+ extractOnErrorOption(params.providerOptions)
1148
+ );
1149
+ const finalPrompt = ((_c = processedPrompt[0]) == null ? void 0 : _c.role) === "system" ? [
1150
+ {
1151
+ role: "system",
1152
+ content: systemPrompt + "\n\n" + processedPrompt[0].content
1153
+ },
1154
+ ...processedPrompt.slice(1)
1155
+ ] : [
1156
+ {
1157
+ role: "system",
1158
+ content: systemPrompt
1159
+ },
1160
+ ...processedPrompt
1161
+ ];
1162
+ const baseReturnParams = {
1163
+ ...params,
1164
+ prompt: finalPrompt,
1165
+ tools: [],
1166
+ toolChoice: void 0,
1167
+ providerOptions: {
1168
+ ...params.providerOptions || {},
1169
+ toolCallMiddleware: {
1170
+ ...params.providerOptions && typeof params.providerOptions === "object" && params.providerOptions.toolCallMiddleware || {},
1171
+ toolNames: functionTools.map((t) => t.name)
1172
+ }
1173
+ }
1174
+ };
1175
+ if (((_d = params.toolChoice) == null ? void 0 : _d.type) === "none") {
1176
+ throw new Error(
1177
+ "The 'none' toolChoice type is not supported by this middleware. Please use 'auto', 'required', or specify a tool name."
1178
+ );
1179
+ }
1180
+ if (((_e = params.toolChoice) == null ? void 0 : _e.type) === "tool") {
1181
+ const selectedToolName = params.toolChoice.toolName;
1182
+ const providerDefinedMatch = ((_f = params.tools) != null ? _f : []).find((t) => {
1183
+ if (t.type === "function") return false;
1184
+ const anyTool = t;
1185
+ return anyTool.id === selectedToolName || anyTool.name === selectedToolName;
1186
+ });
1187
+ if (providerDefinedMatch) {
1188
+ throw new Error(
1189
+ "Provider-defined tools are not supported by this middleware. Please use custom tools."
1190
+ );
1191
+ }
1192
+ const selectedTool = ((_g = params.tools) != null ? _g : []).find(
1193
+ (t) => t.type === "function" && t.name === selectedToolName
1194
+ );
1195
+ if (!selectedTool) {
1196
+ throw new Error(
1197
+ `Tool with name '${selectedToolName}' not found in params.tools.`
1198
+ );
1199
+ }
1200
+ return {
1201
+ ...baseReturnParams,
1202
+ responseFormat: {
1203
+ type: "json",
1204
+ schema: {
1205
+ type: "object",
1206
+ properties: {
1207
+ name: {
1208
+ const: selectedTool.name
1209
+ },
1210
+ arguments: selectedTool.inputSchema
1211
+ },
1212
+ required: ["name", "arguments"]
1213
+ },
1214
+ name: selectedTool.name,
1215
+ description: typeof selectedTool.description === "string" ? selectedTool.description : void 0
1216
+ },
1217
+ providerOptions: {
1218
+ ...baseReturnParams.providerOptions || {},
1219
+ toolCallMiddleware: {
1220
+ ...baseReturnParams.providerOptions && typeof baseReturnParams.providerOptions === "object" && baseReturnParams.providerOptions.toolCallMiddleware || {},
1221
+ toolChoice: params.toolChoice
1222
+ }
1223
+ }
1224
+ };
1225
+ }
1226
+ if (((_h = params.toolChoice) == null ? void 0 : _h.type) === "required") {
1227
+ if (!params.tools || params.tools.length === 0) {
1228
+ throw new Error(
1229
+ "Tool choice type 'required' is set, but no tools are provided in params.tools."
1230
+ );
1231
+ }
1232
+ return {
1233
+ ...baseReturnParams,
1234
+ responseFormat: {
1235
+ type: "json",
1236
+ schema: createDynamicIfThenElseSchema(functionTools)
1237
+ },
1238
+ providerOptions: {
1239
+ ...baseReturnParams.providerOptions || {},
1240
+ toolCallMiddleware: {
1241
+ ...baseReturnParams.providerOptions && typeof baseReturnParams.providerOptions === "object" && baseReturnParams.providerOptions.toolCallMiddleware || {},
1242
+ toolChoice: { type: "required" }
1243
+ }
1244
+ }
1245
+ };
1246
+ }
1247
+ return baseReturnParams;
1248
+ }
1249
+ function convertToolPrompt(prompt, resolvedProtocol, providerOptions) {
1250
+ const processedPrompt = prompt.map((message) => {
1251
+ var _a;
1252
+ if (message.role === "assistant") {
1253
+ const newContent = [];
1254
+ for (const content of message.content) {
1255
+ if (isToolCallContent(content)) {
1256
+ newContent.push({
1257
+ type: "text",
1258
+ text: resolvedProtocol.formatToolCall(content)
1259
+ });
1260
+ } else if (content.type === "text") {
1261
+ newContent.push(content);
1262
+ } else if (content.type === "reasoning") {
1263
+ newContent.push(content);
1264
+ } else {
1265
+ const options = extractOnErrorOption(providerOptions);
1266
+ (_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(
1267
+ options,
1268
+ "tool-call-middleware: unknown assistant content; stringifying for provider compatibility",
1269
+ { content }
1270
+ );
1271
+ newContent.push({
1272
+ type: "text",
1273
+ text: JSON.stringify(content)
1274
+ });
1275
+ }
1276
+ }
1277
+ const onlyText = newContent.every((c) => c.type === "text");
1278
+ const condensedAssistant = onlyText ? [
1279
+ {
1280
+ type: "text",
1281
+ text: newContent.map((c) => c.text).join("\n")
1282
+ }
1283
+ ] : newContent;
1284
+ return { role: "assistant", content: condensedAssistant };
1285
+ }
1286
+ if (message.role === "tool") {
1287
+ return {
1288
+ role: "user",
1289
+ // Map tool results to text response blocks, then condense into a single text block
1290
+ content: [
1291
+ {
1292
+ type: "text",
1293
+ text: message.content.map(
1294
+ (toolResult) => isToolResultPart(toolResult) ? resolvedProtocol.formatToolResponse(toolResult) : resolvedProtocol.formatToolResponse(
1295
+ toolResult
1296
+ )
1297
+ ).join("\n")
1298
+ }
1299
+ ]
1300
+ };
1301
+ }
1302
+ return message;
1303
+ });
1304
+ for (let i = 0; i < processedPrompt.length; i++) {
1305
+ const msg = processedPrompt[i];
1306
+ if (Array.isArray(msg.content)) {
1307
+ const allText = msg.content.every(
1308
+ (c) => (c == null ? void 0 : c.type) === "text"
1309
+ );
1310
+ if (allText && msg.content.length > 1) {
1311
+ const joinedText = msg.content.map((c) => c.text).join("\n");
1312
+ if (msg.role === "system") {
1313
+ processedPrompt[i] = {
1314
+ role: "system",
1315
+ content: joinedText
1316
+ };
1317
+ } else if (msg.role === "assistant") {
1318
+ processedPrompt[i] = {
1319
+ role: "assistant",
1320
+ content: [
1321
+ {
1322
+ type: "text",
1323
+ text: joinedText
1324
+ }
1325
+ ]
1326
+ };
1327
+ } else {
1328
+ processedPrompt[i] = {
1329
+ role: "user",
1330
+ content: [
1331
+ {
1332
+ type: "text",
1333
+ text: joinedText
1334
+ }
1335
+ ]
1336
+ };
1337
+ }
1338
+ }
1339
+ }
1340
+ }
1341
+ for (let i = processedPrompt.length - 1; i > 0; i--) {
1342
+ const current = processedPrompt[i];
1343
+ const prev = processedPrompt[i - 1];
1344
+ if (current.role === "user" && prev.role === "user") {
1345
+ const prevContent = prev.content.map((c) => c.type === "text" ? c.text : "").join("\n");
1346
+ const currentContent = current.content.map((c) => c.type === "text" ? c.text : "").join("\n");
1347
+ processedPrompt[i - 1] = {
1348
+ role: "user",
1349
+ content: [{ type: "text", text: prevContent + "\n" + currentContent }]
1350
+ };
1351
+ processedPrompt.splice(i, 1);
1352
+ }
1353
+ }
1354
+ return processedPrompt;
1355
+ }
1356
+
1357
+ // src/tool-call-middleware.ts
988
1358
  function createToolMiddleware({
989
- toolCallTag,
990
- toolCallEndTag,
991
- toolResponseTag,
992
- toolResponseEndTag,
1359
+ protocol,
993
1360
  toolSystemPromptTemplate
994
1361
  }) {
1362
+ const resolvedProtocol = isProtocolFactory(protocol) ? protocol() : protocol;
995
1363
  return {
996
1364
  middlewareVersion: "v2",
997
1365
  wrapStream: async ({ doStream, doGenerate, params }) => {
998
1366
  if (isToolChoiceActive(params)) {
999
1367
  return toolChoiceStream({
1000
- doGenerate
1368
+ doGenerate,
1369
+ options: extractOnErrorOption(params.providerOptions)
1001
1370
  });
1002
1371
  } else {
1003
- return normalToolStream({
1372
+ return wrapStream({
1373
+ protocol: resolvedProtocol,
1004
1374
  doStream,
1005
- toolCallTag,
1006
- toolCallEndTag
1375
+ doGenerate,
1376
+ params
1007
1377
  });
1008
1378
  }
1009
1379
  },
1010
- wrapGenerate: async ({ doGenerate, params }) => {
1011
- const result = await doGenerate();
1012
- if (result.content.length === 0) {
1013
- return result;
1380
+ wrapGenerate: async ({ doGenerate, params }) => wrapGenerate({
1381
+ protocol: resolvedProtocol,
1382
+ doGenerate,
1383
+ params
1384
+ }),
1385
+ transformParams: async ({
1386
+ params
1387
+ }) => {
1388
+ return transformParams({
1389
+ protocol: resolvedProtocol,
1390
+ toolSystemPromptTemplate,
1391
+ params
1392
+ });
1393
+ }
1394
+ };
1395
+ }
1396
+
1397
+ // src/protocols/json-mix-protocol.ts
1398
+ import { generateId as generateId3 } from "@ai-sdk/provider-utils";
1399
+ var jsonMixProtocol = ({
1400
+ toolCallStart = "<tool_call>",
1401
+ toolCallEnd = "</tool_call>",
1402
+ toolResponseStart = "<tool_response>",
1403
+ toolResponseEnd = "</tool_response>"
1404
+ } = {}) => ({
1405
+ formatTools({ tools, toolSystemPromptTemplate }) {
1406
+ const toolsForPrompt = (tools || []).filter((tool) => tool.type === "function").map((tool) => ({
1407
+ name: tool.name,
1408
+ description: tool.type === "function" && typeof tool.description === "string" ? tool.description : void 0,
1409
+ parameters: tool.inputSchema
1410
+ }));
1411
+ return toolSystemPromptTemplate(JSON.stringify(toolsForPrompt));
1412
+ },
1413
+ formatToolCall(toolCall) {
1414
+ let args = {};
1415
+ try {
1416
+ args = JSON.parse(toolCall.input);
1417
+ } catch (e) {
1418
+ args = toolCall.input;
1419
+ }
1420
+ return `${toolCallStart}${JSON.stringify({
1421
+ name: toolCall.toolName,
1422
+ arguments: args
1423
+ })}${toolCallEnd}`;
1424
+ },
1425
+ formatToolResponse(toolResult) {
1426
+ return `${toolResponseStart}${JSON.stringify({
1427
+ toolName: toolResult.toolName,
1428
+ result: toolResult.output
1429
+ })}${toolResponseEnd}`;
1430
+ },
1431
+ parseGeneratedText({ text, options }) {
1432
+ var _a;
1433
+ const startEsc = escapeRegExp(toolCallStart);
1434
+ const endEsc = escapeRegExp(toolCallEnd);
1435
+ const toolCallRegex = new RegExp(
1436
+ `${startEsc}([\0-\uFFFF]*?)${endEsc}`,
1437
+ "gs"
1438
+ );
1439
+ const processedElements = [];
1440
+ let currentIndex = 0;
1441
+ let match;
1442
+ while ((match = toolCallRegex.exec(text)) !== null) {
1443
+ const startIndex = match.index;
1444
+ const toolCallJson = match[1];
1445
+ if (startIndex > currentIndex) {
1446
+ const textSegment = text.substring(currentIndex, startIndex);
1447
+ if (textSegment.trim()) {
1448
+ processedElements.push({ type: "text", text: textSegment });
1449
+ }
1014
1450
  }
1015
- if (isToolChoiceActive(params)) {
1016
- const toolJson = result.content[0].type === "text" ? JSON.parse(result.content[0].text) : {};
1017
- return {
1018
- ...result,
1019
- content: [
1020
- {
1021
- type: "tool-call",
1022
- toolCallType: "function",
1023
- toolCallId: generateId2(),
1024
- toolName: toolJson.name || "unknown",
1025
- input: JSON.stringify(toolJson.arguments || {})
1451
+ if (toolCallJson) {
1452
+ try {
1453
+ const parsedToolCall = relaxed_json_exports.parse(toolCallJson);
1454
+ processedElements.push({
1455
+ type: "tool-call",
1456
+ toolCallId: generateId3(),
1457
+ toolName: parsedToolCall.name,
1458
+ input: JSON.stringify((_a = parsedToolCall.arguments) != null ? _a : {})
1459
+ });
1460
+ } catch (error) {
1461
+ if (options == null ? void 0 : options.onError) {
1462
+ options.onError(
1463
+ "Could not process JSON tool call, keeping original text.",
1464
+ { toolCall: match[0], error }
1465
+ );
1466
+ }
1467
+ processedElements.push({ type: "text", text: match[0] });
1468
+ }
1469
+ }
1470
+ currentIndex = startIndex + match[0].length;
1471
+ }
1472
+ if (currentIndex < text.length) {
1473
+ const remainingText = text.substring(currentIndex);
1474
+ if (remainingText.trim()) {
1475
+ processedElements.push({ type: "text", text: remainingText });
1476
+ }
1477
+ }
1478
+ return processedElements;
1479
+ },
1480
+ createStreamParser({ tools: _tools, options } = { tools: [] }) {
1481
+ let isInsideToolCall = false;
1482
+ let buffer = "";
1483
+ let currentToolCallJson = "";
1484
+ let currentTextId = null;
1485
+ let hasEmittedTextStart = false;
1486
+ return new TransformStream({
1487
+ transform(chunk, controller) {
1488
+ var _a;
1489
+ if (chunk.type === "finish") {
1490
+ if (isInsideToolCall && buffer.length > 0) {
1491
+ if (!currentTextId) {
1492
+ currentTextId = generateId3();
1493
+ controller.enqueue({ type: "text-start", id: currentTextId });
1494
+ hasEmittedTextStart = true;
1495
+ }
1496
+ controller.enqueue({
1497
+ type: "text-delta",
1498
+ id: currentTextId,
1499
+ delta: `${toolCallStart}${buffer}`
1500
+ });
1501
+ buffer = "";
1502
+ } else if (!isInsideToolCall && buffer.length > 0) {
1503
+ if (!currentTextId) {
1504
+ currentTextId = generateId3();
1505
+ controller.enqueue({ type: "text-start", id: currentTextId });
1506
+ hasEmittedTextStart = true;
1507
+ }
1508
+ controller.enqueue({
1509
+ type: "text-delta",
1510
+ id: currentTextId,
1511
+ delta: buffer
1512
+ });
1513
+ buffer = "";
1514
+ }
1515
+ if (currentTextId && hasEmittedTextStart) {
1516
+ controller.enqueue({ type: "text-end", id: currentTextId });
1517
+ currentTextId = null;
1518
+ hasEmittedTextStart = false;
1519
+ }
1520
+ if (currentToolCallJson) {
1521
+ const errorId = generateId3();
1522
+ controller.enqueue({ type: "text-start", id: errorId });
1523
+ controller.enqueue({
1524
+ type: "text-delta",
1525
+ id: errorId,
1526
+ delta: `${toolCallStart}${currentToolCallJson}`
1527
+ });
1528
+ controller.enqueue({ type: "text-end", id: errorId });
1529
+ currentToolCallJson = "";
1530
+ }
1531
+ controller.enqueue(chunk);
1532
+ return;
1533
+ }
1534
+ if (chunk.type !== "text-delta") {
1535
+ controller.enqueue(chunk);
1536
+ return;
1537
+ }
1538
+ buffer += chunk.delta;
1539
+ const publish = (text) => {
1540
+ if (isInsideToolCall) {
1541
+ if (currentTextId && hasEmittedTextStart) {
1542
+ controller.enqueue({ type: "text-end", id: currentTextId });
1543
+ currentTextId = null;
1544
+ hasEmittedTextStart = false;
1545
+ }
1546
+ currentToolCallJson += text;
1547
+ } else if (text.length > 0) {
1548
+ if (!currentTextId) {
1549
+ currentTextId = generateId3();
1550
+ controller.enqueue({ type: "text-start", id: currentTextId });
1551
+ hasEmittedTextStart = true;
1026
1552
  }
1027
- ]
1553
+ controller.enqueue({
1554
+ type: "text-delta",
1555
+ id: currentTextId,
1556
+ delta: text
1557
+ });
1558
+ }
1028
1559
  };
1029
- }
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];
1560
+ let startIndex;
1561
+ while ((startIndex = getPotentialStartIndex(
1562
+ buffer,
1563
+ isInsideToolCall ? toolCallEnd : toolCallStart
1564
+ )) != null) {
1565
+ const tag = isInsideToolCall ? toolCallEnd : toolCallStart;
1566
+ if (startIndex + tag.length > buffer.length) {
1567
+ break;
1038
1568
  }
1039
- const text = contentItem.text;
1040
- const processedElements = [];
1041
- let currentIndex = 0;
1042
- let match;
1043
- const parseAndCreateToolCall = (toolCallJson) => {
1569
+ publish(buffer.slice(0, startIndex));
1570
+ buffer = buffer.slice(startIndex + tag.length);
1571
+ if (!isInsideToolCall) {
1572
+ currentToolCallJson = "";
1573
+ isInsideToolCall = true;
1574
+ } else {
1044
1575
  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;
1576
+ const parsedToolCall = relaxed_json_exports.parse(currentToolCallJson);
1577
+ if (currentTextId && hasEmittedTextStart) {
1578
+ controller.enqueue({ type: "text-end", id: currentTextId });
1579
+ currentTextId = null;
1580
+ hasEmittedTextStart = false;
1052
1581
  }
1053
- return {
1582
+ controller.enqueue({
1054
1583
  type: "tool-call",
1055
- toolCallId: generateId2(),
1584
+ toolCallId: generateId3(),
1056
1585
  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 });
1586
+ input: JSON.stringify((_a = parsedToolCall.arguments) != null ? _a : {})
1587
+ });
1588
+ } catch (e) {
1589
+ const errorId = generateId3();
1590
+ controller.enqueue({ type: "text-start", id: errorId });
1591
+ controller.enqueue({
1592
+ type: "text-delta",
1593
+ id: errorId,
1594
+ delta: `${toolCallStart}${currentToolCallJson}${toolCallEnd}`
1595
+ });
1596
+ controller.enqueue({ type: "text-end", id: errorId });
1597
+ if (options == null ? void 0 : options.onError) {
1598
+ options.onError(
1599
+ "Could not process streaming JSON tool call; emitting original text.",
1600
+ {
1601
+ toolCall: `${toolCallStart}${currentToolCallJson}${toolCallEnd}`
1602
+ }
1603
+ );
1078
1604
  }
1079
1605
  }
1080
- if (toolCallJson) {
1081
- const toolCallObject = parseAndCreateToolCall(toolCallJson);
1082
- if (toolCallObject) {
1083
- processedElements.push(toolCallObject);
1606
+ currentToolCallJson = "";
1607
+ isInsideToolCall = false;
1608
+ }
1609
+ }
1610
+ if (!isInsideToolCall) {
1611
+ const potentialIndex = getPotentialStartIndex(buffer, toolCallStart);
1612
+ if (potentialIndex != null && potentialIndex + toolCallStart.length > buffer.length) {
1613
+ publish(buffer.slice(0, potentialIndex));
1614
+ buffer = buffer.slice(potentialIndex);
1615
+ } else {
1616
+ publish(buffer);
1617
+ buffer = "";
1618
+ }
1619
+ }
1620
+ }
1621
+ });
1622
+ }
1623
+ });
1624
+
1625
+ // src/protocols/xml-protocol.ts
1626
+ import { generateId as generateId4 } from "@ai-sdk/provider-utils";
1627
+ import { XMLParser, XMLBuilder } from "fast-xml-parser";
1628
+ var xmlProtocol = () => ({
1629
+ formatTools({ tools, toolSystemPromptTemplate }) {
1630
+ const toolsForPrompt = (tools || []).map((tool) => ({
1631
+ name: tool.name,
1632
+ description: tool.description,
1633
+ parameters: unwrapJsonSchema(tool.inputSchema)
1634
+ }));
1635
+ return toolSystemPromptTemplate(JSON.stringify(toolsForPrompt));
1636
+ },
1637
+ formatToolCall(toolCall) {
1638
+ const builder = new XMLBuilder({ format: true, suppressEmptyNode: true });
1639
+ let args = {};
1640
+ const inputValue = hasInputProperty(toolCall) ? toolCall.input : void 0;
1641
+ if (typeof inputValue === "string") {
1642
+ try {
1643
+ args = JSON.parse(inputValue);
1644
+ } catch (e) {
1645
+ args = inputValue;
1646
+ }
1647
+ } else {
1648
+ args = inputValue;
1649
+ }
1650
+ const xmlContent = builder.build({
1651
+ [toolCall.toolName]: args
1652
+ });
1653
+ return xmlContent;
1654
+ },
1655
+ formatToolResponse(toolResult) {
1656
+ const builder = new XMLBuilder({ format: true });
1657
+ const xmlContent = builder.build({
1658
+ tool_response: {
1659
+ tool_name: toolResult.toolName,
1660
+ result: toolResult.output
1661
+ }
1662
+ });
1663
+ return xmlContent;
1664
+ },
1665
+ parseGeneratedText({ text, tools, options }) {
1666
+ var _a, _b, _c;
1667
+ const originalSchemas = (options == null ? void 0 : options.originalToolSchemas) || {};
1668
+ const toolNames = tools.map((t) => t.name).filter((name) => name != null);
1669
+ if (toolNames.length === 0) {
1670
+ return [{ type: "text", text }];
1671
+ }
1672
+ const toolNamesPattern = toolNames.map((n) => escapeRegExp(n)).join("|");
1673
+ const toolCallRegex = new RegExp(
1674
+ String.raw`<(${toolNamesPattern})>([\s\S]*?)<\/\1>`,
1675
+ "g"
1676
+ );
1677
+ const processedElements = [];
1678
+ let currentIndex = 0;
1679
+ let match;
1680
+ while ((match = toolCallRegex.exec(text)) !== null) {
1681
+ const startIndex = match.index;
1682
+ const toolName = match[1];
1683
+ const toolContent = match[2].trim();
1684
+ if (startIndex > currentIndex) {
1685
+ const textSegment = text.substring(currentIndex, startIndex);
1686
+ if (textSegment.trim()) {
1687
+ processedElements.push({ type: "text", text: textSegment });
1688
+ }
1689
+ }
1690
+ try {
1691
+ const parser = new XMLParser({
1692
+ ignoreAttributes: false,
1693
+ parseTagValue: false,
1694
+ ignoreDeclaration: true,
1695
+ textNodeName: "#text"
1696
+ });
1697
+ const parsedArgs = ((_a = parser.parse(`<root>${toolContent}</root>`)) == null ? void 0 : _a.root) || {};
1698
+ const args = {};
1699
+ for (const k of Object.keys(parsedArgs || {})) {
1700
+ const v = parsedArgs[k];
1701
+ let val = v;
1702
+ if (v && typeof v === "object" && Object.prototype.hasOwnProperty.call(v, "#text")) {
1703
+ val = v == null ? void 0 : v["#text"];
1704
+ }
1705
+ if (Array.isArray(v)) {
1706
+ val = v.map((item) => {
1707
+ if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
1708
+ const textVal = item == null ? void 0 : item["#text"];
1709
+ return typeof textVal === "string" ? textVal.trim() : textVal;
1710
+ }
1711
+ return typeof item === "string" ? item.trim() : item;
1712
+ });
1713
+ } else if (v && typeof v === "object" && !Object.prototype.hasOwnProperty.call(v, "#text")) {
1714
+ const obj = v;
1715
+ const keys = Object.keys(obj);
1716
+ if (keys.length === 1 && keys[0] === "item") {
1717
+ const itemValue = obj.item;
1718
+ if (Array.isArray(itemValue)) {
1719
+ val = itemValue.map((item) => {
1720
+ if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
1721
+ const textVal = item == null ? void 0 : item["#text"];
1722
+ const trimmed2 = typeof textVal === "string" ? textVal.trim() : textVal;
1723
+ if (typeof trimmed2 === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed2)) {
1724
+ const num = Number(trimmed2);
1725
+ if (Number.isFinite(num)) return num;
1726
+ }
1727
+ return trimmed2;
1728
+ }
1729
+ const trimmed = typeof item === "string" ? item.trim() : item;
1730
+ if (typeof trimmed === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed)) {
1731
+ const num = Number(trimmed);
1732
+ if (Number.isFinite(num)) return num;
1733
+ }
1734
+ return trimmed;
1735
+ });
1084
1736
  } else {
1085
- console.warn(
1086
- `Could not process tool call, keeping original text: ${match[0]}`
1737
+ const trimmed = typeof itemValue === "string" ? itemValue.trim() : itemValue;
1738
+ if (typeof trimmed === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed)) {
1739
+ const num = Number(trimmed);
1740
+ if (Number.isFinite(num)) {
1741
+ val = num;
1742
+ } else {
1743
+ val = trimmed;
1744
+ }
1745
+ } else {
1746
+ val = trimmed;
1747
+ }
1748
+ }
1749
+ } else {
1750
+ const isIndexedTuple = keys.length > 0 && keys.every((key) => /^\d+$/.test(key)) && (() => {
1751
+ const indices = keys.map((k2) => parseInt(k2)).sort((a, b) => a - b);
1752
+ return indices[0] === 0 && indices.every((val2, idx) => val2 === idx);
1753
+ })();
1754
+ if (isIndexedTuple) {
1755
+ const sortedKeys = keys.sort(
1756
+ (a, b) => parseInt(a) - parseInt(b)
1087
1757
  );
1088
- processedElements.push({ type: "text", text: match[0] });
1758
+ val = sortedKeys.map((key) => {
1759
+ const item = obj[key];
1760
+ if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
1761
+ const textVal = item == null ? void 0 : item["#text"];
1762
+ return typeof textVal === "string" ? textVal.trim() : textVal;
1763
+ }
1764
+ return typeof item === "string" ? item.trim() : item;
1765
+ });
1766
+ } else {
1767
+ val = v;
1089
1768
  }
1090
1769
  }
1091
- currentIndex = endIndex;
1092
- }
1093
- if (currentIndex < text.length) {
1094
- const remainingText = text.substring(currentIndex);
1095
- if (remainingText.trim()) {
1096
- processedElements.push({ type: "text", text: remainingText });
1097
- }
1098
1770
  }
1099
- return processedElements;
1771
+ args[k] = typeof val === "string" ? val.trim() : val;
1100
1772
  }
1101
- );
1102
- return {
1103
- ...result,
1104
- content: newContent
1105
- };
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
1117
- });
1118
- const baseReturnParams = {
1119
- ...params,
1120
- prompt: toolSystemPrompt,
1121
- // Reset tools and toolChoice to default after prompt transformation
1122
- tools: [],
1123
- toolChoice: void 0
1124
- };
1125
- if (((_a = params.toolChoice) == null ? void 0 : _a.type) === "none") {
1126
- throw new Error(
1127
- "The 'none' toolChoice type is not supported by this middleware. Please use 'auto', 'required', or specify a tool name."
1128
- );
1773
+ const originalSchema = originalSchemas[toolName];
1774
+ const fallbackSchema = (_b = tools.find((t) => t.name === toolName)) == null ? void 0 : _b.inputSchema;
1775
+ const schema = originalSchema || fallbackSchema;
1776
+ const coercedArgs = coerceBySchema(args, schema);
1777
+ processedElements.push({
1778
+ type: "tool-call",
1779
+ toolCallId: generateId4(),
1780
+ toolName,
1781
+ input: JSON.stringify(coercedArgs)
1782
+ });
1783
+ } catch (error) {
1784
+ const message = `Could not process XML tool call, keeping original text: ${match[0]}`;
1785
+ (_c = options == null ? void 0 : options.onError) == null ? void 0 : _c.call(options, message, { toolCall: match[0], toolName, error });
1786
+ processedElements.push({ type: "text", text: match[0] });
1129
1787
  }
1130
- if (((_b = params.toolChoice) == null ? void 0 : _b.type) === "tool") {
1131
- const selectedToolName = params.toolChoice.toolName;
1132
- const selectedTool = (_c = params.tools) == null ? void 0 : _c.find(
1133
- (tool) => tool.type === "function" ? tool.name === selectedToolName : tool.id === selectedToolName
1134
- );
1135
- if (!selectedTool) {
1136
- throw new Error(
1137
- `Tool with name '${selectedToolName}' not found in params.tools.`
1138
- );
1788
+ currentIndex = startIndex + match[0].length;
1789
+ }
1790
+ if (currentIndex < text.length) {
1791
+ const remainingText = text.substring(currentIndex);
1792
+ if (remainingText.trim()) {
1793
+ processedElements.push({ type: "text", text: remainingText });
1794
+ }
1795
+ }
1796
+ return processedElements;
1797
+ },
1798
+ createStreamParser({ tools, options }) {
1799
+ const originalSchemas = (options == null ? void 0 : options.originalToolSchemas) || {};
1800
+ const toolNames = tools.map((t) => t.name).filter((name) => name != null);
1801
+ let buffer = "";
1802
+ let currentToolCall = null;
1803
+ let currentTextId = null;
1804
+ const flushText = (controller, text) => {
1805
+ const content = text != null ? text : buffer;
1806
+ if (content) {
1807
+ if (!currentTextId) {
1808
+ currentTextId = generateId4();
1809
+ controller.enqueue({ type: "text-start", id: currentTextId });
1139
1810
  }
1140
- if (selectedTool.type === "provider-defined") {
1141
- throw new Error(
1142
- "Provider-defined tools are not supported by this middleware. Please use custom tools."
1143
- );
1811
+ controller.enqueue({
1812
+ type: "text-delta",
1813
+ id: currentTextId,
1814
+ delta: content
1815
+ });
1816
+ if (text === void 0) {
1817
+ buffer = "";
1144
1818
  }
1145
- return {
1146
- ...baseReturnParams,
1147
- responseFormat: {
1148
- type: "json",
1149
- schema: {
1150
- type: "object",
1151
- properties: {
1152
- name: {
1153
- const: selectedTool.name
1154
- },
1155
- arguments: selectedTool.inputSchema
1156
- },
1157
- required: ["name", "arguments"]
1158
- },
1159
- name: selectedTool.name,
1160
- description: selectedTool.type === "function" && typeof selectedTool.description === "string" ? selectedTool.description : void 0
1161
- },
1162
- providerOptions: {
1163
- toolCallMiddleware: {
1164
- toolChoice: params.toolChoice
1165
- }
1166
- }
1167
- };
1168
1819
  }
1169
- if (((_d = params.toolChoice) == null ? void 0 : _d.type) === "required") {
1170
- if (!params.tools || params.tools.length === 0) {
1171
- throw new Error(
1172
- "Tool choice type 'required' is set, but no tools are provided in params.tools."
1173
- );
1820
+ if (currentTextId && !text) {
1821
+ controller.enqueue({ type: "text-end", id: currentTextId });
1822
+ currentTextId = null;
1823
+ }
1824
+ };
1825
+ return new TransformStream({
1826
+ transform(chunk, controller) {
1827
+ var _a, _b;
1828
+ if (chunk.type !== "text-delta") {
1829
+ if (buffer) flushText(controller);
1830
+ controller.enqueue(chunk);
1831
+ return;
1174
1832
  }
1175
- return {
1176
- ...baseReturnParams,
1177
- responseFormat: {
1178
- type: "json",
1179
- schema: createDynamicIfThenElseSchema(params.tools)
1180
- },
1181
- providerOptions: {
1182
- toolCallMiddleware: {
1183
- toolChoice: { type: "required" }
1833
+ buffer += chunk.delta;
1834
+ while (true) {
1835
+ if (currentToolCall) {
1836
+ const endTag = `</${currentToolCall.name}>`;
1837
+ const endTagIndex = buffer.indexOf(endTag);
1838
+ if (endTagIndex !== -1) {
1839
+ const toolContent = buffer.substring(0, endTagIndex);
1840
+ buffer = buffer.substring(endTagIndex + endTag.length);
1841
+ try {
1842
+ const parser = new XMLParser({
1843
+ ignoreAttributes: false,
1844
+ parseTagValue: false,
1845
+ ignoreDeclaration: true,
1846
+ textNodeName: "#text"
1847
+ });
1848
+ const parsedArgs = ((_a = parser.parse(`<root>${toolContent}</root>`)) == null ? void 0 : _a.root) || {};
1849
+ const args = {};
1850
+ for (const k of Object.keys(parsedArgs || {})) {
1851
+ const v = parsedArgs[k];
1852
+ let val = v;
1853
+ if (v && typeof v === "object" && Object.prototype.hasOwnProperty.call(v, "#text")) {
1854
+ val = v == null ? void 0 : v["#text"];
1855
+ }
1856
+ if (Array.isArray(v)) {
1857
+ val = v.map((item) => {
1858
+ if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
1859
+ const textVal = item == null ? void 0 : item["#text"];
1860
+ return typeof textVal === "string" ? textVal.trim() : textVal;
1861
+ }
1862
+ return typeof item === "string" ? item.trim() : item;
1863
+ });
1864
+ } else if (v && typeof v === "object" && !Object.prototype.hasOwnProperty.call(v, "#text")) {
1865
+ const obj = v;
1866
+ const keys = Object.keys(obj);
1867
+ if (keys.length === 1 && keys[0] === "item") {
1868
+ const itemValue = obj.item;
1869
+ if (Array.isArray(itemValue)) {
1870
+ val = itemValue.map((item) => {
1871
+ if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
1872
+ const textVal = item == null ? void 0 : item["#text"];
1873
+ const trimmed2 = typeof textVal === "string" ? textVal.trim() : textVal;
1874
+ if (typeof trimmed2 === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed2)) {
1875
+ const num = Number(trimmed2);
1876
+ if (Number.isFinite(num)) return num;
1877
+ }
1878
+ return trimmed2;
1879
+ }
1880
+ const trimmed = typeof item === "string" ? item.trim() : item;
1881
+ if (typeof trimmed === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed)) {
1882
+ const num = Number(trimmed);
1883
+ if (Number.isFinite(num)) return num;
1884
+ }
1885
+ return trimmed;
1886
+ });
1887
+ } else {
1888
+ const trimmed = typeof itemValue === "string" ? itemValue.trim() : itemValue;
1889
+ if (typeof trimmed === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed)) {
1890
+ const num = Number(trimmed);
1891
+ if (Number.isFinite(num)) {
1892
+ val = num;
1893
+ } else {
1894
+ val = trimmed;
1895
+ }
1896
+ } else {
1897
+ val = trimmed;
1898
+ }
1899
+ }
1900
+ } else {
1901
+ const isIndexedTuple = keys.length > 0 && keys.every((key) => /^\d+$/.test(key)) && (() => {
1902
+ const indices = keys.map((k2) => parseInt(k2)).sort((a, b) => a - b);
1903
+ return indices[0] === 0 && indices.every((val2, idx) => val2 === idx);
1904
+ })();
1905
+ if (isIndexedTuple) {
1906
+ const sortedKeys = keys.sort(
1907
+ (a, b) => parseInt(a) - parseInt(b)
1908
+ );
1909
+ val = sortedKeys.map((key) => {
1910
+ const item = obj[key];
1911
+ if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, "#text")) {
1912
+ const textVal = item == null ? void 0 : item["#text"];
1913
+ return typeof textVal === "string" ? textVal.trim() : textVal;
1914
+ }
1915
+ return typeof item === "string" ? item.trim() : item;
1916
+ });
1917
+ } else {
1918
+ val = v;
1919
+ }
1920
+ }
1921
+ }
1922
+ args[k] = typeof val === "string" ? val.trim() : val;
1923
+ }
1924
+ const originalSchema = originalSchemas[currentToolCall.name];
1925
+ const fallbackSchema = (_b = tools.find(
1926
+ (t) => t.name === currentToolCall.name
1927
+ )) == null ? void 0 : _b.inputSchema;
1928
+ const toolSchema = originalSchema || fallbackSchema;
1929
+ const coercedArgs = coerceBySchema(args, toolSchema);
1930
+ flushText(controller);
1931
+ controller.enqueue({
1932
+ type: "tool-call",
1933
+ toolCallId: generateId4(),
1934
+ toolName: currentToolCall.name,
1935
+ input: JSON.stringify(coercedArgs)
1936
+ });
1937
+ } catch (e) {
1938
+ const originalCallText = `<${currentToolCall.name}>${toolContent}${endTag}`;
1939
+ if (options == null ? void 0 : options.onError) {
1940
+ options.onError(
1941
+ "Could not process streaming XML tool call; emitting original text.",
1942
+ {
1943
+ toolCall: originalCallText,
1944
+ toolName: currentToolCall.name
1945
+ }
1946
+ );
1947
+ }
1948
+ flushText(controller, originalCallText);
1949
+ }
1950
+ currentToolCall = null;
1951
+ } else {
1952
+ break;
1953
+ }
1954
+ } else {
1955
+ let earliestStartTagIndex = -1;
1956
+ let earliestToolName = "";
1957
+ if (toolNames.length > 0) {
1958
+ for (const name of toolNames) {
1959
+ const startTag = `<${name}>`;
1960
+ const index = buffer.indexOf(startTag);
1961
+ if (index !== -1 && (earliestStartTagIndex === -1 || index < earliestStartTagIndex)) {
1962
+ earliestStartTagIndex = index;
1963
+ earliestToolName = name;
1964
+ }
1965
+ }
1966
+ }
1967
+ if (earliestStartTagIndex !== -1) {
1968
+ const textBeforeTag = buffer.substring(0, earliestStartTagIndex);
1969
+ flushText(controller, textBeforeTag);
1970
+ const startTag = `<${earliestToolName}>`;
1971
+ buffer = buffer.substring(
1972
+ earliestStartTagIndex + startTag.length
1973
+ );
1974
+ currentToolCall = { name: earliestToolName, content: "" };
1975
+ } else {
1976
+ break;
1184
1977
  }
1185
1978
  }
1186
- };
1979
+ }
1980
+ },
1981
+ flush(controller) {
1982
+ if (currentToolCall) {
1983
+ const unfinishedCall = `<${currentToolCall.name}>${buffer}`;
1984
+ flushText(controller, unfinishedCall);
1985
+ } else if (buffer) {
1986
+ flushText(controller);
1987
+ }
1988
+ if (currentTextId) {
1989
+ controller.enqueue({ type: "text-end", id: currentTextId });
1990
+ }
1187
1991
  }
1188
- return baseReturnParams;
1189
- }
1190
- };
1191
- }
1992
+ });
1993
+ }
1994
+ });
1995
+
1996
+ // src/protocols/dummy-protocol.ts
1997
+ import { generateId as generateId5 } from "@ai-sdk/provider-utils";
1192
1998
 
1193
1999
  // src/index.ts
1194
2000
  var gemmaToolMiddleware = createToolMiddleware({
2001
+ protocol: jsonMixProtocol(
2002
+ // Customize the tool call delimiters to use markdown code fences
2003
+ {
2004
+ toolCallStart: "```tool_call\n",
2005
+ toolCallEnd: "\n``",
2006
+ // two backticks are more common in gemma output @
2007
+ toolResponseStart: "```tool_response\n",
2008
+ toolResponseEnd: "\n```"
2009
+ }
2010
+ ),
1195
2011
  toolSystemPromptTemplate(tools) {
1196
2012
  return `You have access to functions. If you decide to invoke any of the function(s),
1197
2013
  you MUST put it in the format of markdown code fence block with the language name of tool_call , e.g.
@@ -1200,34 +2016,51 @@ you MUST put it in the format of markdown code fence block with the language nam
1200
2016
  \`\`\`
1201
2017
  You SHOULD NOT include any other text in the response if you call a function
1202
2018
  ${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```"
2019
+ }
1209
2020
  });
1210
2021
  var hermesToolMiddleware = createToolMiddleware({
2022
+ protocol: jsonMixProtocol,
1211
2023
  toolSystemPromptTemplate(tools) {
1212
2024
  return `You are a function calling AI model.
1213
2025
  You are provided with function signatures within <tools></tools> XML tags.
1214
2026
  You may call one or more functions to assist with the user query.
1215
2027
  Don't make assumptions about what values to plug into functions.
1216
2028
  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']}
2029
+ 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
2030
  For each function call return a json object with function name and arguments within <tool_call></tool_call> XML tags as follows:
1219
2031
  <tool_call>
1220
- {'arguments': <args-dict>, 'name': <function-name>}
2032
+ {"name": "<function-name>", "arguments": <args-dict>}
1221
2033
  </tool_call>`;
1222
- },
1223
- toolCallTag: "<tool_call>",
1224
- toolCallEndTag: "</tool_call>",
1225
- toolResponseTag: "<tool_response>",
1226
- toolResponseEndTag: "</tool_response>"
2034
+ }
2035
+ });
2036
+ var xmlToolMiddleware = createToolMiddleware({
2037
+ protocol: xmlProtocol,
2038
+ toolSystemPromptTemplate(tools) {
2039
+ return `You are a function calling AI model.
2040
+ You are provided with function signatures within <tools></tools> XML tags.
2041
+ You may call one or more functions to assist with the user query.
2042
+ Don't make assumptions about what values to plug into functions.
2043
+ Here are the available tools: <tools>${tools}</tools>
2044
+ For a function call, return exactly one XML element whose tag name matches the tool's name, and nothing else.
2045
+ 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.
2046
+ Examples:
2047
+ <get_weather>
2048
+ <location>
2049
+ San Fransisco
2050
+ </location>
2051
+ </get_weather>`;
2052
+ }
1227
2053
  });
1228
2054
  export {
2055
+ coerceBySchema,
1229
2056
  createToolMiddleware,
2057
+ fixToolCallWithSchema,
1230
2058
  gemmaToolMiddleware,
1231
- hermesToolMiddleware
2059
+ getSchemaType,
2060
+ hermesToolMiddleware,
2061
+ jsonMixProtocol,
2062
+ unwrapJsonSchema,
2063
+ xmlProtocol,
2064
+ xmlToolMiddleware
1232
2065
  };
1233
2066
  //# sourceMappingURL=index.js.map