llm-exe 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -333,6 +333,123 @@ var BaseParserWithJson = class extends BaseParser {
333
333
  }
334
334
  };
335
335
 
336
+ // src/utils/modules/assert.ts
337
+ function assert(condition, message) {
338
+ if (condition === void 0 || condition === null || condition === false) {
339
+ if (typeof message === "string") {
340
+ throw new Error(message);
341
+ } else if (message instanceof Error) {
342
+ throw message;
343
+ } else {
344
+ throw new Error(`Assertion error`);
345
+ }
346
+ }
347
+ }
348
+
349
+ // src/utils/guards.ts
350
+ var guards_exports = {};
351
+ __export(guards_exports, {
352
+ hasFunctionCall: () => hasFunctionCall,
353
+ hasToolCall: () => hasToolCall,
354
+ isAssistantMessage: () => isAssistantMessage,
355
+ isFunctionCall: () => isFunctionCall,
356
+ isOutputResult: () => isOutputResult,
357
+ isOutputResultContentText: () => isOutputResultContentText,
358
+ isSystemMessage: () => isSystemMessage,
359
+ isToolCall: () => isToolCall,
360
+ isUserMessage: () => isUserMessage
361
+ });
362
+ function isOutputResult(obj) {
363
+ return !!(obj && typeof obj === "object" && "id" in obj && "stopReason" in obj && "content" in obj && Array.isArray(obj.content));
364
+ }
365
+ function isOutputResultContentText(obj) {
366
+ return !!(obj && typeof obj === "object" && "text" in obj && "type" in obj && obj.type === "text" && typeof obj.text === "string");
367
+ }
368
+ function isFunctionCall(result) {
369
+ return !!(result && typeof result === "object" && "functionId" in result && "type" in result && result.type === "function_use");
370
+ }
371
+ function isToolCall(result) {
372
+ return isFunctionCall(result);
373
+ }
374
+ function hasFunctionCall(results) {
375
+ return !!(results && Array.isArray(results) && results.some(isToolCall));
376
+ }
377
+ function hasToolCall(results) {
378
+ return hasFunctionCall(results);
379
+ }
380
+ function isUserMessage(message) {
381
+ return message.role === "user";
382
+ }
383
+ function isAssistantMessage(message) {
384
+ return message.role === "assistant" || message.role === "model";
385
+ }
386
+ function isSystemMessage(message) {
387
+ return message.role === "system";
388
+ }
389
+
390
+ // src/parser/parsers/StringParser.ts
391
+ var StringParser = class extends BaseParser {
392
+ constructor(options) {
393
+ super("string", options);
394
+ }
395
+ parse(text, _options) {
396
+ if (isOutputResult(text)) {
397
+ return text.content?.[0]?.text ?? "";
398
+ }
399
+ assert(
400
+ typeof text === "string",
401
+ `Invalid input. Expected string. Received ${typeof text}.`
402
+ );
403
+ const parsed = text.toString();
404
+ return parsed;
405
+ }
406
+ };
407
+
408
+ // src/parser/parsers/BooleanParser.ts
409
+ var BooleanParser = class extends BaseParser {
410
+ constructor(options) {
411
+ super("boolean", options);
412
+ }
413
+ parse(text) {
414
+ assert(
415
+ typeof text === "string",
416
+ `Invalid input. Expected string. Received ${typeof text}.`
417
+ );
418
+ const clean = text.toLowerCase().trim();
419
+ if (clean === "true") {
420
+ return true;
421
+ }
422
+ return false;
423
+ }
424
+ };
425
+
426
+ // src/utils/modules/isFinite.ts
427
+ function isFinite(value) {
428
+ return typeof value === "number" && Number.isFinite(value);
429
+ }
430
+
431
+ // src/utils/modules/toNumber.ts
432
+ function toNumber(value) {
433
+ if (typeof value === "number") {
434
+ return value;
435
+ }
436
+ if (typeof value === "string" && value.trim() !== "") {
437
+ return Number(value);
438
+ }
439
+ return NaN;
440
+ }
441
+
442
+ // src/parser/parsers/NumberParser.ts
443
+ var NumberParser = class extends BaseParser {
444
+ constructor(options) {
445
+ super("number", options);
446
+ }
447
+ parse(text) {
448
+ const match = text.match(/\d/g);
449
+ return match && isFinite(toNumber(match[0])) ? toNumber(match[0]) : -1;
450
+ }
451
+ };
452
+
336
453
  // src/utils/index.ts
337
454
  var utils_exports = {};
338
455
  __export(utils_exports, {
@@ -352,19 +469,6 @@ __export(utils_exports, {
352
469
  replaceTemplateStringAsync: () => replaceTemplateStringAsync
353
470
  });
354
471
 
355
- // src/utils/modules/assert.ts
356
- function assert(condition, message) {
357
- if (condition === void 0 || condition === null || condition === false) {
358
- if (typeof message === "string") {
359
- throw new Error(message);
360
- } else if (message instanceof Error) {
361
- throw message;
362
- } else {
363
- throw new Error(`Assertion error`);
364
- }
365
- }
366
- }
367
-
368
472
  // src/utils/modules/defineSchema.ts
369
473
  import { asConst } from "json-schema-to-ts";
370
474
  function defineSchema(obj) {
@@ -410,17 +514,6 @@ function importHelpers(_helpers) {
410
514
  return helpers;
411
515
  }
412
516
 
413
- // src/utils/modules/toNumber.ts
414
- function toNumber(value) {
415
- if (typeof value === "number") {
416
- return value;
417
- }
418
- if (typeof value === "string" && value.trim() !== "") {
419
- return Number(value);
420
- }
421
- return NaN;
422
- }
423
-
424
517
  // src/utils/modules/get.ts
425
518
  function get(obj, path, defaultValue) {
426
519
  if (obj == null || path === "" || Array.isArray(path) && path.length === 0) {
@@ -1320,82 +1413,6 @@ function registerPartials(partials2) {
1320
1413
  hbsAsync.registerPartials(partials2);
1321
1414
  }
1322
1415
 
1323
- // src/llm/output/_utils/getResultText.ts
1324
- function getResultText(content) {
1325
- if (content.length === 1 && content.every((a) => a.type === "text")) {
1326
- return content[0]?.text || "";
1327
- }
1328
- return "";
1329
- }
1330
-
1331
- // src/parser/parsers/OpenAiFunctionParser.ts
1332
- var OpenAiFunctionParser = class extends BaseParser {
1333
- constructor(options) {
1334
- super("openAiFunction", options, "function_call");
1335
- __publicField(this, "parser");
1336
- this.parser = options.parser;
1337
- }
1338
- parse(text, _options) {
1339
- const functionUse = text?.find((a) => a.type === "function_use");
1340
- if (functionUse && "name" in functionUse && "input" in functionUse) {
1341
- return {
1342
- name: functionUse.name,
1343
- arguments: maybeParseJSON(functionUse.input)
1344
- };
1345
- }
1346
- return this.parser.parse(getResultText(text));
1347
- }
1348
- };
1349
-
1350
- // src/parser/parsers/StringParser.ts
1351
- var StringParser = class extends BaseParser {
1352
- constructor(options) {
1353
- super("string", options);
1354
- }
1355
- parse(text, _options) {
1356
- assert(
1357
- typeof text === "string",
1358
- `Invalid input. Expected string. Received ${typeof text}.`
1359
- );
1360
- const parsed = text.toString();
1361
- return parsed;
1362
- }
1363
- };
1364
-
1365
- // src/parser/parsers/BooleanParser.ts
1366
- var BooleanParser = class extends BaseParser {
1367
- constructor(options) {
1368
- super("boolean", options);
1369
- }
1370
- parse(text) {
1371
- assert(
1372
- typeof text === "string",
1373
- `Invalid input. Expected string. Received ${typeof text}.`
1374
- );
1375
- const clean = text.toLowerCase().trim();
1376
- if (clean === "true") {
1377
- return true;
1378
- }
1379
- return false;
1380
- }
1381
- };
1382
-
1383
- // src/utils/modules/isFinite.ts
1384
- function isFinite(value) {
1385
- return typeof value === "number" && Number.isFinite(value);
1386
- }
1387
-
1388
- // src/parser/parsers/NumberParser.ts
1389
- var NumberParser = class extends BaseParser {
1390
- constructor(options) {
1391
- super("number", options);
1392
- }
1393
- parse(text) {
1394
- const match = text.match(/\d/g);
1395
- return match && isFinite(toNumber(match[0])) ? toNumber(match[0]) : -1;
1396
- }
1397
- };
1398
-
1399
1416
  // src/parser/_utils.ts
1400
1417
  import { validate as validateSchema } from "jsonschema";
1401
1418
  function enforceParserSchema(schema, parsed) {
@@ -1688,6 +1705,46 @@ function createCustomParser(name, parserFn) {
1688
1705
  return new CustomParser(name, parserFn);
1689
1706
  }
1690
1707
 
1708
+ // src/parser/parsers/LlmNativeFunctionParser.ts
1709
+ var LlmFunctionParser = class extends BaseParser {
1710
+ constructor(options) {
1711
+ super("functionCall", options, "function_call");
1712
+ __publicField(this, "parser");
1713
+ this.parser = options.parser;
1714
+ }
1715
+ parse(text, _options) {
1716
+ if (typeof text === "string") {
1717
+ return this.parser.parse(text);
1718
+ }
1719
+ const { content } = text;
1720
+ const functionUses = content?.filter((a) => a.type === "function_use") || [];
1721
+ if (functionUses.length === 0) {
1722
+ const [item] = content;
1723
+ return this.parser.parse(item.text);
1724
+ }
1725
+ return content;
1726
+ }
1727
+ };
1728
+ var LlmNativeFunctionParser = class extends BaseParser {
1729
+ constructor(options) {
1730
+ super("openAiFunction", options, "function_call");
1731
+ __publicField(this, "parser");
1732
+ this.parser = options.parser;
1733
+ }
1734
+ parse(text, _options) {
1735
+ const { content } = text;
1736
+ const functionUse = content?.find((a) => a.type === "function_use");
1737
+ if (functionUse && "name" in functionUse && "input" in functionUse) {
1738
+ return {
1739
+ name: functionUse.name,
1740
+ arguments: maybeParseJSON(functionUse.input)
1741
+ };
1742
+ }
1743
+ return this.parser.parse(text?.text ?? text);
1744
+ }
1745
+ };
1746
+ var OpenAiFunctionParser = LlmNativeFunctionParser;
1747
+
1691
1748
  // src/executor/llm.ts
1692
1749
  var LlmExecutor = class extends BaseExecutor {
1693
1750
  constructor(llmConfiguration, options) {
@@ -1743,7 +1800,7 @@ var LlmExecutor = class extends BaseExecutor {
1743
1800
  }
1744
1801
  getHandlerOutput(out, _metadata) {
1745
1802
  if (this.parser.target === "function_call") {
1746
- const outToStr = out.getResultContent();
1803
+ const outToStr = out.getResult();
1747
1804
  return this.parser.parse(outToStr, _metadata);
1748
1805
  } else {
1749
1806
  const outToStr = out.getResultText();
@@ -1763,31 +1820,55 @@ var LlmExecutor = class extends BaseExecutor {
1763
1820
  }
1764
1821
  };
1765
1822
 
1766
- // src/executor/_functions.ts
1767
- function createCoreExecutor(handler, options) {
1768
- return new CoreExecutor({ handler }, options);
1769
- }
1770
- function createLlmExecutor(llmConfiguration, options) {
1771
- return new LlmExecutor(llmConfiguration, options);
1772
- }
1773
-
1774
1823
  // src/executor/llm-openai-function.ts
1824
+ var LlmExecutorWithFunctions = class extends LlmExecutor {
1825
+ constructor(llmConfiguration, options) {
1826
+ super(
1827
+ Object.assign({}, llmConfiguration, {
1828
+ parser: new LlmFunctionParser({
1829
+ parser: llmConfiguration.parser || new StringParser()
1830
+ })
1831
+ }),
1832
+ options
1833
+ );
1834
+ }
1835
+ async execute(_input, _options) {
1836
+ return super.execute(_input, _options);
1837
+ }
1838
+ };
1775
1839
  var LlmExecutorOpenAiFunctions = class extends LlmExecutor {
1776
1840
  constructor(llmConfiguration, options) {
1777
1841
  super(
1778
1842
  Object.assign({}, llmConfiguration, {
1779
- parser: new OpenAiFunctionParser({
1843
+ parser: new LlmNativeFunctionParser({
1780
1844
  parser: llmConfiguration.parser || new StringParser()
1781
1845
  })
1782
1846
  }),
1783
1847
  options
1784
1848
  );
1849
+ console.warn(
1850
+ `LlmExecutorOpenAiFunctions is deprecated. Please migrate to LlmExecutorWithFunctions`
1851
+ );
1785
1852
  }
1786
1853
  async execute(_input, _options) {
1787
1854
  return super.execute(_input, _options);
1788
1855
  }
1789
1856
  };
1790
1857
 
1858
+ // src/executor/_functions.ts
1859
+ function createCoreExecutor(handler, options) {
1860
+ return new CoreExecutor({ handler }, options);
1861
+ }
1862
+ function createLlmExecutor(llmConfiguration, options) {
1863
+ return new LlmExecutor(llmConfiguration, options);
1864
+ }
1865
+ function createLlmFunctionExecutor(llmConfiguration, options) {
1866
+ return new LlmExecutorWithFunctions(
1867
+ llmConfiguration,
1868
+ options
1869
+ );
1870
+ }
1871
+
1791
1872
  // src/utils/modules/enforceResultAttributes.ts
1792
1873
  function enforceResultAttributes(input) {
1793
1874
  if (!input) {
@@ -1976,6 +2057,39 @@ function getEnvironmentVariable(name) {
1976
2057
  }
1977
2058
  }
1978
2059
 
2060
+ // src/llm/config/openai/promptSanitizeMessageCallback.ts
2061
+ function openaiPromptMessageCallback(_message) {
2062
+ let message = { ..._message };
2063
+ if (message.role === "function") {
2064
+ message.role = "tool";
2065
+ message.tool_call_id = message.id;
2066
+ delete message.id;
2067
+ }
2068
+ if (message?.function_call) {
2069
+ const { function_call } = message;
2070
+ const toolsArr = Array.isArray(function_call) ? function_call : [function_call];
2071
+ message.role = "assistant";
2072
+ message.tool_calls = toolsArr.map((call) => {
2073
+ const { id, ...functionCall } = call;
2074
+ return {
2075
+ id,
2076
+ type: "function",
2077
+ function: functionCall
2078
+ };
2079
+ });
2080
+ delete message.function_call;
2081
+ }
2082
+ return message;
2083
+ }
2084
+
2085
+ // src/llm/config/openai/promptSanitize.ts
2086
+ function openaiPromptSanitize(_messages, _inputBodyObj, _outputObj) {
2087
+ if (typeof _messages === "string") {
2088
+ return [{ role: "user", content: _messages }];
2089
+ }
2090
+ return _messages.map(openaiPromptMessageCallback);
2091
+ }
2092
+
1979
2093
  // src/llm/config/openai/index.ts
1980
2094
  var openAiChatV1 = {
1981
2095
  key: "openai.chat.v1",
@@ -1994,12 +2108,7 @@ var openAiChatV1 = {
1994
2108
  mapBody: {
1995
2109
  prompt: {
1996
2110
  key: "messages",
1997
- sanitize: (v) => {
1998
- if (typeof v === "string") {
1999
- return [{ role: "user", content: v }];
2000
- }
2001
- return v;
2002
- }
2111
+ sanitize: openaiPromptSanitize
2003
2112
  },
2004
2113
  model: {
2005
2114
  key: "model"
@@ -2050,14 +2159,54 @@ var openai = {
2050
2159
  "openai.gpt-4o-mini": withDefaultModel(openAiChatV1, "gpt-4o-mini")
2051
2160
  };
2052
2161
 
2162
+ // src/llm/config/anthropic/promptSanitizeMessageCallback.ts
2163
+ function anthropicPromptMessageCallback(_message) {
2164
+ let message = { ..._message };
2165
+ if (message.role === "function") {
2166
+ message.role = "user";
2167
+ message.content = [
2168
+ {
2169
+ type: "tool_result",
2170
+ tool_use_id: message.id,
2171
+ content: maybeStringifyJSON(message.content)
2172
+ }
2173
+ ];
2174
+ delete message.name;
2175
+ delete message.id;
2176
+ }
2177
+ if (message?.function_call) {
2178
+ const { function_call } = message;
2179
+ const toolsArr = Array.isArray(function_call) ? function_call : [function_call];
2180
+ message.role = "assistant";
2181
+ message.content = toolsArr.map((call) => {
2182
+ const { id, name, arguments: input } = call;
2183
+ return {
2184
+ type: "tool_use",
2185
+ id,
2186
+ name,
2187
+ input: maybeParseJSON(input)
2188
+ };
2189
+ });
2190
+ delete message.function_call;
2191
+ }
2192
+ return message;
2193
+ }
2194
+
2053
2195
  // src/llm/config/anthropic/promptSanitize.ts
2054
2196
  function anthropicPromptSanitize(_messages, _inputBodyObj, _outputObj) {
2055
2197
  if (typeof _messages === "string") {
2056
- return [{ role: "user", content: _messages }];
2198
+ return [{ role: "user", content: _messages }].map(
2199
+ anthropicPromptMessageCallback
2200
+ );
2057
2201
  }
2058
- const [first, ...messages] = [..._messages.map((a) => ({ ...a }))];
2202
+ const [first, ...messages] = [
2203
+ ..._messages.map((a) => ({ ...a }))
2204
+ ];
2059
2205
  if (first.role === "system" && messages.length === 0) {
2060
- return [{ role: "user", content: first.content }, ...messages];
2206
+ return [
2207
+ { role: "user", content: first.content },
2208
+ ...messages
2209
+ ].map(anthropicPromptMessageCallback);
2061
2210
  }
2062
2211
  if (first.role === "system" && messages.length > 0) {
2063
2212
  _outputObj.system = first.content;
@@ -2066,7 +2215,7 @@ function anthropicPromptSanitize(_messages, _inputBodyObj, _outputObj) {
2066
2215
  return { ...m, role: "user" };
2067
2216
  }
2068
2217
  return m;
2069
- });
2218
+ }).map(anthropicPromptMessageCallback);
2070
2219
  }
2071
2220
  return [
2072
2221
  first,
@@ -2076,7 +2225,7 @@ function anthropicPromptSanitize(_messages, _inputBodyObj, _outputObj) {
2076
2225
  }
2077
2226
  return m;
2078
2227
  })
2079
- ];
2228
+ ].map(anthropicPromptMessageCallback);
2080
2229
  }
2081
2230
 
2082
2231
  // src/llm/config/bedrock/index.ts
@@ -2295,30 +2444,49 @@ var ollama = {
2295
2444
  "ollama.qwq": withDefaultModel(ollamaChatV1, "qwq")
2296
2445
  };
2297
2446
 
2298
- // src/utils/modules/modifyPromptRoleChange.ts
2299
- function modifyPromptRoleChange(messages, roleChanges) {
2300
- const roleChangeMap = new Map(roleChanges.map(({ from, to }) => [from, to]));
2301
- if (Array.isArray(messages)) {
2302
- return messages.map((message) => {
2303
- const newRole2 = roleChangeMap.get(message.role);
2304
- return newRole2 ? { ...message, role: newRole2 } : message;
2305
- });
2306
- }
2307
- const newRole = roleChangeMap.get(messages.role);
2308
- return newRole ? { ...messages, role: newRole } : messages;
2309
- }
2310
-
2311
2447
  // src/llm/config/google/promptSanitizeMessageCallback.ts
2312
2448
  function googleGeminiPromptMessageCallback(_message) {
2313
2449
  let message = { ..._message };
2314
- message = modifyPromptRoleChange(_message, [
2315
- { from: "assistant", to: "model" }
2316
- ]);
2317
- const { role, ...payload } = message;
2318
2450
  const parts = [];
2451
+ if (message.role === "assistant") {
2452
+ message.role = "model";
2453
+ }
2454
+ if (message.role === "system") {
2455
+ message.role = "model";
2456
+ }
2457
+ let { role, ...payload } = message;
2319
2458
  if (typeof payload.content === "string") {
2320
2459
  parts.push({ text: message.content });
2321
2460
  }
2461
+ if (message.role === "function") {
2462
+ role = "user";
2463
+ parts.push({
2464
+ functionResponse: {
2465
+ name: message.name,
2466
+ response: {
2467
+ result: message.content
2468
+ }
2469
+ }
2470
+ });
2471
+ delete message.id;
2472
+ }
2473
+ if (message?.function_call) {
2474
+ const { function_call } = message;
2475
+ const toolsArr = Array.isArray(function_call) ? function_call : [function_call];
2476
+ role = "model";
2477
+ parts.push(
2478
+ ...toolsArr.map((call) => {
2479
+ const { name, arguments: input } = call;
2480
+ return {
2481
+ functionCall: {
2482
+ name,
2483
+ args: maybeParseJSON(input)
2484
+ }
2485
+ };
2486
+ })
2487
+ );
2488
+ delete message.function_call;
2489
+ }
2322
2490
  return {
2323
2491
  role,
2324
2492
  parts
@@ -2348,7 +2516,9 @@ function googleGeminiPromptSanitize(_messages, _inputBodyObj, _outputObj) {
2348
2516
  (message) => message.role !== "system"
2349
2517
  );
2350
2518
  _outputObj.system_instruction = {
2351
- parts: theSystemInstructions.map((message) => ({ text: message.content }))
2519
+ parts: theSystemInstructions.map((message) => ({
2520
+ text: message.content
2521
+ }))
2352
2522
  };
2353
2523
  return withoutSystemInstructions.map(googleGeminiPromptMessageCallback);
2354
2524
  }
@@ -2469,7 +2639,7 @@ function getLlmConfig(provider) {
2469
2639
 
2470
2640
  // src/llm/output/_utils/getResultContent.ts
2471
2641
  function getResultContent(result, index) {
2472
- if (index && index > 0) {
2642
+ if (typeof index === "number" && index > 0) {
2473
2643
  const arr = result?.options || [];
2474
2644
  const val = arr[index];
2475
2645
  return val ? val : [];
@@ -2477,6 +2647,16 @@ function getResultContent(result, index) {
2477
2647
  return [...result.content];
2478
2648
  }
2479
2649
 
2650
+ // src/llm/output/_utils/getResultText.ts
2651
+ function getResultText(result, index) {
2652
+ if (typeof index === "number" && index > 0) {
2653
+ const arr = result?.options || [];
2654
+ const val = arr[index];
2655
+ return isOutputResultContentText(val?.[0]) ? val[0]?.text : "";
2656
+ }
2657
+ return isOutputResultContentText(result?.content?.[0]) ? result.content[0]?.text : "";
2658
+ }
2659
+
2480
2660
  // src/llm/output/base.ts
2481
2661
  function BaseLlmOutput2(result) {
2482
2662
  const __result = Object.freeze({
@@ -2501,7 +2681,7 @@ function BaseLlmOutput2(result) {
2501
2681
  }
2502
2682
  return {
2503
2683
  getResultContent: (index) => getResultContent(__result, index),
2504
- getResultText: () => getResultText(__result.content),
2684
+ getResultText: (index) => getResultText(__result, index),
2505
2685
  getResult
2506
2686
  };
2507
2687
  }
@@ -2536,25 +2716,24 @@ function formatContent(response, handler) {
2536
2716
 
2537
2717
  // src/llm/output/openai.ts
2538
2718
  function formatResult(result) {
2719
+ const out = [];
2539
2720
  if (typeof result?.message?.content === "string") {
2540
- return {
2721
+ out.push({
2541
2722
  type: "text",
2542
2723
  text: result.message.content
2543
- };
2544
- } else if (result?.message && "tool_calls" in result.message) {
2545
- const tool_calls = result.message.tool_calls;
2546
- for (const call of tool_calls) {
2547
- return {
2724
+ });
2725
+ }
2726
+ if (result?.message?.tool_calls) {
2727
+ for (const call of result.message.tool_calls) {
2728
+ out.push({
2729
+ functionId: call.id,
2548
2730
  type: "function_use",
2549
2731
  name: call.function.name,
2550
- input: JSON.parse(call.function.arguments)
2551
- };
2732
+ input: maybeParseJSON(call.function.arguments)
2733
+ });
2552
2734
  }
2553
2735
  }
2554
- return {
2555
- type: "text",
2556
- text: ""
2557
- };
2736
+ return out;
2558
2737
  }
2559
2738
  function OutputOpenAIChat(result, _config) {
2560
2739
  const id = result.id;
@@ -2562,7 +2741,7 @@ function OutputOpenAIChat(result, _config) {
2562
2741
  const created = result.created;
2563
2742
  const [_content, ..._options] = result?.choices || [];
2564
2743
  const stopReason = _content?.finish_reason;
2565
- const content = formatContent(_content, formatResult);
2744
+ const content = formatResult(_content);
2566
2745
  const options = formatOptions(_options, formatResult);
2567
2746
  const usage = {
2568
2747
  output_tokens: result?.usage?.completion_tokens,
@@ -2593,6 +2772,7 @@ function formatResult2(response) {
2593
2772
  });
2594
2773
  } else if (result.type === "tool_use") {
2595
2774
  out.push({
2775
+ functionId: result.id,
2596
2776
  type: "function_use",
2597
2777
  name: result.name,
2598
2778
  input: result.input
@@ -2670,12 +2850,15 @@ function formatResult3(result) {
2670
2850
  };
2671
2851
  } else if (result?.message && "tool_calls" in result.message) {
2672
2852
  const tool_calls = result.message.tool_calls;
2673
- for (const call of tool_calls) {
2674
- return {
2675
- type: "function_use",
2676
- name: call.function.name,
2677
- input: JSON.parse(call.function.arguments)
2678
- };
2853
+ if (tool_calls) {
2854
+ for (const call of tool_calls) {
2855
+ return {
2856
+ functionId: call.id,
2857
+ type: "function_use",
2858
+ name: call.function.name,
2859
+ input: JSON.parse(call.function.arguments)
2860
+ };
2861
+ }
2679
2862
  }
2680
2863
  }
2681
2864
  return {
@@ -2780,37 +2963,36 @@ function OutputOllamaChat(result, _config) {
2780
2963
  }
2781
2964
 
2782
2965
  // src/llm/output/google.gemini/formatResult.ts
2783
- function formatResult4(result) {
2966
+ function formatResult4(result, id) {
2784
2967
  const { parts = [] } = result?.content || {};
2785
- if (parts.length === 1) {
2786
- const answer = parts[0];
2787
- if (!!answer?.functionCall && typeof answer?.functionCall === "object") {
2788
- return {
2789
- type: "function_use",
2790
- name: answer.functionCall.name,
2791
- input: JSON.parse(answer.functionCall.args)
2792
- };
2793
- } else {
2794
- return {
2968
+ const out = [];
2969
+ for (let i = 0; i < parts.length; i++) {
2970
+ const part = parts[i];
2971
+ if (typeof part.text === "string") {
2972
+ out.push({
2795
2973
  type: "text",
2796
- text: answer.text || ""
2797
- };
2974
+ text: part.text
2975
+ });
2976
+ } else if (part?.functionCall) {
2977
+ out.push({
2978
+ functionId: `${id || uuidv4()}-${i}`,
2979
+ type: "function_use",
2980
+ name: part.functionCall.name,
2981
+ input: maybeParseJSON(part.functionCall.args)
2982
+ });
2798
2983
  }
2799
2984
  }
2800
- return {
2801
- type: "text",
2802
- text: ""
2803
- };
2985
+ return out;
2804
2986
  }
2805
2987
 
2806
2988
  // src/llm/output/google.gemini/index.ts
2807
2989
  function OutputGoogleGeminiChat(result, _config) {
2808
- const id = "result.id";
2809
- const name = result.modelVersion;
2990
+ const id = result.responseId;
2991
+ const name = result.modelVersion || _config?.model || "gemini";
2810
2992
  const created = (/* @__PURE__ */ new Date()).getTime();
2811
2993
  const [_content, ..._options] = result?.candidates || [];
2812
2994
  const stopReason = _content?.finishReason?.toLowerCase();
2813
- const content = formatContent(_content, formatResult4);
2995
+ const content = formatResult4(_content, id);
2814
2996
  const options = formatOptions(_options, formatResult4);
2815
2997
  const usage = {
2816
2998
  output_tokens: result?.usageMetadata?.candidatesTokenCount,
@@ -2829,7 +3011,7 @@ function OutputGoogleGeminiChat(result, _config) {
2829
3011
  }
2830
3012
 
2831
3013
  // src/llm/output/index.ts
2832
- function getOutputParser(config, response) {
3014
+ function normalizeLlmOutputToInternalFormat(config, response) {
2833
3015
  switch (config?.key) {
2834
3016
  case "openai.chat.v1":
2835
3017
  case "openai.chat-mock.v1":
@@ -3077,11 +3259,20 @@ async function parseHeaders(config, replacements, payload) {
3077
3259
 
3078
3260
  // src/llm/output/_utils/cleanJsonSchemaFor.ts
3079
3261
  var providerFieldExclusions = {
3080
- "openai.chat": ["default"]
3262
+ "openai.chat": ["default"],
3263
+ // fields to exclude for openai.chat
3264
+ "anthropic.chat": []
3081
3265
  // fields to exclude for openai.chat
3082
3266
  };
3083
3267
  function cleanJsonSchemaFor(schema = {}, provider) {
3084
3268
  const clone = deepClone(schema);
3269
+ if (Object.keys(clone).length === 0) {
3270
+ return {
3271
+ type: "object",
3272
+ properties: {},
3273
+ required: []
3274
+ };
3275
+ }
3085
3276
  const exclusions = providerFieldExclusions[provider] || [];
3086
3277
  function removeDisallowedFields(obj) {
3087
3278
  if (Array.isArray(obj)) {
@@ -3110,7 +3301,7 @@ async function useLlm_call(state, messages, _options) {
3110
3301
  })
3111
3302
  );
3112
3303
  if (_options && _options?.jsonSchema) {
3113
- if (state.provider === "openai.chat") {
3304
+ if (state.provider.startsWith("openai")) {
3114
3305
  const curr = input["response_format"] || {};
3115
3306
  input["response_format"] = Object.assign(curr, {
3116
3307
  type: "json_schema",
@@ -3123,7 +3314,7 @@ async function useLlm_call(state, messages, _options) {
3123
3314
  }
3124
3315
  }
3125
3316
  if (_options && _options?.functionCall) {
3126
- if (state.provider === "anthropic.chat") {
3317
+ if (state.provider.startsWith("anthropic")) {
3127
3318
  if (_options?.functionCall === "none") {
3128
3319
  _options.functions = [];
3129
3320
  } else if (_options?.functionCall === "auto" || _options?.functionCall === "any") {
@@ -3131,21 +3322,27 @@ async function useLlm_call(state, messages, _options) {
3131
3322
  } else {
3132
3323
  input["tool_choice"] = _options?.functionCall;
3133
3324
  }
3134
- } else if (state.provider === "openai.chat") {
3325
+ } else if (state.provider.startsWith("openai")) {
3135
3326
  input["tool_choice"] = normalizeFunctionCall(
3136
3327
  _options?.functionCall,
3137
3328
  "openai"
3138
3329
  );
3330
+ } else if (state.provider.startsWith("google")) {
3331
+ input["toolConfig"] = {
3332
+ functionCallingConfig: {
3333
+ mode: normalizeFunctionCall(_options?.functionCall, "google")
3334
+ }
3335
+ };
3139
3336
  }
3140
3337
  }
3141
3338
  if (_options && _options?.functions?.length) {
3142
- if (state.provider === "anthropic.chat") {
3339
+ if (state.provider.startsWith("anthropic")) {
3143
3340
  input["tools"] = _options.functions.map((f) => ({
3144
3341
  name: f.name,
3145
3342
  description: f.description,
3146
- input_schema: f.parameters
3343
+ input_schema: cleanJsonSchemaFor(f.parameters, "anthropic.chat")
3147
3344
  }));
3148
- } else if (state.provider === "openai.chat") {
3345
+ } else if (state.provider.startsWith("openai")) {
3149
3346
  input["tools"] = _options.functions.map((f) => {
3150
3347
  const props = {
3151
3348
  name: f?.name,
@@ -3163,6 +3360,16 @@ async function useLlm_call(state, messages, _options) {
3163
3360
  )
3164
3361
  };
3165
3362
  });
3363
+ } else if (state.provider.startsWith("google")) {
3364
+ input["tools"] = [
3365
+ {
3366
+ functionDeclarations: _options.functions.map((f) => ({
3367
+ name: f.name,
3368
+ description: f.description,
3369
+ parameters: cleanJsonSchemaFor(f.parameters, "google.chat")
3370
+ }))
3371
+ }
3372
+ ];
3166
3373
  }
3167
3374
  }
3168
3375
  const body = JSON.stringify(input);
@@ -3192,7 +3399,7 @@ async function useLlm_call(state, messages, _options) {
3192
3399
  body,
3193
3400
  headers
3194
3401
  });
3195
- return getOutputParser(state, response);
3402
+ return normalizeLlmOutputToInternalFormat(state, response);
3196
3403
  }
3197
3404
 
3198
3405
  // src/llm/_utils.stateFromOptions.ts
@@ -3764,7 +3971,7 @@ var ChatPrompt = class extends BasePrompt {
3764
3971
  this.parseUserTemplates = options?.allowUnsafeUserTemplate;
3765
3972
  }
3766
3973
  }
3767
- addToPrompt(content, role, name) {
3974
+ addToPrompt(content, role, name, id) {
3768
3975
  if (content) {
3769
3976
  switch (role) {
3770
3977
  case "system":
@@ -3778,11 +3985,11 @@ var ChatPrompt = class extends BasePrompt {
3778
3985
  break;
3779
3986
  case "function":
3780
3987
  assert(name, "Function message requires name");
3781
- this.addFunctionMessage(content, name);
3988
+ this.addFunctionMessage(content, name, id);
3782
3989
  break;
3783
3990
  case "function_call":
3784
3991
  assert(name, "Function message requires name");
3785
- this.addFunctionCallMessage({ name, arguments: content });
3992
+ this.addFunctionCallMessage({ name, arguments: content, id });
3786
3993
  break;
3787
3994
  }
3788
3995
  }
@@ -3822,11 +4029,12 @@ var ChatPrompt = class extends BasePrompt {
3822
4029
  * @param content The message content.
3823
4030
  * @return ChatPrompt so it can be chained.
3824
4031
  */
3825
- addFunctionMessage(content, name) {
4032
+ addFunctionMessage(content, name, id) {
3826
4033
  this.messages.push({
3827
4034
  role: "function",
3828
4035
  name,
3829
- content
4036
+ content,
4037
+ id
3830
4038
  });
3831
4039
  return this;
3832
4040
  }
@@ -3838,8 +4046,9 @@ var ChatPrompt = class extends BasePrompt {
3838
4046
  addFunctionCallMessage(function_call) {
3839
4047
  if (function_call) {
3840
4048
  this.messages.push({
3841
- role: "assistant",
4049
+ role: "function_call",
3842
4050
  function_call: {
4051
+ id: function_call.id,
3843
4052
  name: function_call.name,
3844
4053
  arguments: maybeStringifyJSON(function_call.arguments)
3845
4054
  },
@@ -3861,17 +4070,16 @@ var ChatPrompt = class extends BasePrompt {
3861
4070
  this.addUserMessage(message.content, message?.name);
3862
4071
  break;
3863
4072
  case "assistant":
3864
- if (message.function_call) {
3865
- this.addFunctionCallMessage(message.function_call);
3866
- } else if (message?.content) {
3867
- this.addAssistantMessage(message?.content);
3868
- }
4073
+ this.addAssistantMessage(message?.content);
3869
4074
  break;
3870
4075
  case "system":
3871
4076
  this.addSystemMessage(message.content);
3872
4077
  break;
4078
+ case "function_call":
4079
+ this.addFunctionCallMessage(message.function_call);
4080
+ break;
3873
4081
  case "function":
3874
- this.addFunctionMessage(message.content, message.name);
4082
+ this.addFunctionMessage(message.content, message.name, message.id);
3875
4083
  break;
3876
4084
  }
3877
4085
  }
@@ -3935,20 +4143,19 @@ var ChatPrompt = class extends BasePrompt {
3935
4143
  break;
3936
4144
  }
3937
4145
  case "assistant": {
3938
- if (message.function_call) {
3939
- messagesOut.push({
3940
- role: "assistant",
3941
- content: null,
3942
- function_call: message.function_call
3943
- });
3944
- } else if (message?.content) {
3945
- messagesOut.push({
3946
- role: "assistant",
3947
- content: message.content
3948
- });
3949
- }
4146
+ messagesOut.push({
4147
+ role: "assistant",
4148
+ content: message.content
4149
+ });
3950
4150
  break;
3951
4151
  }
4152
+ case "function_call":
4153
+ messagesOut.push({
4154
+ role: "function_call",
4155
+ content: null,
4156
+ function_call: message.function_call
4157
+ });
4158
+ break;
3952
4159
  case "function":
3953
4160
  messagesOut.push({
3954
4161
  role: "function",
@@ -4127,20 +4334,19 @@ var ChatPrompt = class extends BasePrompt {
4127
4334
  break;
4128
4335
  }
4129
4336
  case "assistant": {
4130
- if (message2.function_call) {
4131
- messagesOut.push({
4132
- role: "assistant",
4133
- content: null,
4134
- function_call: message2.function_call
4135
- });
4136
- } else if (message2?.content) {
4137
- messagesOut.push({
4138
- role: "assistant",
4139
- content: message2.content
4140
- });
4141
- }
4337
+ messagesOut.push({
4338
+ role: "assistant",
4339
+ content: message2.content
4340
+ });
4142
4341
  break;
4143
4342
  }
4343
+ case "function_call":
4344
+ messagesOut.push({
4345
+ role: "function_call",
4346
+ content: null,
4347
+ function_call: message2.function_call
4348
+ });
4349
+ break;
4144
4350
  case "function":
4145
4351
  messagesOut.push({
4146
4352
  role: "function",
@@ -4364,10 +4570,17 @@ var Dialogue = class extends BaseStateItem {
4364
4570
  }
4365
4571
  setAssistantMessage(content) {
4366
4572
  if (content) {
4367
- this.value.push({
4368
- role: "assistant",
4369
- content
4370
- });
4573
+ if (isOutputResultContentText(content)) {
4574
+ this.value.push({
4575
+ role: "assistant",
4576
+ content: content.text
4577
+ });
4578
+ } else {
4579
+ this.value.push({
4580
+ role: "assistant",
4581
+ content
4582
+ });
4583
+ }
4371
4584
  }
4372
4585
  return this;
4373
4586
  }
@@ -4380,22 +4593,57 @@ var Dialogue = class extends BaseStateItem {
4380
4593
  }
4381
4594
  return this;
4382
4595
  }
4383
- setFunctionMessage(content, name) {
4596
+ setToolMessage(content, name, id) {
4597
+ this.setFunctionMessage(content, name, id);
4598
+ }
4599
+ setFunctionMessage(content, name, id) {
4384
4600
  if (content) {
4385
4601
  this.value.push({
4386
4602
  role: "function",
4603
+ id,
4387
4604
  name,
4388
4605
  content
4389
4606
  });
4390
4607
  }
4391
4608
  return this;
4392
4609
  }
4610
+ /**
4611
+ * Set
4612
+ */
4613
+ setToolCallMessage(input) {
4614
+ this.setFunctionCallMessage(input);
4615
+ }
4393
4616
  setFunctionCallMessage(input) {
4617
+ if (!input || typeof input !== "object") {
4618
+ throw new LlmExeError(`Invalid arguments`, "state", {
4619
+ error: `Invalid arguments: input must be an object`,
4620
+ module: "dialogue"
4621
+ });
4622
+ }
4623
+ if ("function_call" in input) {
4624
+ if (!input.function_call || typeof input.function_call !== "object") {
4625
+ throw new LlmExeError(`Invalid arguments`, "state", {
4626
+ error: `Invalid arguments: input must be an object`,
4627
+ module: "dialogue"
4628
+ });
4629
+ }
4630
+ this.value.push({
4631
+ role: "function_call",
4632
+ function_call: {
4633
+ id: input?.function_call.id,
4634
+ name: input?.function_call.name,
4635
+ arguments: maybeStringifyJSON(input?.function_call.arguments)
4636
+ },
4637
+ content: null
4638
+ });
4639
+ return this;
4640
+ }
4394
4641
  this.value.push({
4395
- role: "assistant",
4642
+ role: "function_call",
4396
4643
  function_call: {
4397
- name: input?.function_call.name,
4398
- arguments: maybeStringifyJSON(input?.function_call.arguments)
4644
+ id: input?.id,
4645
+ name: input?.name,
4646
+ arguments: maybeStringifyJSON(input?.arguments)
4399
4647
  },
4400
4648
  content: null
4401
4649
  });
@@ -4413,21 +4661,26 @@ var Dialogue = class extends BaseStateItem {
4413
4661
  case "user":
4414
4662
  this.setUserMessage(message?.content, message?.name);
4415
4663
  break;
4664
+ case "model":
4416
4665
  case "assistant":
4417
- if (message.function_call) {
4418
- this.setFunctionCallMessage({
4419
- function_call: message.function_call
4420
- });
4421
- } else if (message?.content) {
4422
- this.setAssistantMessage(message?.content);
4423
- }
4666
+ this.setAssistantMessage(message?.content);
4424
4667
  break;
4425
4668
  case "system":
4426
4669
  this.setSystemMessage(message?.content);
4427
4670
  break;
4671
+ case "function_call":
4672
+ this.setFunctionCallMessage({
4673
+ function_call: message.function_call
4674
+ });
4675
+ break;
4428
4676
  case "function":
4429
4677
  this.setFunctionMessage(message?.content, message.name);
4430
4678
  break;
4679
+ default:
4680
+ this.value.push({
4681
+ role: message.role,
4682
+ content: message.content || ""
4683
+ });
4431
4684
  }
4432
4685
  }
4433
4686
  return this;
@@ -4443,6 +4696,30 @@ var Dialogue = class extends BaseStateItem {
4443
4696
  };
4444
4697
  }
4445
4698
  // deserialize() {}
4699
+ /**
4700
+ * Add LLM output to dialogue history in the order it was returned
4701
+ *
4702
+ * @param output - The LLM output result from llm.call()
4703
+ * @returns this for chaining
4704
+ */
4705
+ addFromOutput(output) {
4706
+ const result = "getResult" in output ? output.getResult() : output;
4707
+ if (!result || typeof result !== "object") {
4708
+ return this;
4709
+ }
4710
+ for (const item of result.content) {
4711
+ if (item.type === "text") {
4712
+ this.setAssistantMessage(item.text);
4713
+ } else if (item.type === "function_use") {
4714
+ this.setToolCallMessage({
4715
+ name: item.name,
4716
+ arguments: maybeStringifyJSON(item.input),
4717
+ id: item.functionId
4718
+ });
4719
+ }
4720
+ }
4721
+ return this;
4722
+ }
4446
4723
  };
4447
4724
 
4448
4725
  // src/state/_base.ts
@@ -4549,6 +4826,8 @@ export {
4549
4826
  DefaultState,
4550
4827
  DefaultStateItem,
4551
4828
  LlmExecutorOpenAiFunctions,
4829
+ LlmExecutorWithFunctions,
4830
+ LlmNativeFunctionParser,
4552
4831
  OpenAiFunctionParser,
4553
4832
  TextPrompt,
4554
4833
  createCallableExecutor,
@@ -4558,11 +4837,13 @@ export {
4558
4837
  createDialogue,
4559
4838
  createEmbedding,
4560
4839
  createLlmExecutor,
4840
+ createLlmFunctionExecutor,
4561
4841
  createParser,
4562
4842
  createPrompt,
4563
4843
  createState,
4564
4844
  createStateItem,
4565
4845
  defineSchema,
4846
+ guards_exports as guards,
4566
4847
  registerHelpers,
4567
4848
  registerPartials,
4568
4849
  useExecutors,