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