@workglow/ai-provider 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/dist/common/ToolCallParsers.d.ts +253 -0
  2. package/dist/common/ToolCallParsers.d.ts.map +1 -0
  3. package/dist/provider-anthropic/AnthropicProvider.d.ts +3 -2
  4. package/dist/provider-anthropic/AnthropicProvider.d.ts.map +1 -1
  5. package/dist/provider-anthropic/AnthropicQueuedProvider.d.ts +3 -2
  6. package/dist/provider-anthropic/AnthropicQueuedProvider.d.ts.map +1 -1
  7. package/dist/provider-anthropic/common/Anthropic_Client.d.ts.map +1 -1
  8. package/dist/provider-anthropic/common/Anthropic_JobRunFns.d.ts.map +1 -1
  9. package/dist/provider-anthropic/common/Anthropic_ModelSchema.d.ts.map +1 -1
  10. package/dist/provider-anthropic/common/Anthropic_ToolCalling.d.ts +10 -0
  11. package/dist/provider-anthropic/common/Anthropic_ToolCalling.d.ts.map +1 -0
  12. package/dist/provider-anthropic/index.js +3 -4
  13. package/dist/provider-anthropic/index.js.map +3 -3
  14. package/dist/provider-anthropic/runtime.js +225 -8
  15. package/dist/provider-anthropic/runtime.js.map +9 -8
  16. package/dist/provider-chrome/WebBrowserProvider.d.ts +2 -1
  17. package/dist/provider-chrome/WebBrowserProvider.d.ts.map +1 -1
  18. package/dist/provider-chrome/WebBrowserQueuedProvider.d.ts +2 -1
  19. package/dist/provider-chrome/WebBrowserQueuedProvider.d.ts.map +1 -1
  20. package/dist/provider-chrome/common/WebBrowser_Constants.d.ts.map +1 -1
  21. package/dist/provider-chrome/common/WebBrowser_ModelSchema.d.ts.map +1 -1
  22. package/dist/provider-chrome/index.js +2 -4
  23. package/dist/provider-chrome/index.js.map +3 -3
  24. package/dist/provider-chrome/runtime.js +3 -7
  25. package/dist/provider-chrome/runtime.js.map +4 -4
  26. package/dist/provider-gemini/GoogleGeminiProvider.d.ts +3 -2
  27. package/dist/provider-gemini/GoogleGeminiProvider.d.ts.map +1 -1
  28. package/dist/provider-gemini/GoogleGeminiQueuedProvider.d.ts +3 -2
  29. package/dist/provider-gemini/GoogleGeminiQueuedProvider.d.ts.map +1 -1
  30. package/dist/provider-gemini/common/Gemini_JobRunFns.d.ts.map +1 -1
  31. package/dist/provider-gemini/common/Gemini_ModelSchema.d.ts.map +1 -1
  32. package/dist/provider-gemini/common/Gemini_ToolCalling.d.ts +10 -0
  33. package/dist/provider-gemini/common/Gemini_ToolCalling.d.ts.map +1 -0
  34. package/dist/provider-gemini/index.js +3 -4
  35. package/dist/provider-gemini/index.js.map +3 -3
  36. package/dist/provider-gemini/runtime.js +188 -8
  37. package/dist/provider-gemini/runtime.js.map +7 -6
  38. package/dist/provider-hf-inference/HfInferenceProvider.d.ts +3 -2
  39. package/dist/provider-hf-inference/HfInferenceProvider.d.ts.map +1 -1
  40. package/dist/provider-hf-inference/HfInferenceQueuedProvider.d.ts +3 -2
  41. package/dist/provider-hf-inference/HfInferenceQueuedProvider.d.ts.map +1 -1
  42. package/dist/provider-hf-inference/common/HFI_JobRunFns.d.ts.map +1 -1
  43. package/dist/provider-hf-inference/common/HFI_ModelSchema.d.ts.map +1 -1
  44. package/dist/provider-hf-inference/common/HFI_ToolCalling.d.ts +10 -0
  45. package/dist/provider-hf-inference/common/HFI_ToolCalling.d.ts.map +1 -0
  46. package/dist/provider-hf-inference/index.js +3 -4
  47. package/dist/provider-hf-inference/index.js.map +3 -3
  48. package/dist/provider-hf-inference/runtime.js +157 -8
  49. package/dist/provider-hf-inference/runtime.js.map +7 -6
  50. package/dist/provider-hf-transformers/HuggingFaceTransformersProvider.d.ts +3 -2
  51. package/dist/provider-hf-transformers/HuggingFaceTransformersProvider.d.ts.map +1 -1
  52. package/dist/provider-hf-transformers/HuggingFaceTransformersQueuedProvider.d.ts +3 -3
  53. package/dist/provider-hf-transformers/HuggingFaceTransformersQueuedProvider.d.ts.map +1 -1
  54. package/dist/provider-hf-transformers/common/HFT_Constants.d.ts.map +1 -1
  55. package/dist/provider-hf-transformers/common/HFT_JobRunFns.d.ts +52 -0
  56. package/dist/provider-hf-transformers/common/HFT_JobRunFns.d.ts.map +1 -1
  57. package/dist/provider-hf-transformers/common/HFT_ModelSchema.d.ts.map +1 -1
  58. package/dist/provider-hf-transformers/common/HFT_OnnxDtypes.d.ts.map +1 -1
  59. package/dist/provider-hf-transformers/common/HFT_Pipeline.d.ts +1 -1
  60. package/dist/provider-hf-transformers/common/HFT_Pipeline.d.ts.map +1 -1
  61. package/dist/provider-hf-transformers/common/HFT_StructuredGeneration.d.ts.map +1 -1
  62. package/dist/provider-hf-transformers/common/HFT_TextClassification.d.ts.map +1 -1
  63. package/dist/provider-hf-transformers/common/HFT_TextQuestionAnswer.d.ts.map +1 -1
  64. package/dist/provider-hf-transformers/common/HFT_TextSummary.d.ts.map +1 -1
  65. package/dist/provider-hf-transformers/common/HFT_TextTranslation.d.ts.map +1 -1
  66. package/dist/provider-hf-transformers/common/HFT_ToolCalling.d.ts +10 -0
  67. package/dist/provider-hf-transformers/common/HFT_ToolCalling.d.ts.map +1 -0
  68. package/dist/provider-hf-transformers/common/HFT_ToolMarkup.d.ts +20 -0
  69. package/dist/provider-hf-transformers/common/HFT_ToolMarkup.d.ts.map +1 -0
  70. package/dist/provider-hf-transformers/common/HFT_ToolParser.d.ts +67 -0
  71. package/dist/provider-hf-transformers/common/HFT_ToolParser.d.ts.map +1 -0
  72. package/dist/provider-hf-transformers/index.d.ts +1 -0
  73. package/dist/provider-hf-transformers/index.d.ts.map +1 -1
  74. package/dist/provider-hf-transformers/index.js +71 -7
  75. package/dist/provider-hf-transformers/index.js.map +7 -6
  76. package/dist/provider-hf-transformers/runtime.d.ts +1 -0
  77. package/dist/provider-hf-transformers/runtime.d.ts.map +1 -1
  78. package/dist/provider-hf-transformers/runtime.js +1244 -13
  79. package/dist/provider-hf-transformers/runtime.js.map +18 -15
  80. package/dist/provider-llamacpp/LlamaCppProvider.d.ts +3 -2
  81. package/dist/provider-llamacpp/LlamaCppProvider.d.ts.map +1 -1
  82. package/dist/provider-llamacpp/LlamaCppQueuedProvider.d.ts +3 -2
  83. package/dist/provider-llamacpp/LlamaCppQueuedProvider.d.ts.map +1 -1
  84. package/dist/provider-llamacpp/common/LlamaCpp_JobRunFns.d.ts.map +1 -1
  85. package/dist/provider-llamacpp/common/LlamaCpp_ModelSchema.d.ts.map +1 -1
  86. package/dist/provider-llamacpp/common/LlamaCpp_ToolCalling.d.ts +10 -0
  87. package/dist/provider-llamacpp/common/LlamaCpp_ToolCalling.d.ts.map +1 -0
  88. package/dist/provider-llamacpp/common/LlamaCpp_ToolParser.d.ts +35 -0
  89. package/dist/provider-llamacpp/common/LlamaCpp_ToolParser.d.ts.map +1 -0
  90. package/dist/provider-llamacpp/index.js +3 -4
  91. package/dist/provider-llamacpp/index.js.map +3 -3
  92. package/dist/provider-llamacpp/runtime.js +1394 -9
  93. package/dist/provider-llamacpp/runtime.js.map +11 -8
  94. package/dist/provider-ollama/OllamaProvider.d.ts +3 -2
  95. package/dist/provider-ollama/OllamaProvider.d.ts.map +1 -1
  96. package/dist/provider-ollama/OllamaQueuedProvider.d.ts +3 -2
  97. package/dist/provider-ollama/OllamaQueuedProvider.d.ts.map +1 -1
  98. package/dist/provider-ollama/common/Ollama_JobRunFns.browser.d.ts +47 -1
  99. package/dist/provider-ollama/common/Ollama_JobRunFns.browser.d.ts.map +1 -1
  100. package/dist/provider-ollama/common/Ollama_JobRunFns.d.ts +46 -0
  101. package/dist/provider-ollama/common/Ollama_JobRunFns.d.ts.map +1 -1
  102. package/dist/provider-ollama/common/Ollama_ModelSchema.d.ts.map +1 -1
  103. package/dist/provider-ollama/common/Ollama_ToolCalling.d.ts +16 -0
  104. package/dist/provider-ollama/common/Ollama_ToolCalling.d.ts.map +1 -0
  105. package/dist/provider-ollama/index.browser.js +3 -4
  106. package/dist/provider-ollama/index.browser.js.map +3 -3
  107. package/dist/provider-ollama/index.js +3 -4
  108. package/dist/provider-ollama/index.js.map +3 -3
  109. package/dist/provider-ollama/runtime.browser.js +130 -8
  110. package/dist/provider-ollama/runtime.browser.js.map +8 -7
  111. package/dist/provider-ollama/runtime.js +125 -8
  112. package/dist/provider-ollama/runtime.js.map +8 -7
  113. package/dist/provider-openai/OpenAiProvider.d.ts +3 -2
  114. package/dist/provider-openai/OpenAiProvider.d.ts.map +1 -1
  115. package/dist/provider-openai/OpenAiQueuedProvider.d.ts +3 -2
  116. package/dist/provider-openai/OpenAiQueuedProvider.d.ts.map +1 -1
  117. package/dist/provider-openai/common/OpenAI_Client.d.ts.map +1 -1
  118. package/dist/provider-openai/common/OpenAI_JobRunFns.browser.d.ts.map +1 -1
  119. package/dist/provider-openai/common/OpenAI_JobRunFns.d.ts.map +1 -1
  120. package/dist/provider-openai/common/OpenAI_ModelSchema.d.ts.map +1 -1
  121. package/dist/provider-openai/common/OpenAI_ToolCalling.d.ts +10 -0
  122. package/dist/provider-openai/common/OpenAI_ToolCalling.d.ts.map +1 -0
  123. package/dist/provider-openai/index.browser.js +3 -4
  124. package/dist/provider-openai/index.browser.js.map +3 -3
  125. package/dist/provider-openai/index.js +3 -4
  126. package/dist/provider-openai/index.js.map +3 -3
  127. package/dist/provider-openai/runtime.browser.js +138 -8
  128. package/dist/provider-openai/runtime.browser.js.map +8 -7
  129. package/dist/provider-openai/runtime.js +138 -8
  130. package/dist/provider-openai/runtime.js.map +8 -7
  131. package/dist/provider-tf-mediapipe/TensorFlowMediaPipeProvider.d.ts +2 -1
  132. package/dist/provider-tf-mediapipe/TensorFlowMediaPipeProvider.d.ts.map +1 -1
  133. package/dist/provider-tf-mediapipe/TensorFlowMediaPipeQueuedProvider.d.ts +2 -1
  134. package/dist/provider-tf-mediapipe/TensorFlowMediaPipeQueuedProvider.d.ts.map +1 -1
  135. package/dist/provider-tf-mediapipe/common/TFMP_Constants.d.ts.map +1 -1
  136. package/dist/provider-tf-mediapipe/common/TFMP_Download.d.ts.map +1 -1
  137. package/dist/provider-tf-mediapipe/common/TFMP_ImageClassification.d.ts.map +1 -1
  138. package/dist/provider-tf-mediapipe/common/TFMP_JobRunFns.d.ts.map +1 -1
  139. package/dist/provider-tf-mediapipe/common/TFMP_ModelSchema.d.ts.map +1 -1
  140. package/dist/provider-tf-mediapipe/common/TFMP_Runtime.d.ts +3 -16
  141. package/dist/provider-tf-mediapipe/common/TFMP_Runtime.d.ts.map +1 -1
  142. package/dist/provider-tf-mediapipe/index.js.map +2 -2
  143. package/dist/provider-tf-mediapipe/runtime.js +2 -4
  144. package/dist/provider-tf-mediapipe/runtime.js.map +13 -13
  145. package/dist/test.d.ts +7 -0
  146. package/dist/test.d.ts.map +1 -0
  147. package/dist/test.js +913 -0
  148. package/dist/test.js.map +10 -0
  149. package/package.json +24 -17
package/dist/test.js ADDED
@@ -0,0 +1,913 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __returnValue = (v) => v;
3
+ function __exportSetter(name, newValue) {
4
+ this[name] = __returnValue.bind(null, newValue);
5
+ }
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, {
9
+ get: all[name],
10
+ enumerable: true,
11
+ configurable: true,
12
+ set: __exportSetter.bind(all, name)
13
+ });
14
+ };
15
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
16
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
17
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
18
+ }) : x)(function(x) {
19
+ if (typeof require !== "undefined")
20
+ return require.apply(this, arguments);
21
+ throw Error('Dynamic require of "' + x + '" is not supported');
22
+ });
23
+
24
+ // src/common/ToolCallParsers.ts
25
+ function stripModelArtifacts(text) {
26
+ return text.replace(/<think>(?:[^<]|<(?!\/think>))*<\/think>/g, "").replace(/<\|[a-z_]+\|>/g, "").trim();
27
+ }
28
+ function makeToolCall(name, args, id = null) {
29
+ return { name, arguments: args, id };
30
+ }
31
+ function tryParseJson(text) {
32
+ try {
33
+ return JSON.parse(text);
34
+ } catch {
35
+ return;
36
+ }
37
+ }
38
+ function findBalancedBlocks(source, openChar, closeChar, startFrom = 0) {
39
+ const results = [];
40
+ const length = source.length;
41
+ let i = startFrom;
42
+ while (i < length) {
43
+ if (source[i] !== openChar) {
44
+ i++;
45
+ continue;
46
+ }
47
+ let depth = 1;
48
+ let j = i + 1;
49
+ let inString = false;
50
+ let escape = false;
51
+ while (j < length && depth > 0) {
52
+ const ch = source[j];
53
+ if (inString) {
54
+ if (escape) {
55
+ escape = false;
56
+ } else if (ch === "\\") {
57
+ escape = true;
58
+ } else if (ch === '"') {
59
+ inString = false;
60
+ }
61
+ } else {
62
+ if (ch === '"') {
63
+ inString = true;
64
+ } else if (ch === openChar) {
65
+ depth++;
66
+ } else if (ch === closeChar) {
67
+ depth--;
68
+ }
69
+ }
70
+ j++;
71
+ }
72
+ if (depth === 0) {
73
+ results.push({ text: source.slice(i, j), start: i, end: j });
74
+ i = j;
75
+ } else {
76
+ break;
77
+ }
78
+ }
79
+ return results;
80
+ }
81
+ function parseJsonToolCallArray(jsonStr, nameKey = "name", argsKeys = ["arguments", "parameters"]) {
82
+ const parsed = tryParseJson(jsonStr.trim());
83
+ if (!parsed)
84
+ return;
85
+ const arr = Array.isArray(parsed) ? parsed : [parsed];
86
+ const calls = arr.filter((c) => !!c && typeof c === "object" && !!c[nameKey]).map((c) => {
87
+ const args = argsKeys.reduce((found, key) => found ?? c[key], undefined);
88
+ return makeToolCall(c[nameKey], args ?? {}, c.id ?? null);
89
+ });
90
+ return calls.length > 0 ? calls : undefined;
91
+ }
92
+ function parseKeyValueArgs(argsStr) {
93
+ const args = {};
94
+ if (!argsStr)
95
+ return args;
96
+ const argRegex = /(?<!\w)(\w+)\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s,]+))/g;
97
+ let match;
98
+ while ((match = argRegex.exec(argsStr)) !== null) {
99
+ const key = match[1];
100
+ const value = match[2] ?? match[3] ?? match[4];
101
+ args[key] = coerceArgValue(value);
102
+ }
103
+ return args;
104
+ }
105
+ function coerceArgValue(value) {
106
+ if (value === "true")
107
+ return true;
108
+ if (value === "false")
109
+ return false;
110
+ if (value !== "" && !isNaN(Number(value)))
111
+ return Number(value);
112
+ return value;
113
+ }
114
+ function parseFunctionGemmaArgumentValue(rawValue) {
115
+ const trimmed = rawValue.trim();
116
+ if (trimmed.length === 0)
117
+ return "";
118
+ if (trimmed === "true")
119
+ return true;
120
+ if (trimmed === "false")
121
+ return false;
122
+ if (trimmed === "null")
123
+ return null;
124
+ const numeric = Number(trimmed);
125
+ if (!Number.isNaN(numeric) && /^-?\d+(?:\.\d+)?$/.test(trimmed)) {
126
+ return numeric;
127
+ }
128
+ if (trimmed.startsWith('"') && trimmed.endsWith('"') || trimmed.startsWith("{") && trimmed.endsWith("}") || trimmed.startsWith("[") && trimmed.endsWith("]")) {
129
+ try {
130
+ return JSON.parse(trimmed);
131
+ } catch {}
132
+ }
133
+ return trimmed;
134
+ }
135
+ function parseFunctionGemmaLooseObject(text) {
136
+ const trimmed = text.trim();
137
+ if (!trimmed.startsWith("{") || !trimmed.endsWith("}")) {
138
+ return;
139
+ }
140
+ const inner = trimmed.slice(1, -1).trim();
141
+ if (inner.length === 0) {
142
+ return {};
143
+ }
144
+ const result = {};
145
+ const pairs = inner.matchAll(/([A-Za-z0-9_]+)\s*:\s*('[^']*'|"[^"]*"|[^,}]+)/g);
146
+ for (const [_, rawKey, rawValue] of pairs) {
147
+ const key = rawKey.trim();
148
+ const valueText = rawValue.trim().replace(/^'([^']*)'$/, '"$1"');
149
+ result[key] = parseFunctionGemmaArgumentValue(valueText);
150
+ }
151
+ return Object.keys(result).length > 0 ? result : undefined;
152
+ }
153
+ var parseLlama = (text) => {
154
+ const calls = [];
155
+ let content = text;
156
+ const pythonTagMatch = text.match(/<\|python_tag\|>((?:[^<]|<(?!\|eot_id\|>|\|eom_id\|>))*)(?:<\|eot_id\|>|<\|eom_id\|>|$)/);
157
+ if (pythonTagMatch) {
158
+ content = text.slice(0, text.indexOf("<|python_tag|>")).trim();
159
+ const jsonSection = pythonTagMatch[1].trim();
160
+ for (const line of jsonSection.split(`
161
+ `)) {
162
+ const trimmed = line.trim();
163
+ if (!trimmed)
164
+ continue;
165
+ const parsed = tryParseJson(trimmed);
166
+ if (parsed?.name) {
167
+ calls.push(makeToolCall(parsed.name, parsed.parameters ?? parsed.arguments ?? {}, parsed.id ?? null));
168
+ }
169
+ }
170
+ }
171
+ if (calls.length === 0) {
172
+ const funcTagRegex = /<function=(\w+)>((?:[^<]|<(?!\/function>))*)<\/function>/g;
173
+ let funcMatch;
174
+ while ((funcMatch = funcTagRegex.exec(text)) !== null) {
175
+ const args = tryParseJson(funcMatch[2].trim());
176
+ if (args) {
177
+ calls.push(makeToolCall(funcMatch[1], args));
178
+ }
179
+ }
180
+ if (calls.length > 0) {
181
+ content = text.replace(/<function=\w+>(?:[^<]|<(?!\/function>))*<\/function>/g, "").trim();
182
+ }
183
+ }
184
+ if (calls.length === 0) {
185
+ const blocks = findBalancedBlocks(text, "{", "}");
186
+ for (const block of blocks) {
187
+ const parsed = tryParseJson(block.text);
188
+ if (parsed?.name && (parsed.parameters !== undefined || parsed.arguments !== undefined)) {
189
+ calls.push(makeToolCall(parsed.name, parsed.parameters ?? parsed.arguments ?? {}, parsed.id ?? null));
190
+ }
191
+ }
192
+ if (calls.length > 0) {
193
+ content = text.slice(0, text.indexOf(calls[0].name) - '{"name": "'.length).trim();
194
+ }
195
+ }
196
+ return calls.length > 0 ? { tool_calls: calls, content, parser: "llama" } : null;
197
+ };
198
+ var parseMistral = (text) => {
199
+ const marker = "[TOOL_CALLS]";
200
+ const idx = text.indexOf(marker);
201
+ if (idx === -1)
202
+ return null;
203
+ const content = text.slice(0, idx).trim();
204
+ const jsonStr = text.slice(idx + marker.length).trim();
205
+ const calls = parseJsonToolCallArray(jsonStr);
206
+ return calls ? { tool_calls: calls, content, parser: "mistral" } : null;
207
+ };
208
+ var parseHermes = (text) => {
209
+ const regex = /<tool_call>((?:[^<]|<(?!\/tool_call>))*)<\/tool_call>/g;
210
+ const calls = [];
211
+ let match;
212
+ while ((match = regex.exec(text)) !== null) {
213
+ const parsed = tryParseJson(match[1].trim());
214
+ if (parsed) {
215
+ calls.push(makeToolCall(parsed.name ?? "", parsed.arguments ?? parsed.parameters ?? {}, parsed.id ?? null));
216
+ }
217
+ }
218
+ if (calls.length === 0)
219
+ return null;
220
+ const content = text.replace(/<tool_call>(?:[^<]|<(?!\/tool_call>))*<\/tool_call>/g, "").trim();
221
+ return { tool_calls: calls, content, parser: "hermes" };
222
+ };
223
+ var parseCohere = (text) => {
224
+ const blockMatch = text.match(/Action:\s*```(?:json)?\n?((?:[^`]|`(?!``))*)\n?```/);
225
+ let inlineJsonStr;
226
+ if (!blockMatch) {
227
+ const actionIdx2 = text.indexOf("Action:");
228
+ if (actionIdx2 !== -1) {
229
+ const afterAction = text.slice(actionIdx2 + "Action:".length).trimStart();
230
+ if (afterAction.startsWith("[")) {
231
+ const blocks = findBalancedBlocks(afterAction, "[", "]");
232
+ if (blocks.length > 0) {
233
+ inlineJsonStr = blocks[0].text;
234
+ }
235
+ }
236
+ }
237
+ }
238
+ const jsonStr = blockMatch?.[1] ?? inlineJsonStr;
239
+ if (!jsonStr)
240
+ return null;
241
+ const calls = parseJsonToolCallArray(jsonStr, "tool_name", ["parameters", "arguments"]);
242
+ if (!calls) {
243
+ const fallbackCalls = parseJsonToolCallArray(jsonStr);
244
+ if (!fallbackCalls)
245
+ return null;
246
+ const actionIdx2 = text.indexOf("Action:");
247
+ const content2 = text.slice(0, actionIdx2).trim();
248
+ return { tool_calls: fallbackCalls, content: content2, parser: "cohere" };
249
+ }
250
+ const actionIdx = text.indexOf("Action:");
251
+ const content = text.slice(0, actionIdx).trim();
252
+ return { tool_calls: calls, content, parser: "cohere" };
253
+ };
254
+ var parseDeepSeek = (text) => {
255
+ const calls = [];
256
+ const bar = "(?:||\\|)";
257
+ const sep = "[\\s▁]";
258
+ const v31Regex = new RegExp(`<${bar}tool${sep}call${sep}begin${bar}>\\s*(\\w+)\\s*<${bar}tool${sep}sep${bar}>\\s*([^<]*(?:<(?!${bar}tool${sep}call${sep}end${bar}>)[^<]*)*)\\s*<${bar}tool${sep}call${sep}end${bar}>`, "g");
259
+ let match;
260
+ while ((match = v31Regex.exec(text)) !== null) {
261
+ const args = tryParseJson(match[2].trim());
262
+ if (args) {
263
+ calls.push(makeToolCall(match[1], args));
264
+ }
265
+ }
266
+ if (calls.length === 0) {
267
+ const v2Regex = new RegExp(`<${bar}tool${sep}call${sep}begin${bar}>\\s*(\\w+)\\s*\\n\`\`\`(?:json)?\\n([^\`]*(?:\`(?!\`\`)[^\`]*)*)\\n\`\`\`\\s*<${bar}tool${sep}call${sep}end${bar}>`, "g");
268
+ while ((match = v2Regex.exec(text)) !== null) {
269
+ const args = tryParseJson(match[2].trim());
270
+ if (args) {
271
+ calls.push(makeToolCall(match[1], args));
272
+ }
273
+ }
274
+ }
275
+ if (calls.length === 0)
276
+ return null;
277
+ const content = text.replace(new RegExp(`<${bar}tool${sep}calls?${sep}(?:begin|end)${bar}>`, "g"), "").replace(new RegExp(`<${bar}tool${sep}call${sep}(?:begin|end)${bar}>[^<]*(?:<(?!${bar}tool${sep}call${sep}end${bar}>)[^<]*)*<${bar}tool${sep}call${sep}end${bar}>`, "g"), "").replace(new RegExp(`<${bar}tool${sep}sep${bar}>`, "g"), "").trim();
278
+ return { tool_calls: calls, content, parser: "deepseek" };
279
+ };
280
+ var parsePhi = (text) => {
281
+ const match = text.match(/<\|tool_calls\|>((?:[^<]|<(?!\|\/tool_calls\|>))*)<\|\/tool_calls\|>/);
282
+ if (!match)
283
+ return null;
284
+ const calls = parseJsonToolCallArray(match[1]);
285
+ if (!calls)
286
+ return null;
287
+ const content = text.slice(0, text.indexOf("<|tool_calls|>")).trim();
288
+ return { tool_calls: calls, content, parser: "phi" };
289
+ };
290
+ var parsePhiFunctools = (text) => {
291
+ const idx = text.indexOf("functools");
292
+ if (idx === -1)
293
+ return null;
294
+ let start = idx + "functools".length;
295
+ while (start < text.length && /\s/.test(text[start]))
296
+ start++;
297
+ if (start >= text.length || text[start] !== "[")
298
+ return null;
299
+ const blocks = findBalancedBlocks(text, "[", "]", start);
300
+ if (blocks.length === 0)
301
+ return null;
302
+ const calls = parseJsonToolCallArray(blocks[0].text);
303
+ if (!calls)
304
+ return null;
305
+ const content = text.slice(0, idx).trim();
306
+ return { tool_calls: calls, content, parser: "phi_functools" };
307
+ };
308
+ var parseInternLM = (text) => {
309
+ const regex = /<\|action_start\|>\s*<\|plugin\|>((?:[^<]|<(?!\|action_end\|>))*)<\|action_end\|>/g;
310
+ const calls = [];
311
+ let match;
312
+ while ((match = regex.exec(text)) !== null) {
313
+ const parsed = tryParseJson(match[1].trim());
314
+ if (parsed) {
315
+ calls.push(makeToolCall(parsed.name ?? "", parsed.parameters ?? parsed.arguments ?? {}, parsed.id ?? null));
316
+ }
317
+ }
318
+ if (calls.length === 0)
319
+ return null;
320
+ const content = text.replace(/<\|action_start\|>\s*<\|plugin\|>(?:[^<]|<(?!\|action_end\|>))*<\|action_end\|>/g, "").trim();
321
+ return { tool_calls: calls, content, parser: "internlm" };
322
+ };
323
+ var parseChatGLM = (text) => {
324
+ const match = text.match(/^(\w+)\n(\{[\s\S]*\})\s*$/m);
325
+ if (!match)
326
+ return null;
327
+ const args = tryParseJson(match[2].trim());
328
+ if (!args)
329
+ return null;
330
+ return {
331
+ tool_calls: [makeToolCall(match[1], args)],
332
+ content: "",
333
+ parser: "chatglm"
334
+ };
335
+ };
336
+ var parseFunctionary = (text) => {
337
+ const regex = />>>\s*(\w+)\s*\n((?:(?!>>>)[\s\S])*)/g;
338
+ const calls = [];
339
+ let content = "";
340
+ let match;
341
+ while ((match = regex.exec(text)) !== null) {
342
+ const funcName = match[1].trim();
343
+ const body = match[2].trim();
344
+ if (funcName === "all") {
345
+ content += body;
346
+ continue;
347
+ }
348
+ const args = tryParseJson(body);
349
+ calls.push(makeToolCall(funcName, args ?? { content: body }));
350
+ }
351
+ if (calls.length === 0)
352
+ return null;
353
+ return { tool_calls: calls, content: content.trim(), parser: "functionary" };
354
+ };
355
+ var parseGorilla = (text) => {
356
+ const regex = /<<function>>\s{0,20}(\w+)\(([^)]*)\)/g;
357
+ const calls = [];
358
+ let match;
359
+ while ((match = regex.exec(text)) !== null) {
360
+ calls.push(makeToolCall(match[1], parseKeyValueArgs(match[2].trim())));
361
+ }
362
+ if (calls.length === 0)
363
+ return null;
364
+ const content = text.replace(/<<function>>\s{0,20}\w+\([^)]*\)/g, "").trim();
365
+ return { tool_calls: calls, content, parser: "gorilla" };
366
+ };
367
+ var parseNexusRaven = (text) => {
368
+ const regex = /Call:\s{0,20}(\w+)\(([^)]*)\)/g;
369
+ const calls = [];
370
+ let match;
371
+ while ((match = regex.exec(text)) !== null) {
372
+ calls.push(makeToolCall(match[1], parseKeyValueArgs(match[2].trim())));
373
+ }
374
+ if (calls.length === 0)
375
+ return null;
376
+ const thoughtMatch = text.match(/Thought:\s*((?:(?!Call:)[\s\S])*)/);
377
+ const content = thoughtMatch?.[1]?.trim() ?? text.replace(/Call:\s{0,20}\w+\([^)]*\)/g, "").trim();
378
+ return { tool_calls: calls, content, parser: "nexusraven" };
379
+ };
380
+ var parseXLAM = (text) => {
381
+ const codeBlockMatch = text.match(/```(?:json)?\n?((?:[^`]|`(?!``))*)\n?```/);
382
+ let jsonStr;
383
+ let isCodeBlock = false;
384
+ if (codeBlockMatch) {
385
+ const inner = codeBlockMatch[1].trim();
386
+ if (inner.startsWith("[")) {
387
+ jsonStr = inner;
388
+ isCodeBlock = true;
389
+ }
390
+ }
391
+ if (!jsonStr) {
392
+ const trimmed = text.trim();
393
+ if (!trimmed.startsWith("["))
394
+ return null;
395
+ jsonStr = trimmed;
396
+ }
397
+ const calls = parseJsonToolCallArray(jsonStr);
398
+ if (!calls)
399
+ return null;
400
+ const content = isCodeBlock ? text.slice(0, text.indexOf("```")).trim() : "";
401
+ return { tool_calls: calls, content, parser: "xlam" };
402
+ };
403
+ var parseFireFunction = (text) => {
404
+ const toolCallsIdx = text.indexOf('"tool_calls"');
405
+ if (toolCallsIdx === -1)
406
+ return null;
407
+ let bracketStart = text.indexOf("[", toolCallsIdx);
408
+ if (bracketStart === -1)
409
+ return null;
410
+ const blocks = findBalancedBlocks(text, "[", "]", bracketStart);
411
+ if (blocks.length === 0)
412
+ return null;
413
+ const parsed = tryParseJson(blocks[0].text);
414
+ if (!parsed || !Array.isArray(parsed))
415
+ return null;
416
+ const calls = [];
417
+ for (const c of parsed) {
418
+ const fn = c.function;
419
+ if (!fn?.name)
420
+ continue;
421
+ let args = fn.arguments ?? {};
422
+ if (typeof args === "string") {
423
+ args = tryParseJson(args) ?? {};
424
+ }
425
+ calls.push(makeToolCall(fn.name, args, c.id ?? null));
426
+ }
427
+ return calls.length > 0 ? { tool_calls: calls, content: "", parser: "firefunction" } : null;
428
+ };
429
+ var parseGranite = (text) => {
430
+ const regex = /<\|tool_call\|>((?:[^<]|<(?!\|\/tool_call\|>|\|end_of_text\|>))*?)(?:<\|\/tool_call\|>|<\|end_of_text\|>|$)/g;
431
+ const calls = [];
432
+ let match;
433
+ while ((match = regex.exec(text)) !== null) {
434
+ const parsed = tryParseJson(match[1].trim());
435
+ if (parsed) {
436
+ calls.push(makeToolCall(parsed.name ?? "", parsed.arguments ?? parsed.parameters ?? {}, parsed.id ?? null));
437
+ }
438
+ }
439
+ if (calls.length === 0)
440
+ return null;
441
+ const content = text.replace(/<\|tool_call\|>(?:[^<]|<(?!\|\/tool_call\|>|\|end_of_text\|>))*(?:<\|\/tool_call\|>|$)/g, "").trim();
442
+ return { tool_calls: calls, content, parser: "granite" };
443
+ };
444
+ var parseGemma = (text) => {
445
+ const openMarker = "```tool_code";
446
+ const openIdx = text.indexOf(openMarker);
447
+ if (openIdx === -1)
448
+ return null;
449
+ const lineStart = text.indexOf(`
450
+ `, openIdx + openMarker.length);
451
+ if (lineStart === -1)
452
+ return null;
453
+ let closeIdx = -1;
454
+ let searchFrom = lineStart + 1;
455
+ while (searchFrom < text.length) {
456
+ const candidate = text.indexOf("```", searchFrom);
457
+ if (candidate === -1)
458
+ break;
459
+ const lineBegin = text.lastIndexOf(`
460
+ `, candidate - 1);
461
+ if (lineBegin >= lineStart && text.slice(lineBegin + 1, candidate).trim() === "") {
462
+ closeIdx = candidate;
463
+ break;
464
+ }
465
+ searchFrom = candidate + 3;
466
+ }
467
+ if (closeIdx === -1)
468
+ return null;
469
+ const rawCode = text.slice(lineStart + 1, closeIdx).replace(/\n[ \t]*$/, "");
470
+ const code = rawCode.trim();
471
+ const funcMatch = code.match(/^(\w+)\(([\s\S]*)\)$/);
472
+ if (!funcMatch)
473
+ return null;
474
+ const blockEnd = closeIdx + 3;
475
+ const content = (text.slice(0, openIdx) + text.slice(blockEnd)).trim();
476
+ return {
477
+ tool_calls: [makeToolCall(funcMatch[1], parseKeyValueArgs(funcMatch[2].trim()))],
478
+ content,
479
+ parser: "gemma"
480
+ };
481
+ };
482
+ function parseFunctionGemmaArgs(argsStr) {
483
+ const args = {};
484
+ if (!argsStr.trim())
485
+ return args;
486
+ const escapeRegex = /(?<![A-Za-z0-9_])([A-Za-z0-9_]+)\s*:\s*<escape>((?:[^<]|<(?!escape>))*)<escape>/g;
487
+ let escapeMatch;
488
+ while ((escapeMatch = escapeRegex.exec(argsStr)) !== null) {
489
+ args[escapeMatch[1]] = coerceArgValue(escapeMatch[2]);
490
+ }
491
+ if (Object.keys(args).length > 0)
492
+ return args;
493
+ const plainRegex = /(?<![A-Za-z0-9_])(?=([A-Za-z0-9_]+))\1\s*:\s*(?:'([^']*)'|"([^"]*)"|([^,}]+))/g;
494
+ let plainMatch;
495
+ while ((plainMatch = plainRegex.exec(argsStr)) !== null) {
496
+ const key = plainMatch[1].trim();
497
+ const value = (plainMatch[2] ?? plainMatch[3] ?? plainMatch[4] ?? "").replace(/<escape>/g, "").trim();
498
+ args[key] = parseFunctionGemmaArgumentValue(value);
499
+ }
500
+ if (Object.keys(args).length > 0)
501
+ return args;
502
+ const jsonResult = tryParseJson(`{${argsStr}}`);
503
+ if (jsonResult && typeof jsonResult === "object")
504
+ return jsonResult;
505
+ return args;
506
+ }
507
+ var parseFunctionGemma = (text) => {
508
+ const regex = /(?:<start_function_call>\s*)?call:(?=([\w.]+))\1\s*\{([^}]*)\}(?:\s*<end_function_call>)?/g;
509
+ const calls = [];
510
+ let match;
511
+ while ((match = regex.exec(text)) !== null) {
512
+ calls.push(makeToolCall(match[1].trim(), parseFunctionGemmaArgs(match[2])));
513
+ }
514
+ if (calls.length === 0) {
515
+ const fallbackRegex = /^:([A-Za-z_]\w*)\s*\{([^}]*)\}$/;
516
+ const fallbackMatch = text.trim().match(fallbackRegex);
517
+ if (fallbackMatch) {
518
+ calls.push(makeToolCall(fallbackMatch[1].trim(), parseFunctionGemmaArgs(fallbackMatch[2])));
519
+ }
520
+ }
521
+ if (calls.length === 0)
522
+ return null;
523
+ const content = text.replace(/(?:<start_function_call>\s*)?(?:call)?:(?=([\w.]+))\1\s*\{[^}]*\}(?:\s*<end_function_call>)?/g, "").trim();
524
+ return { tool_calls: calls, content, parser: "functiongemma" };
525
+ };
526
+ function parseLiquidArgs(argsStr) {
527
+ const trimmed = argsStr.trim();
528
+ const paramsMatch = trimmed.match(/^params\s*=\s*(\{[\s\S]*\})$/);
529
+ if (paramsMatch) {
530
+ const jsonStr = paramsMatch[1].replace(/'/g, '"');
531
+ const parsed = tryParseJson(jsonStr);
532
+ if (parsed && typeof parsed === "object") {
533
+ return parsed;
534
+ }
535
+ }
536
+ if (trimmed.startsWith("{") && trimmed.endsWith("}")) {
537
+ const jsonified = trimmed.replace(/([{,]\s*)(\w+)\s*:/g, '$1"$2":');
538
+ const parsed = tryParseJson(jsonified);
539
+ if (parsed && typeof parsed === "object") {
540
+ return parsed;
541
+ }
542
+ }
543
+ return parseKeyValueArgs(argsStr);
544
+ }
545
+ function extractPythonicCalls(text) {
546
+ const calls = [];
547
+ const startRegex = /(?<!\w)(\w+)\(/g;
548
+ let startMatch;
549
+ while ((startMatch = startRegex.exec(text)) !== null) {
550
+ const funcName = startMatch[1];
551
+ const argsStart = startMatch.index + startMatch[0].length;
552
+ let depth = 1;
553
+ let i = argsStart;
554
+ while (i < text.length && depth > 0) {
555
+ if (text[i] === "(")
556
+ depth++;
557
+ else if (text[i] === ")")
558
+ depth--;
559
+ i++;
560
+ }
561
+ if (depth === 0) {
562
+ const argsStr = text.slice(argsStart, i - 1);
563
+ calls.push(makeToolCall(funcName, parseLiquidArgs(argsStr)));
564
+ startRegex.lastIndex = i;
565
+ }
566
+ }
567
+ return calls;
568
+ }
569
+ var parseLiquid = (text) => {
570
+ const specialMatch = text.match(/<\|tool_call_start\|>((?:[^<]|<(?!\|tool_call_end\|>))*)<\|tool_call_end\|>/);
571
+ if (specialMatch) {
572
+ const inner = specialMatch[1].trim();
573
+ const unwrapped = inner.startsWith("[") && inner.endsWith("]") ? inner.slice(1, -1) : inner;
574
+ const calls = extractPythonicCalls(unwrapped);
575
+ if (calls.length > 0) {
576
+ const content = stripModelArtifacts(text.replace(/<\|tool_call_start\|>(?:[^<]|<(?!\|tool_call_end\|>))*<\|tool_call_end\|>/g, ""));
577
+ return { tool_calls: calls, content, parser: "liquid" };
578
+ }
579
+ }
580
+ const bracketCalls = [];
581
+ const bracketSpans = [];
582
+ {
583
+ const bracketOpenRegex = /\[(?=\w+\()/g;
584
+ let bm;
585
+ while ((bm = bracketOpenRegex.exec(text)) !== null) {
586
+ const innerStart = bm.index + 1;
587
+ let depth = 0;
588
+ let i = innerStart;
589
+ let foundClose = false;
590
+ while (i < text.length) {
591
+ const ch = text[i];
592
+ if (ch === "(")
593
+ depth++;
594
+ else if (ch === ")") {
595
+ depth--;
596
+ if (depth === 0 && i + 1 < text.length && text[i + 1] === "]") {
597
+ const inner = text.slice(innerStart, i + 1);
598
+ const calls = extractPythonicCalls(inner);
599
+ bracketCalls.push(...calls);
600
+ bracketSpans.push([bm.index, i + 2]);
601
+ bracketOpenRegex.lastIndex = i + 2;
602
+ foundClose = true;
603
+ break;
604
+ }
605
+ }
606
+ i++;
607
+ }
608
+ if (!foundClose)
609
+ break;
610
+ }
611
+ }
612
+ if (bracketCalls.length > 0) {
613
+ let content = text;
614
+ for (let k = bracketSpans.length - 1;k >= 0; k--) {
615
+ content = content.slice(0, bracketSpans[k][0]) + content.slice(bracketSpans[k][1]);
616
+ }
617
+ return { tool_calls: bracketCalls, content: stripModelArtifacts(content), parser: "liquid" };
618
+ }
619
+ const callPrefixRegex = /\|?\|?Call:\s*/g;
620
+ let callPrefixMatch;
621
+ const callCalls = [];
622
+ while ((callPrefixMatch = callPrefixRegex.exec(text)) !== null) {
623
+ const afterPrefix = text.slice(callPrefixMatch.index + callPrefixMatch[0].length);
624
+ const calls = extractPythonicCalls(afterPrefix);
625
+ if (calls.length > 0) {
626
+ callCalls.push(calls[0]);
627
+ }
628
+ }
629
+ if (callCalls.length > 0) {
630
+ const content = stripModelArtifacts(text.replace(/\|?\|?Call:\s{0,20}\w+\([^)]*\)/g, ""));
631
+ return { tool_calls: callCalls, content, parser: "liquid" };
632
+ }
633
+ return null;
634
+ };
635
+ var parseJamba = (text) => {
636
+ const tagMatch = text.match(/<tool_calls>((?:[^<]|<(?!\/tool_calls>))*)<\/tool_calls>/);
637
+ if (tagMatch) {
638
+ const parsed = tryParseJson(tagMatch[1].trim());
639
+ if (parsed) {
640
+ const arr = Array.isArray(parsed) ? parsed : [parsed];
641
+ const calls = [];
642
+ for (const c of arr) {
643
+ if (!c.name)
644
+ continue;
645
+ let args = c.arguments ?? c.parameters ?? {};
646
+ if (typeof args === "string") {
647
+ args = tryParseJson(args) ?? {};
648
+ }
649
+ calls.push(makeToolCall(c.name, args, c.id ?? null));
650
+ }
651
+ if (calls.length > 0) {
652
+ const content = text.slice(0, text.indexOf("<tool_calls>")).trim();
653
+ return { tool_calls: calls, content, parser: "jamba" };
654
+ }
655
+ }
656
+ }
657
+ return parseFireFunction(text);
658
+ };
659
+ var parseQwen35Xml = (text) => {
660
+ const toolCallMatches = text.matchAll(/<tool_call>((?:[^<]|<(?!\/tool_call>))*)<\/tool_call>/g);
661
+ const calls = [];
662
+ for (const [_, toolCallBody] of toolCallMatches) {
663
+ const functionMatch = toolCallBody.trim().match(/<function=([^>\n<]+)>((?:[^<]|<(?!\/function>))*)<\/function>/);
664
+ if (!functionMatch) {
665
+ continue;
666
+ }
667
+ const [, rawName, functionBody] = functionMatch;
668
+ const parsedInput = {};
669
+ const parameterMatches = functionBody.matchAll(/<parameter=([^>\n<]+)>((?:[^<]|<(?!\/parameter>))*)<\/parameter>/g);
670
+ for (const [__, rawParamName, rawValue] of parameterMatches) {
671
+ const paramName = rawParamName.trim();
672
+ const valueText = rawValue.trim();
673
+ if (paramName === "params") {
674
+ try {
675
+ const parsedValue = JSON.parse(valueText);
676
+ if (parsedValue && typeof parsedValue === "object" && !Array.isArray(parsedValue)) {
677
+ Object.assign(parsedInput, parsedValue);
678
+ continue;
679
+ }
680
+ } catch {}
681
+ }
682
+ parsedInput[paramName] = valueText;
683
+ }
684
+ calls.push(makeToolCall(rawName.trim(), parsedInput));
685
+ }
686
+ if (calls.length === 0)
687
+ return null;
688
+ const content = text.replace(/<tool_call>(?:[^<]|<(?!\/tool_call>))*<\/tool_call>/g, "").trim();
689
+ return { tool_calls: calls, content, parser: "qwen35xml" };
690
+ };
691
+ var MODEL_PARSERS = {
692
+ llama: [parseLlama, parseHermes],
693
+ mistral: [parseMistral, parseHermes],
694
+ mixtral: [parseMistral, parseHermes],
695
+ qwen: [parseHermes, parseLlama],
696
+ qwen2: [parseHermes, parseLlama],
697
+ qwen3: [parseHermes, parseQwen35Xml, parseLlama],
698
+ qwen35: [parseQwen35Xml, parseHermes, parseLlama],
699
+ cohere: [parseCohere, parseHermes],
700
+ command: [parseCohere, parseHermes],
701
+ deepseek: [parseDeepSeek, parseHermes],
702
+ hermes: [parseHermes],
703
+ phi: [parsePhi, parsePhiFunctools, parseHermes],
704
+ internlm: [parseInternLM, parseHermes],
705
+ chatglm: [parseChatGLM],
706
+ glm: [parseChatGLM],
707
+ functiongemma: [parseFunctionGemma, parseGemma, parseHermes],
708
+ gemma: [parseFunctionGemma, parseGemma, parseHermes],
709
+ functionary: [parseFunctionary],
710
+ gorilla: [parseGorilla],
711
+ nexusraven: [parseNexusRaven],
712
+ xlam: [parseXLAM],
713
+ firefunction: [parseFireFunction, parsePhiFunctools],
714
+ granite: [parseGranite, parseHermes],
715
+ solar: [parseHermes],
716
+ jamba: [parseJamba, parseHermes],
717
+ liquid: [parseLiquid, parseHermes],
718
+ lfm: [parseLiquid, parseHermes],
719
+ yi: [parseHermes, parseLlama],
720
+ falcon: [parseHermes, parseLlama]
721
+ };
722
+ var DEFAULT_PARSER_CHAIN = [
723
+ parsePhi,
724
+ parseMistral,
725
+ parseDeepSeek,
726
+ parseInternLM,
727
+ parseGranite,
728
+ parseFunctionGemma,
729
+ parseQwen35Xml,
730
+ parseHermes,
731
+ parseCohere,
732
+ parseFunctionary,
733
+ parseGorilla,
734
+ parseNexusRaven,
735
+ parseFireFunction,
736
+ parsePhiFunctools,
737
+ parseLiquid,
738
+ parseLlama,
739
+ parseGemma,
740
+ parseXLAM
741
+ ];
742
+ function detectModelFamily(tokenizerOrName) {
743
+ let name = "";
744
+ if (typeof tokenizerOrName === "string") {
745
+ name = tokenizerOrName.toLowerCase();
746
+ } else if (tokenizerOrName) {
747
+ const config = tokenizerOrName.config ?? {};
748
+ name = (config.name_or_path ?? config._name_or_path ?? config.model_type ?? tokenizerOrName.name_or_path ?? "").toLowerCase();
749
+ }
750
+ if (!name)
751
+ return null;
752
+ for (const family of Object.keys(MODEL_PARSERS)) {
753
+ if (name.includes(family)) {
754
+ return family;
755
+ }
756
+ }
757
+ return null;
758
+ }
759
+ function parseToolCalls(text, { tokenizer = null, model = null, parser = null } = {}) {
760
+ if (!text || typeof text !== "string") {
761
+ return { tool_calls: [], content: text ?? "", parser: "none" };
762
+ }
763
+ let parsersToTry;
764
+ if (parser) {
765
+ const key = parser.toLowerCase();
766
+ const found = MODEL_PARSERS[key];
767
+ if (!found) {
768
+ throw new Error(`Unknown parser "${parser}". Available parsers: ${Object.keys(MODEL_PARSERS).join(", ")}`);
769
+ }
770
+ parsersToTry = found;
771
+ } else {
772
+ const family = detectModelFamily(tokenizer ?? model ?? null);
773
+ parsersToTry = family ? MODEL_PARSERS[family] : DEFAULT_PARSER_CHAIN;
774
+ }
775
+ for (const parserFn of parsersToTry) {
776
+ const result = parserFn(text);
777
+ if (result)
778
+ return result;
779
+ }
780
+ return { tool_calls: [], content: text, parser: "none" };
781
+ }
782
+ function hasToolCalls(text) {
783
+ if (!text)
784
+ return false;
785
+ return text.includes("<tool_call>") || text.includes("[TOOL_CALLS]") || text.includes("<|python_tag|>") || text.includes("<function=") || text.includes("<|tool_calls|>") || text.includes("<tool_calls>") || text.includes("<|action_start|>") || text.includes("<<function>>") || text.includes(">>>") || text.includes("Call:") || text.includes("Action:") || text.includes("functools") || text.includes("<start_function_call>") || text.includes("<|tool_call|>") || text.includes("<|tool_call_start|>") || /tool[\s\u2581]call[\s\u2581]begin/.test(text);
786
+ }
787
+ function getAvailableParsers() {
788
+ return Object.keys(MODEL_PARSERS);
789
+ }
790
+ function getGenerationPrefix(family, forcedToolName) {
791
+ if (!family)
792
+ return;
793
+ switch (family) {
794
+ case "functiongemma":
795
+ return forcedToolName ? `<start_function_call>call:${forcedToolName}{` : "<start_function_call>call:";
796
+ default:
797
+ return;
798
+ }
799
+ }
800
+ function parseToolCallsFromText(responseText) {
801
+ const functionGemmaResult = parseFunctionGemma(responseText);
802
+ if (functionGemmaResult && functionGemmaResult.tool_calls.length > 0) {
803
+ return {
804
+ text: functionGemmaResult.content,
805
+ toolCalls: functionGemmaResult.tool_calls.map((call, index) => ({
806
+ id: call.id ?? `call_${index}`,
807
+ name: call.name,
808
+ input: call.arguments
809
+ }))
810
+ };
811
+ }
812
+ const looseObject = parseFunctionGemmaLooseObject(responseText);
813
+ if (looseObject) {
814
+ return {
815
+ text: "",
816
+ toolCalls: [{ id: "call_0", name: "", input: looseObject }]
817
+ };
818
+ }
819
+ const hermesResult = parseHermes(responseText);
820
+ if (hermesResult && hermesResult.tool_calls.length > 0) {
821
+ return {
822
+ text: hermesResult.content,
823
+ toolCalls: hermesResult.tool_calls.map((call, index) => ({
824
+ id: call.id ?? `call_${index}`,
825
+ name: call.name,
826
+ input: call.arguments
827
+ }))
828
+ };
829
+ }
830
+ const toolCalls = [];
831
+ let callIndex = 0;
832
+ const jsonCandidates = findBalancedBlocks(responseText, "{", "}");
833
+ const matchedRanges = [];
834
+ for (const candidate of jsonCandidates) {
835
+ try {
836
+ const parsed = JSON.parse(candidate.text);
837
+ if (parsed.name && (parsed.arguments !== undefined || parsed.parameters !== undefined)) {
838
+ const id = `call_${callIndex++}`;
839
+ toolCalls.push({
840
+ id,
841
+ name: parsed.name,
842
+ input: parsed.arguments ?? parsed.parameters ?? {}
843
+ });
844
+ matchedRanges.push({ start: candidate.start, end: candidate.end });
845
+ } else if (parsed.function?.name) {
846
+ let functionArgs = parsed.function.arguments ?? {};
847
+ if (typeof functionArgs === "string") {
848
+ try {
849
+ functionArgs = JSON.parse(functionArgs);
850
+ } catch {
851
+ functionArgs = {};
852
+ }
853
+ }
854
+ const id = `call_${callIndex++}`;
855
+ toolCalls.push({
856
+ id,
857
+ name: parsed.function.name,
858
+ input: functionArgs ?? {}
859
+ });
860
+ matchedRanges.push({ start: candidate.start, end: candidate.end });
861
+ }
862
+ } catch {}
863
+ }
864
+ let cleanedText = responseText;
865
+ if (toolCalls.length > 0) {
866
+ let result = "";
867
+ let lastIndex = 0;
868
+ for (const range of matchedRanges) {
869
+ result += responseText.slice(lastIndex, range.start);
870
+ lastIndex = range.end;
871
+ }
872
+ result += responseText.slice(lastIndex);
873
+ cleanedText = result.trim();
874
+ }
875
+ return { text: cleanedText, toolCalls };
876
+ }
877
+ export {
878
+ tryParseJson,
879
+ stripModelArtifacts,
880
+ parseXLAM,
881
+ parseToolCallsFromText,
882
+ parseToolCalls,
883
+ parseQwen35Xml,
884
+ parsePhiFunctools,
885
+ parsePhi,
886
+ parseNexusRaven,
887
+ parseMistral,
888
+ parseLlama,
889
+ parseLiquid,
890
+ parseKeyValueArgs,
891
+ parseJsonToolCallArray,
892
+ parseJamba,
893
+ parseInternLM,
894
+ parseHermes,
895
+ parseGranite,
896
+ parseGorilla,
897
+ parseGemma,
898
+ parseFunctionary,
899
+ parseFunctionGemmaLooseObject,
900
+ parseFunctionGemmaArgumentValue,
901
+ parseFunctionGemma,
902
+ parseFireFunction,
903
+ parseDeepSeek,
904
+ parseCohere,
905
+ parseChatGLM,
906
+ makeToolCall,
907
+ hasToolCalls,
908
+ getGenerationPrefix,
909
+ getAvailableParsers,
910
+ coerceArgValue
911
+ };
912
+
913
+ //# debugId=846853B19CC40B4B64756E2164756E21