llm-exe 2.2.1 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -64,6 +64,7 @@ __export(index_exports, {
64
64
  createState: () => createState,
65
65
  createStateItem: () => createStateItem,
66
66
  defineSchema: () => defineSchema,
67
+ guards: () => guards_exports,
67
68
  registerHelpers: () => registerHelpers,
68
69
  registerPartials: () => registerPartials,
69
70
  useExecutors: () => useExecutors,
@@ -406,12 +407,56 @@ function assert(condition, message) {
406
407
  }
407
408
  }
408
409
 
410
+ // src/utils/guards.ts
411
+ var guards_exports = {};
412
+ __export(guards_exports, {
413
+ hasFunctionCall: () => hasFunctionCall,
414
+ hasToolCall: () => hasToolCall,
415
+ isAssistantMessage: () => isAssistantMessage,
416
+ isFunctionCall: () => isFunctionCall,
417
+ isOutputResult: () => isOutputResult,
418
+ isOutputResultContentText: () => isOutputResultContentText,
419
+ isSystemMessage: () => isSystemMessage,
420
+ isToolCall: () => isToolCall,
421
+ isUserMessage: () => isUserMessage
422
+ });
423
+ function isOutputResult(obj) {
424
+ return !!(obj && typeof obj === "object" && "id" in obj && "stopReason" in obj && "content" in obj && Array.isArray(obj.content));
425
+ }
426
+ function isOutputResultContentText(obj) {
427
+ return !!(obj && typeof obj === "object" && "text" in obj && "type" in obj && obj.type === "text" && typeof obj.text === "string");
428
+ }
429
+ function isFunctionCall(result) {
430
+ return !!(result && typeof result === "object" && "functionId" in result && "type" in result && result.type === "function_use");
431
+ }
432
+ function isToolCall(result) {
433
+ return isFunctionCall(result);
434
+ }
435
+ function hasFunctionCall(results) {
436
+ return !!(results && Array.isArray(results) && results.some(isToolCall));
437
+ }
438
+ function hasToolCall(results) {
439
+ return hasFunctionCall(results);
440
+ }
441
+ function isUserMessage(message) {
442
+ return message.role === "user";
443
+ }
444
+ function isAssistantMessage(message) {
445
+ return message.role === "assistant" || message.role === "model";
446
+ }
447
+ function isSystemMessage(message) {
448
+ return message.role === "system";
449
+ }
450
+
409
451
  // src/parser/parsers/StringParser.ts
410
452
  var StringParser = class extends BaseParser {
411
453
  constructor(options) {
412
454
  super("string", options);
413
455
  }
414
456
  parse(text, _options) {
457
+ if (isOutputResult(text)) {
458
+ return text.content?.[0]?.text ?? "";
459
+ }
415
460
  assert(
416
461
  typeof text === "string",
417
462
  `Invalid input. Expected string. Received ${typeof text}.`
@@ -1721,15 +1766,26 @@ function createCustomParser(name, parserFn) {
1721
1766
  return new CustomParser(name, parserFn);
1722
1767
  }
1723
1768
 
1724
- // src/llm/output/_utils/getResultText.ts
1725
- function getResultText(content) {
1726
- if (content.length === 1 && content.every((a) => a.type === "text")) {
1727
- return content[0]?.text || "";
1728
- }
1729
- return "";
1730
- }
1731
-
1732
1769
  // src/parser/parsers/LlmNativeFunctionParser.ts
1770
+ var LlmFunctionParser = class extends BaseParser {
1771
+ constructor(options) {
1772
+ super("functionCall", options, "function_call");
1773
+ __publicField(this, "parser");
1774
+ this.parser = options.parser;
1775
+ }
1776
+ parse(text, _options) {
1777
+ if (typeof text === "string") {
1778
+ return this.parser.parse(text);
1779
+ }
1780
+ const { content } = text;
1781
+ const functionUses = content?.filter((a) => a.type === "function_use") || [];
1782
+ if (functionUses.length === 0) {
1783
+ const [item] = content;
1784
+ return this.parser.parse(item.text);
1785
+ }
1786
+ return content;
1787
+ }
1788
+ };
1733
1789
  var LlmNativeFunctionParser = class extends BaseParser {
1734
1790
  constructor(options) {
1735
1791
  super("openAiFunction", options, "function_call");
@@ -1737,14 +1793,15 @@ var LlmNativeFunctionParser = class extends BaseParser {
1737
1793
  this.parser = options.parser;
1738
1794
  }
1739
1795
  parse(text, _options) {
1740
- const functionUse = text?.find((a) => a.type === "function_use");
1796
+ const { content } = text;
1797
+ const functionUse = content?.find((a) => a.type === "function_use");
1741
1798
  if (functionUse && "name" in functionUse && "input" in functionUse) {
1742
1799
  return {
1743
1800
  name: functionUse.name,
1744
1801
  arguments: maybeParseJSON(functionUse.input)
1745
1802
  };
1746
1803
  }
1747
- return this.parser.parse(getResultText(text));
1804
+ return this.parser.parse(text?.text ?? text);
1748
1805
  }
1749
1806
  };
1750
1807
  var OpenAiFunctionParser = LlmNativeFunctionParser;
@@ -1804,7 +1861,7 @@ var LlmExecutor = class extends BaseExecutor {
1804
1861
  }
1805
1862
  getHandlerOutput(out, _metadata) {
1806
1863
  if (this.parser.target === "function_call") {
1807
- const outToStr = out.getResultContent();
1864
+ const outToStr = out.getResult();
1808
1865
  return this.parser.parse(outToStr, _metadata);
1809
1866
  } else {
1810
1867
  const outToStr = out.getResultText();
@@ -1829,7 +1886,7 @@ var LlmExecutorWithFunctions = class extends LlmExecutor {
1829
1886
  constructor(llmConfiguration, options) {
1830
1887
  super(
1831
1888
  Object.assign({}, llmConfiguration, {
1832
- parser: new LlmNativeFunctionParser({
1889
+ parser: new LlmFunctionParser({
1833
1890
  parser: llmConfiguration.parser || new StringParser()
1834
1891
  })
1835
1892
  }),
@@ -1840,7 +1897,23 @@ var LlmExecutorWithFunctions = class extends LlmExecutor {
1840
1897
  return super.execute(_input, _options);
1841
1898
  }
1842
1899
  };
1843
- var LlmExecutorOpenAiFunctions = class extends LlmExecutorWithFunctions {
1900
+ var LlmExecutorOpenAiFunctions = class extends LlmExecutor {
1901
+ constructor(llmConfiguration, options) {
1902
+ super(
1903
+ Object.assign({}, llmConfiguration, {
1904
+ parser: new LlmNativeFunctionParser({
1905
+ parser: llmConfiguration.parser || new StringParser()
1906
+ })
1907
+ }),
1908
+ options
1909
+ );
1910
+ console.warn(
1911
+ `LlmExecutorOpenAiFunctions is deprecated. Please migrate to LlmExecutorWithFunctions`
1912
+ );
1913
+ }
1914
+ async execute(_input, _options) {
1915
+ return super.execute(_input, _options);
1916
+ }
1844
1917
  };
1845
1918
 
1846
1919
  // src/executor/_functions.ts
@@ -2045,6 +2118,39 @@ function getEnvironmentVariable(name) {
2045
2118
  }
2046
2119
  }
2047
2120
 
2121
+ // src/llm/config/openai/promptSanitizeMessageCallback.ts
2122
+ function openaiPromptMessageCallback(_message) {
2123
+ let message = { ..._message };
2124
+ if (message.role === "function") {
2125
+ message.role = "tool";
2126
+ message.tool_call_id = message.id;
2127
+ delete message.id;
2128
+ }
2129
+ if (message?.function_call) {
2130
+ const { function_call } = message;
2131
+ const toolsArr = Array.isArray(function_call) ? function_call : [function_call];
2132
+ message.role = "assistant";
2133
+ message.tool_calls = toolsArr.map((call) => {
2134
+ const { id, ...functionCall } = call;
2135
+ return {
2136
+ id,
2137
+ type: "function",
2138
+ function: functionCall
2139
+ };
2140
+ });
2141
+ delete message.function_call;
2142
+ }
2143
+ return message;
2144
+ }
2145
+
2146
+ // src/llm/config/openai/promptSanitize.ts
2147
+ function openaiPromptSanitize(_messages, _inputBodyObj, _outputObj) {
2148
+ if (typeof _messages === "string") {
2149
+ return [{ role: "user", content: _messages }];
2150
+ }
2151
+ return _messages.map(openaiPromptMessageCallback);
2152
+ }
2153
+
2048
2154
  // src/llm/config/openai/index.ts
2049
2155
  var openAiChatV1 = {
2050
2156
  key: "openai.chat.v1",
@@ -2063,12 +2169,7 @@ var openAiChatV1 = {
2063
2169
  mapBody: {
2064
2170
  prompt: {
2065
2171
  key: "messages",
2066
- sanitize: (v) => {
2067
- if (typeof v === "string") {
2068
- return [{ role: "user", content: v }];
2069
- }
2070
- return v;
2071
- }
2172
+ sanitize: openaiPromptSanitize
2072
2173
  },
2073
2174
  model: {
2074
2175
  key: "model"
@@ -2119,14 +2220,54 @@ var openai = {
2119
2220
  "openai.gpt-4o-mini": withDefaultModel(openAiChatV1, "gpt-4o-mini")
2120
2221
  };
2121
2222
 
2223
+ // src/llm/config/anthropic/promptSanitizeMessageCallback.ts
2224
+ function anthropicPromptMessageCallback(_message) {
2225
+ let message = { ..._message };
2226
+ if (message.role === "function") {
2227
+ message.role = "user";
2228
+ message.content = [
2229
+ {
2230
+ type: "tool_result",
2231
+ tool_use_id: message.id,
2232
+ content: maybeStringifyJSON(message.content)
2233
+ }
2234
+ ];
2235
+ delete message.name;
2236
+ delete message.id;
2237
+ }
2238
+ if (message?.function_call) {
2239
+ const { function_call } = message;
2240
+ const toolsArr = Array.isArray(function_call) ? function_call : [function_call];
2241
+ message.role = "assistant";
2242
+ message.content = toolsArr.map((call) => {
2243
+ const { id, name, arguments: input } = call;
2244
+ return {
2245
+ type: "tool_use",
2246
+ id,
2247
+ name,
2248
+ input: maybeParseJSON(input)
2249
+ };
2250
+ });
2251
+ delete message.function_call;
2252
+ }
2253
+ return message;
2254
+ }
2255
+
2122
2256
  // src/llm/config/anthropic/promptSanitize.ts
2123
2257
  function anthropicPromptSanitize(_messages, _inputBodyObj, _outputObj) {
2124
2258
  if (typeof _messages === "string") {
2125
- return [{ role: "user", content: _messages }];
2259
+ return [{ role: "user", content: _messages }].map(
2260
+ anthropicPromptMessageCallback
2261
+ );
2126
2262
  }
2127
- const [first, ...messages] = [..._messages.map((a) => ({ ...a }))];
2263
+ const [first, ...messages] = [
2264
+ ..._messages.map((a) => ({ ...a }))
2265
+ ];
2128
2266
  if (first.role === "system" && messages.length === 0) {
2129
- return [{ role: "user", content: first.content }, ...messages];
2267
+ return [
2268
+ { role: "user", content: first.content },
2269
+ ...messages
2270
+ ].map(anthropicPromptMessageCallback);
2130
2271
  }
2131
2272
  if (first.role === "system" && messages.length > 0) {
2132
2273
  _outputObj.system = first.content;
@@ -2135,7 +2276,7 @@ function anthropicPromptSanitize(_messages, _inputBodyObj, _outputObj) {
2135
2276
  return { ...m, role: "user" };
2136
2277
  }
2137
2278
  return m;
2138
- });
2279
+ }).map(anthropicPromptMessageCallback);
2139
2280
  }
2140
2281
  return [
2141
2282
  first,
@@ -2145,7 +2286,7 @@ function anthropicPromptSanitize(_messages, _inputBodyObj, _outputObj) {
2145
2286
  }
2146
2287
  return m;
2147
2288
  })
2148
- ];
2289
+ ].map(anthropicPromptMessageCallback);
2149
2290
  }
2150
2291
 
2151
2292
  // src/llm/config/bedrock/index.ts
@@ -2270,6 +2411,14 @@ var anthropicChatV1 = {
2270
2411
  };
2271
2412
  var anthropic = {
2272
2413
  "anthropic.chat.v1": anthropicChatV1,
2414
+ "anthropic.claude-sonnet-4-0": withDefaultModel(
2415
+ anthropicChatV1,
2416
+ "claude-sonnet-4-0"
2417
+ ),
2418
+ "anthropic.claude-opus-4-0": withDefaultModel(
2419
+ anthropicChatV1,
2420
+ "claude-sonnet-4-0"
2421
+ ),
2273
2422
  "anthropic.claude-3-7-sonnet": withDefaultModel(
2274
2423
  anthropicChatV1,
2275
2424
  "claude-3-7-sonnet-latest"
@@ -2282,6 +2431,7 @@ var anthropic = {
2282
2431
  anthropicChatV1,
2283
2432
  "claude-3-5-haiku-latest"
2284
2433
  ),
2434
+ // Deprecated
2285
2435
  "anthropic.claude-3-opus": withDefaultModel(
2286
2436
  anthropicChatV1,
2287
2437
  "claude-3-opus-latest"
@@ -2306,12 +2456,7 @@ var xaiChatV1 = {
2306
2456
  mapBody: {
2307
2457
  prompt: {
2308
2458
  key: "messages",
2309
- sanitize: (v) => {
2310
- if (typeof v === "string") {
2311
- return [{ role: "user", content: v }];
2312
- }
2313
- return v;
2314
- }
2459
+ sanitize: openaiPromptSanitize
2315
2460
  },
2316
2461
  model: {
2317
2462
  key: "model"
@@ -2327,7 +2472,9 @@ var xaiChatV1 = {
2327
2472
  };
2328
2473
  var xai = {
2329
2474
  "xai.chat.v1": xaiChatV1,
2330
- "xai.grok-2": withDefaultModel(xaiChatV1, "grok-2-latest")
2475
+ "xai.grok-2": withDefaultModel(xaiChatV1, "grok-2-latest"),
2476
+ "xai.grok-3": withDefaultModel(xaiChatV1, "grok-3"),
2477
+ "xai.grok-4": withDefaultModel(xaiChatV1, "grok-4")
2331
2478
  };
2332
2479
 
2333
2480
  // src/llm/config/ollama/index.ts
@@ -2364,30 +2511,49 @@ var ollama = {
2364
2511
  "ollama.qwq": withDefaultModel(ollamaChatV1, "qwq")
2365
2512
  };
2366
2513
 
2367
- // src/utils/modules/modifyPromptRoleChange.ts
2368
- function modifyPromptRoleChange(messages, roleChanges) {
2369
- const roleChangeMap = new Map(roleChanges.map(({ from, to }) => [from, to]));
2370
- if (Array.isArray(messages)) {
2371
- return messages.map((message) => {
2372
- const newRole2 = roleChangeMap.get(message.role);
2373
- return newRole2 ? { ...message, role: newRole2 } : message;
2374
- });
2375
- }
2376
- const newRole = roleChangeMap.get(messages.role);
2377
- return newRole ? { ...messages, role: newRole } : messages;
2378
- }
2379
-
2380
2514
  // src/llm/config/google/promptSanitizeMessageCallback.ts
2381
2515
  function googleGeminiPromptMessageCallback(_message) {
2382
2516
  let message = { ..._message };
2383
- message = modifyPromptRoleChange(_message, [
2384
- { from: "assistant", to: "model" }
2385
- ]);
2386
- const { role, ...payload } = message;
2387
2517
  const parts = [];
2518
+ if (message.role === "assistant") {
2519
+ message.role = "model";
2520
+ }
2521
+ if (message.role === "system") {
2522
+ message.role = "model";
2523
+ }
2524
+ let { role, ...payload } = message;
2388
2525
  if (typeof payload.content === "string") {
2389
2526
  parts.push({ text: message.content });
2390
2527
  }
2528
+ if (message.role === "function") {
2529
+ role = "user";
2530
+ parts.push({
2531
+ functionResponse: {
2532
+ name: message.name,
2533
+ response: {
2534
+ result: message.content
2535
+ }
2536
+ }
2537
+ });
2538
+ delete message.id;
2539
+ }
2540
+ if (message?.function_call) {
2541
+ const { function_call } = message;
2542
+ const toolsArr = Array.isArray(function_call) ? function_call : [function_call];
2543
+ role = "model";
2544
+ parts.push(
2545
+ ...toolsArr.map((call) => {
2546
+ const { name, arguments: input } = call;
2547
+ return {
2548
+ functionCall: {
2549
+ name,
2550
+ args: maybeParseJSON(input)
2551
+ }
2552
+ };
2553
+ })
2554
+ );
2555
+ delete message.function_call;
2556
+ }
2391
2557
  return {
2392
2558
  role,
2393
2559
  parts
@@ -2417,7 +2583,9 @@ function googleGeminiPromptSanitize(_messages, _inputBodyObj, _outputObj) {
2417
2583
  (message) => message.role !== "system"
2418
2584
  );
2419
2585
  _outputObj.system_instruction = {
2420
- parts: theSystemInstructions.map((message) => ({ text: message.content }))
2586
+ parts: theSystemInstructions.map((message) => ({
2587
+ text: message.content
2588
+ }))
2421
2589
  };
2422
2590
  return withoutSystemInstructions.map(googleGeminiPromptMessageCallback);
2423
2591
  }
@@ -2460,9 +2628,21 @@ var google = {
2460
2628
  googleGeminiChatV1,
2461
2629
  "gemini-2.0-flash-lite"
2462
2630
  ),
2631
+ "google.gemini-2.5-flash": withDefaultModel(
2632
+ googleGeminiChatV1,
2633
+ "gemini-2.5-flash"
2634
+ ),
2635
+ "google.gemini-2.5-flash-lite": withDefaultModel(
2636
+ googleGeminiChatV1,
2637
+ "gemini-2.5-flash-lite"
2638
+ ),
2463
2639
  "google.gemini-1.5-pro": withDefaultModel(
2464
2640
  googleGeminiChatV1,
2465
2641
  "gemini-1.5-pro"
2642
+ ),
2643
+ "google.gemini-2.5-pro": withDefaultModel(
2644
+ googleGeminiChatV1,
2645
+ "gemini-2.5-pro"
2466
2646
  )
2467
2647
  };
2468
2648
 
@@ -2484,12 +2664,7 @@ var deepseekChatV1 = {
2484
2664
  mapBody: {
2485
2665
  prompt: {
2486
2666
  key: "messages",
2487
- sanitize: (v) => {
2488
- if (typeof v === "string") {
2489
- return [{ role: "user", content: v }];
2490
- }
2491
- return v;
2492
- }
2667
+ sanitize: openaiPromptSanitize
2493
2668
  },
2494
2669
  model: {
2495
2670
  key: "model"
@@ -2538,7 +2713,7 @@ function getLlmConfig(provider) {
2538
2713
 
2539
2714
  // src/llm/output/_utils/getResultContent.ts
2540
2715
  function getResultContent(result, index) {
2541
- if (index && index > 0) {
2716
+ if (typeof index === "number" && index > 0) {
2542
2717
  const arr = result?.options || [];
2543
2718
  const val = arr[index];
2544
2719
  return val ? val : [];
@@ -2546,6 +2721,16 @@ function getResultContent(result, index) {
2546
2721
  return [...result.content];
2547
2722
  }
2548
2723
 
2724
+ // src/llm/output/_utils/getResultText.ts
2725
+ function getResultText(result, index) {
2726
+ if (typeof index === "number" && index > 0) {
2727
+ const arr = result?.options || [];
2728
+ const val = arr[index];
2729
+ return isOutputResultContentText(val?.[0]) ? val[0]?.text : "";
2730
+ }
2731
+ return isOutputResultContentText(result?.content?.[0]) ? result.content[0]?.text : "";
2732
+ }
2733
+
2549
2734
  // src/llm/output/base.ts
2550
2735
  function BaseLlmOutput2(result) {
2551
2736
  const __result = Object.freeze({
@@ -2570,7 +2755,7 @@ function BaseLlmOutput2(result) {
2570
2755
  }
2571
2756
  return {
2572
2757
  getResultContent: (index) => getResultContent(__result, index),
2573
- getResultText: () => getResultText(__result.content),
2758
+ getResultText: (index) => getResultText(__result, index),
2574
2759
  getResult
2575
2760
  };
2576
2761
  }
@@ -2594,36 +2779,27 @@ function formatOptions(response, handler) {
2594
2779
  }
2595
2780
  return out;
2596
2781
  }
2597
- function formatContent(response, handler) {
2598
- const out = [];
2599
- const result = handler(response);
2600
- if (result) {
2601
- out.push(result);
2602
- }
2603
- return out;
2604
- }
2605
2782
 
2606
2783
  // src/llm/output/openai.ts
2607
2784
  function formatResult(result) {
2785
+ const out = [];
2608
2786
  if (typeof result?.message?.content === "string") {
2609
- return {
2787
+ out.push({
2610
2788
  type: "text",
2611
2789
  text: result.message.content
2612
- };
2613
- } else if (result?.message && "tool_calls" in result.message) {
2614
- const tool_calls = result.message.tool_calls;
2615
- for (const call of tool_calls) {
2616
- return {
2790
+ });
2791
+ }
2792
+ if (result?.message?.tool_calls) {
2793
+ for (const call of result.message.tool_calls) {
2794
+ out.push({
2795
+ functionId: call.id,
2617
2796
  type: "function_use",
2618
2797
  name: call.function.name,
2619
- input: JSON.parse(call.function.arguments)
2620
- };
2798
+ input: maybeParseJSON(call.function.arguments)
2799
+ });
2621
2800
  }
2622
2801
  }
2623
- return {
2624
- type: "text",
2625
- text: ""
2626
- };
2802
+ return out;
2627
2803
  }
2628
2804
  function OutputOpenAIChat(result, _config) {
2629
2805
  const id = result.id;
@@ -2631,7 +2807,7 @@ function OutputOpenAIChat(result, _config) {
2631
2807
  const created = result.created;
2632
2808
  const [_content, ..._options] = result?.choices || [];
2633
2809
  const stopReason = _content?.finish_reason;
2634
- const content = formatContent(_content, formatResult);
2810
+ const content = formatResult(_content);
2635
2811
  const options = formatOptions(_options, formatResult);
2636
2812
  const usage = {
2637
2813
  output_tokens: result?.usage?.completion_tokens,
@@ -2662,6 +2838,7 @@ function formatResult2(response) {
2662
2838
  });
2663
2839
  } else if (result.type === "tool_use") {
2664
2840
  out.push({
2841
+ functionId: result.id,
2665
2842
  type: "function_use",
2666
2843
  name: result.name,
2667
2844
  input: result.input
@@ -2732,33 +2909,32 @@ function OutputDefault(result, _config) {
2732
2909
 
2733
2910
  // src/llm/output/xai.ts
2734
2911
  function formatResult3(result) {
2912
+ const out = [];
2735
2913
  if (typeof result?.message?.content === "string") {
2736
- return {
2914
+ out.push({
2737
2915
  type: "text",
2738
2916
  text: result.message.content
2739
- };
2740
- } else if (result?.message && "tool_calls" in result.message) {
2741
- const tool_calls = result.message.tool_calls;
2742
- for (const call of tool_calls) {
2743
- return {
2917
+ });
2918
+ }
2919
+ if (result?.message?.tool_calls) {
2920
+ for (const call of result.message.tool_calls) {
2921
+ out.push({
2922
+ functionId: call.id,
2744
2923
  type: "function_use",
2745
2924
  name: call.function.name,
2746
- input: JSON.parse(call.function.arguments)
2747
- };
2925
+ input: maybeParseJSON(call.function.arguments)
2926
+ });
2748
2927
  }
2749
2928
  }
2750
- return {
2751
- type: "text",
2752
- text: ""
2753
- };
2929
+ return out;
2754
2930
  }
2755
2931
  function OutputXAIChat(result, _config) {
2756
2932
  const id = result.id;
2757
- const name = result?.model;
2933
+ const name = result.model || _config?.model || "openai.unknown";
2758
2934
  const created = result.created;
2759
2935
  const [_content, ..._options] = result?.choices || [];
2760
2936
  const stopReason = _content?.finish_reason;
2761
- const content = formatContent(_content, formatResult3);
2937
+ const content = formatResult3(_content);
2762
2938
  const options = formatOptions(_options, formatResult3);
2763
2939
  const usage = {
2764
2940
  output_tokens: result?.usage?.completion_tokens,
@@ -2849,37 +3025,36 @@ function OutputOllamaChat(result, _config) {
2849
3025
  }
2850
3026
 
2851
3027
  // src/llm/output/google.gemini/formatResult.ts
2852
- function formatResult4(result) {
3028
+ function formatResult4(result, id) {
2853
3029
  const { parts = [] } = result?.content || {};
2854
- if (parts.length === 1) {
2855
- const answer = parts[0];
2856
- if (!!answer?.functionCall && typeof answer?.functionCall === "object") {
2857
- return {
2858
- type: "function_use",
2859
- name: answer.functionCall.name,
2860
- input: JSON.parse(answer.functionCall.args)
2861
- };
2862
- } else {
2863
- return {
3030
+ const out = [];
3031
+ for (let i = 0; i < parts.length; i++) {
3032
+ const part = parts[i];
3033
+ if (typeof part.text === "string") {
3034
+ out.push({
2864
3035
  type: "text",
2865
- text: answer.text || ""
2866
- };
3036
+ text: part.text
3037
+ });
3038
+ } else if (part?.functionCall) {
3039
+ out.push({
3040
+ functionId: `${id || (0, import_uuid.v4)()}-${i}`,
3041
+ type: "function_use",
3042
+ name: part.functionCall.name,
3043
+ input: maybeParseJSON(part.functionCall.args)
3044
+ });
2867
3045
  }
2868
3046
  }
2869
- return {
2870
- type: "text",
2871
- text: ""
2872
- };
3047
+ return out;
2873
3048
  }
2874
3049
 
2875
3050
  // src/llm/output/google.gemini/index.ts
2876
3051
  function OutputGoogleGeminiChat(result, _config) {
2877
- const id = "result.id";
2878
- const name = result.modelVersion;
3052
+ const id = result.responseId;
3053
+ const name = result.modelVersion || _config?.model || "gemini";
2879
3054
  const created = (/* @__PURE__ */ new Date()).getTime();
2880
3055
  const [_content, ..._options] = result?.candidates || [];
2881
3056
  const stopReason = _content?.finishReason?.toLowerCase();
2882
- const content = formatContent(_content, formatResult4);
3057
+ const content = formatResult4(_content, id);
2883
3058
  const options = formatOptions(_options, formatResult4);
2884
3059
  const usage = {
2885
3060
  output_tokens: result?.usageMetadata?.candidatesTokenCount,
@@ -2897,8 +3072,53 @@ function OutputGoogleGeminiChat(result, _config) {
2897
3072
  });
2898
3073
  }
2899
3074
 
3075
+ // src/llm/output/deepseek.ts
3076
+ function formatResult5(result) {
3077
+ const out = [];
3078
+ if (typeof result?.message?.content === "string" && result?.message?.content) {
3079
+ out.push({
3080
+ type: "text",
3081
+ text: result.message.content
3082
+ });
3083
+ }
3084
+ if (result?.message?.tool_calls) {
3085
+ for (const call of result.message.tool_calls) {
3086
+ out.push({
3087
+ functionId: call.id,
3088
+ type: "function_use",
3089
+ name: call.function.name,
3090
+ input: maybeParseJSON(call.function.arguments)
3091
+ });
3092
+ }
3093
+ }
3094
+ return out;
3095
+ }
3096
+ function OutputDeepSeekChat(result, _config) {
3097
+ const id = result.id;
3098
+ const name = result.model || _config?.model || "deepseek.unknown";
3099
+ const created = result.created;
3100
+ const [_content, ..._options] = result?.choices || [];
3101
+ const stopReason = _content?.finish_reason;
3102
+ const content = formatResult5(_content);
3103
+ const options = formatOptions(_options, formatResult5);
3104
+ const usage = {
3105
+ output_tokens: result?.usage?.completion_tokens,
3106
+ input_tokens: result?.usage?.prompt_tokens,
3107
+ total_tokens: result?.usage?.total_tokens
3108
+ };
3109
+ return BaseLlmOutput2({
3110
+ id,
3111
+ name,
3112
+ created,
3113
+ usage,
3114
+ stopReason,
3115
+ content,
3116
+ options
3117
+ });
3118
+ }
3119
+
2900
3120
  // src/llm/output/index.ts
2901
- function getOutputParser(config, response) {
3121
+ function normalizeLlmOutputToInternalFormat(config, response) {
2902
3122
  switch (config?.key) {
2903
3123
  case "openai.chat.v1":
2904
3124
  case "openai.chat-mock.v1":
@@ -2917,7 +3137,7 @@ function getOutputParser(config, response) {
2917
3137
  case "google.chat.v1":
2918
3138
  return OutputGoogleGeminiChat(response, config);
2919
3139
  case "deepseek.chat.v1":
2920
- return OutputOpenAIChat(response, config);
3140
+ return OutputDeepSeekChat(response, config);
2921
3141
  // use oai for now
2922
3142
  default: {
2923
3143
  if (config?.key?.startsWith("custom:")) {
@@ -3147,9 +3367,9 @@ async function parseHeaders(config, replacements, payload) {
3147
3367
  // src/llm/output/_utils/cleanJsonSchemaFor.ts
3148
3368
  var providerFieldExclusions = {
3149
3369
  "openai.chat": ["default"],
3150
- // fields to exclude for openai.chat
3151
- "anthropic.chat": []
3152
- // fields to exclude for openai.chat
3370
+ // fields to exclude for openai.chat, xai, deepseek
3371
+ "anthropic.chat": [],
3372
+ "google.chat": ["additionalProperties"]
3153
3373
  };
3154
3374
  function cleanJsonSchemaFor(schema = {}, provider) {
3155
3375
  const clone = deepClone(schema);
@@ -3188,7 +3408,7 @@ async function useLlm_call(state, messages, _options) {
3188
3408
  })
3189
3409
  );
3190
3410
  if (_options && _options?.jsonSchema) {
3191
- if (state.provider.startsWith("openai")) {
3411
+ if (state.provider.startsWith("openai") || state.provider.startsWith("deepseek") || state.provider.startsWith("xai")) {
3192
3412
  const curr = input["response_format"] || {};
3193
3413
  input["response_format"] = Object.assign(curr, {
3194
3414
  type: "json_schema",
@@ -3209,11 +3429,17 @@ async function useLlm_call(state, messages, _options) {
3209
3429
  } else {
3210
3430
  input["tool_choice"] = _options?.functionCall;
3211
3431
  }
3212
- } else if (state.provider.startsWith("openai")) {
3432
+ } else if (state.provider.startsWith("openai") || state.provider.startsWith("deepseek") || state.provider.startsWith("xai")) {
3213
3433
  input["tool_choice"] = normalizeFunctionCall(
3214
3434
  _options?.functionCall,
3215
3435
  "openai"
3216
3436
  );
3437
+ } else if (state.provider.startsWith("google")) {
3438
+ input["toolConfig"] = {
3439
+ functionCallingConfig: {
3440
+ mode: normalizeFunctionCall(_options?.functionCall, "google")
3441
+ }
3442
+ };
3217
3443
  }
3218
3444
  }
3219
3445
  if (_options && _options?.functions?.length) {
@@ -3223,7 +3449,7 @@ async function useLlm_call(state, messages, _options) {
3223
3449
  description: f.description,
3224
3450
  input_schema: cleanJsonSchemaFor(f.parameters, "anthropic.chat")
3225
3451
  }));
3226
- } else if (state.provider.startsWith("openai")) {
3452
+ } else if (state.provider.startsWith("openai") || state.provider.startsWith("deepseek") || state.provider.startsWith("xai")) {
3227
3453
  input["tools"] = _options.functions.map((f) => {
3228
3454
  const props = {
3229
3455
  name: f?.name,
@@ -3241,6 +3467,16 @@ async function useLlm_call(state, messages, _options) {
3241
3467
  )
3242
3468
  };
3243
3469
  });
3470
+ } else if (state.provider.startsWith("google")) {
3471
+ input["tools"] = [
3472
+ {
3473
+ functionDeclarations: _options.functions.map((f) => ({
3474
+ name: f.name,
3475
+ description: f.description,
3476
+ parameters: cleanJsonSchemaFor(f.parameters, "google.chat")
3477
+ }))
3478
+ }
3479
+ ];
3244
3480
  }
3245
3481
  }
3246
3482
  const body = JSON.stringify(input);
@@ -3270,7 +3506,7 @@ async function useLlm_call(state, messages, _options) {
3270
3506
  body,
3271
3507
  headers
3272
3508
  });
3273
- return getOutputParser(state, response);
3509
+ return normalizeLlmOutputToInternalFormat(state, response);
3274
3510
  }
3275
3511
 
3276
3512
  // src/llm/_utils.stateFromOptions.ts
@@ -3842,7 +4078,7 @@ var ChatPrompt = class extends BasePrompt {
3842
4078
  this.parseUserTemplates = options?.allowUnsafeUserTemplate;
3843
4079
  }
3844
4080
  }
3845
- addToPrompt(content, role, name) {
4081
+ addToPrompt(content, role, name, id) {
3846
4082
  if (content) {
3847
4083
  switch (role) {
3848
4084
  case "system":
@@ -3856,11 +4092,11 @@ var ChatPrompt = class extends BasePrompt {
3856
4092
  break;
3857
4093
  case "function":
3858
4094
  assert(name, "Function message requires name");
3859
- this.addFunctionMessage(content, name);
4095
+ this.addFunctionMessage(content, name, id);
3860
4096
  break;
3861
4097
  case "function_call":
3862
4098
  assert(name, "Function message requires name");
3863
- this.addFunctionCallMessage({ name, arguments: content });
4099
+ this.addFunctionCallMessage({ name, arguments: content, id });
3864
4100
  break;
3865
4101
  }
3866
4102
  }
@@ -3900,11 +4136,12 @@ var ChatPrompt = class extends BasePrompt {
3900
4136
  * @param content The message content.
3901
4137
  * @return ChatPrompt so it can be chained.
3902
4138
  */
3903
- addFunctionMessage(content, name) {
4139
+ addFunctionMessage(content, name, id) {
3904
4140
  this.messages.push({
3905
4141
  role: "function",
3906
4142
  name,
3907
- content
4143
+ content,
4144
+ id
3908
4145
  });
3909
4146
  return this;
3910
4147
  }
@@ -3916,8 +4153,9 @@ var ChatPrompt = class extends BasePrompt {
3916
4153
  addFunctionCallMessage(function_call) {
3917
4154
  if (function_call) {
3918
4155
  this.messages.push({
3919
- role: "assistant",
4156
+ role: "function_call",
3920
4157
  function_call: {
4158
+ id: function_call.id,
3921
4159
  name: function_call.name,
3922
4160
  arguments: maybeStringifyJSON(function_call.arguments)
3923
4161
  },
@@ -3939,17 +4177,16 @@ var ChatPrompt = class extends BasePrompt {
3939
4177
  this.addUserMessage(message.content, message?.name);
3940
4178
  break;
3941
4179
  case "assistant":
3942
- if (message.function_call) {
3943
- this.addFunctionCallMessage(message.function_call);
3944
- } else if (message?.content) {
3945
- this.addAssistantMessage(message?.content);
3946
- }
4180
+ this.addAssistantMessage(message?.content);
3947
4181
  break;
3948
4182
  case "system":
3949
4183
  this.addSystemMessage(message.content);
3950
4184
  break;
4185
+ case "function_call":
4186
+ this.addFunctionCallMessage(message.function_call);
4187
+ break;
3951
4188
  case "function":
3952
- this.addFunctionMessage(message.content, message.name);
4189
+ this.addFunctionMessage(message.content, message.name, message.id);
3953
4190
  break;
3954
4191
  }
3955
4192
  }
@@ -4013,20 +4250,19 @@ var ChatPrompt = class extends BasePrompt {
4013
4250
  break;
4014
4251
  }
4015
4252
  case "assistant": {
4016
- if (message.function_call) {
4017
- messagesOut.push({
4018
- role: "assistant",
4019
- content: null,
4020
- function_call: message.function_call
4021
- });
4022
- } else if (message?.content) {
4023
- messagesOut.push({
4024
- role: "assistant",
4025
- content: message.content
4026
- });
4027
- }
4253
+ messagesOut.push({
4254
+ role: "assistant",
4255
+ content: message.content
4256
+ });
4028
4257
  break;
4029
4258
  }
4259
+ case "function_call":
4260
+ messagesOut.push({
4261
+ role: "function_call",
4262
+ content: null,
4263
+ function_call: message.function_call
4264
+ });
4265
+ break;
4030
4266
  case "function":
4031
4267
  messagesOut.push({
4032
4268
  role: "function",
@@ -4205,20 +4441,19 @@ var ChatPrompt = class extends BasePrompt {
4205
4441
  break;
4206
4442
  }
4207
4443
  case "assistant": {
4208
- if (message2.function_call) {
4209
- messagesOut.push({
4210
- role: "assistant",
4211
- content: null,
4212
- function_call: message2.function_call
4213
- });
4214
- } else if (message2?.content) {
4215
- messagesOut.push({
4216
- role: "assistant",
4217
- content: message2.content
4218
- });
4219
- }
4444
+ messagesOut.push({
4445
+ role: "assistant",
4446
+ content: message2.content
4447
+ });
4220
4448
  break;
4221
4449
  }
4450
+ case "function_call":
4451
+ messagesOut.push({
4452
+ role: "function_call",
4453
+ content: null,
4454
+ function_call: message2.function_call
4455
+ });
4456
+ break;
4222
4457
  case "function":
4223
4458
  messagesOut.push({
4224
4459
  role: "function",
@@ -4442,10 +4677,17 @@ var Dialogue = class extends BaseStateItem {
4442
4677
  }
4443
4678
  setAssistantMessage(content) {
4444
4679
  if (content) {
4445
- this.value.push({
4446
- role: "assistant",
4447
- content
4448
- });
4680
+ if (isOutputResultContentText(content)) {
4681
+ this.value.push({
4682
+ role: "assistant",
4683
+ content: content.text
4684
+ });
4685
+ } else {
4686
+ this.value.push({
4687
+ role: "assistant",
4688
+ content
4689
+ });
4690
+ }
4449
4691
  }
4450
4692
  return this;
4451
4693
  }
@@ -4458,28 +4700,57 @@ var Dialogue = class extends BaseStateItem {
4458
4700
  }
4459
4701
  return this;
4460
4702
  }
4461
- setFunctionMessage(content, name) {
4703
+ setToolMessage(content, name, id) {
4704
+ this.setFunctionMessage(content, name, id);
4705
+ }
4706
+ setFunctionMessage(content, name, id) {
4462
4707
  if (content) {
4463
4708
  this.value.push({
4464
4709
  role: "function",
4710
+ id,
4465
4711
  name,
4466
4712
  content
4467
4713
  });
4468
4714
  }
4469
4715
  return this;
4470
4716
  }
4717
+ /**
4718
+ * Set
4719
+ */
4720
+ setToolCallMessage(input) {
4721
+ this.setFunctionCallMessage(input);
4722
+ }
4471
4723
  setFunctionCallMessage(input) {
4472
- if (!input?.function_call) {
4724
+ if (!input || typeof input !== "object") {
4473
4725
  throw new LlmExeError(`Invalid arguments`, "state", {
4474
- error: `Invalid arguments: missing required function_call`,
4726
+ error: `Invalid arguments: input must be an object`,
4475
4727
  module: "dialogue"
4476
4728
  });
4477
4729
  }
4730
+ if ("function_call" in input) {
4731
+ if (!input.function_call || typeof input.function_call !== "object") {
4732
+ throw new LlmExeError(`Invalid arguments`, "state", {
4733
+ error: `Invalid arguments: input must be an object`,
4734
+ module: "dialogue"
4735
+ });
4736
+ }
4737
+ this.value.push({
4738
+ role: "function_call",
4739
+ function_call: {
4740
+ id: input?.function_call.id,
4741
+ name: input?.function_call.name,
4742
+ arguments: maybeStringifyJSON(input?.function_call.arguments)
4743
+ },
4744
+ content: null
4745
+ });
4746
+ return this;
4747
+ }
4478
4748
  this.value.push({
4479
- role: "assistant",
4749
+ role: "function_call",
4480
4750
  function_call: {
4481
- name: input?.function_call.name,
4482
- arguments: maybeStringifyJSON(input?.function_call.arguments)
4751
+ id: input?.id,
4752
+ name: input?.name,
4753
+ arguments: maybeStringifyJSON(input?.arguments)
4483
4754
  },
4484
4755
  content: null
4485
4756
  });
@@ -4497,21 +4768,26 @@ var Dialogue = class extends BaseStateItem {
4497
4768
  case "user":
4498
4769
  this.setUserMessage(message?.content, message?.name);
4499
4770
  break;
4771
+ case "model":
4500
4772
  case "assistant":
4501
- if (message.function_call) {
4502
- this.setFunctionCallMessage({
4503
- function_call: message.function_call
4504
- });
4505
- } else if (message?.content) {
4506
- this.setAssistantMessage(message?.content);
4507
- }
4773
+ this.setAssistantMessage(message?.content);
4508
4774
  break;
4509
4775
  case "system":
4510
4776
  this.setSystemMessage(message?.content);
4511
4777
  break;
4778
+ case "function_call":
4779
+ this.setFunctionCallMessage({
4780
+ function_call: message.function_call
4781
+ });
4782
+ break;
4512
4783
  case "function":
4513
4784
  this.setFunctionMessage(message?.content, message.name);
4514
4785
  break;
4786
+ default:
4787
+ this.value.push({
4788
+ role: message.role,
4789
+ content: message.content || ""
4790
+ });
4515
4791
  }
4516
4792
  }
4517
4793
  return this;
@@ -4527,6 +4803,30 @@ var Dialogue = class extends BaseStateItem {
4527
4803
  };
4528
4804
  }
4529
4805
  // deserialize() {}
4806
+ /**
4807
+ * Add LLM output to dialogue history in the order it was returned
4808
+ *
4809
+ * @param output - The LLM output result from llm.call()
4810
+ * @returns this for chaining
4811
+ */
4812
+ addFromOutput(output) {
4813
+ const result = "getResult" in output ? output.getResult() : output;
4814
+ if (!result || typeof result !== "object") {
4815
+ return this;
4816
+ }
4817
+ for (const item of result.content) {
4818
+ if (item.type === "text") {
4819
+ this.setAssistantMessage(item.text);
4820
+ } else if (item.type === "function_use") {
4821
+ this.setToolCallMessage({
4822
+ name: item.name,
4823
+ arguments: maybeStringifyJSON(item.input),
4824
+ id: item.functionId
4825
+ });
4826
+ }
4827
+ }
4828
+ return this;
4829
+ }
4530
4830
  };
4531
4831
 
4532
4832
  // src/state/_base.ts
@@ -4651,6 +4951,7 @@ function createStateItem(name, defaultValue) {
4651
4951
  createState,
4652
4952
  createStateItem,
4653
4953
  defineSchema,
4954
+ guards,
4654
4955
  registerHelpers,
4655
4956
  registerPartials,
4656
4957
  useExecutors,