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.mjs CHANGED
@@ -346,12 +346,56 @@ function assert(condition, message) {
346
346
  }
347
347
  }
348
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
+
349
390
  // src/parser/parsers/StringParser.ts
350
391
  var StringParser = class extends BaseParser {
351
392
  constructor(options) {
352
393
  super("string", options);
353
394
  }
354
395
  parse(text, _options) {
396
+ if (isOutputResult(text)) {
397
+ return text.content?.[0]?.text ?? "";
398
+ }
355
399
  assert(
356
400
  typeof text === "string",
357
401
  `Invalid input. Expected string. Received ${typeof text}.`
@@ -1661,15 +1705,26 @@ function createCustomParser(name, parserFn) {
1661
1705
  return new CustomParser(name, parserFn);
1662
1706
  }
1663
1707
 
1664
- // src/llm/output/_utils/getResultText.ts
1665
- function getResultText(content) {
1666
- if (content.length === 1 && content.every((a) => a.type === "text")) {
1667
- return content[0]?.text || "";
1668
- }
1669
- return "";
1670
- }
1671
-
1672
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
+ };
1673
1728
  var LlmNativeFunctionParser = class extends BaseParser {
1674
1729
  constructor(options) {
1675
1730
  super("openAiFunction", options, "function_call");
@@ -1677,14 +1732,15 @@ var LlmNativeFunctionParser = class extends BaseParser {
1677
1732
  this.parser = options.parser;
1678
1733
  }
1679
1734
  parse(text, _options) {
1680
- const functionUse = text?.find((a) => a.type === "function_use");
1735
+ const { content } = text;
1736
+ const functionUse = content?.find((a) => a.type === "function_use");
1681
1737
  if (functionUse && "name" in functionUse && "input" in functionUse) {
1682
1738
  return {
1683
1739
  name: functionUse.name,
1684
1740
  arguments: maybeParseJSON(functionUse.input)
1685
1741
  };
1686
1742
  }
1687
- return this.parser.parse(getResultText(text));
1743
+ return this.parser.parse(text?.text ?? text);
1688
1744
  }
1689
1745
  };
1690
1746
  var OpenAiFunctionParser = LlmNativeFunctionParser;
@@ -1744,7 +1800,7 @@ var LlmExecutor = class extends BaseExecutor {
1744
1800
  }
1745
1801
  getHandlerOutput(out, _metadata) {
1746
1802
  if (this.parser.target === "function_call") {
1747
- const outToStr = out.getResultContent();
1803
+ const outToStr = out.getResult();
1748
1804
  return this.parser.parse(outToStr, _metadata);
1749
1805
  } else {
1750
1806
  const outToStr = out.getResultText();
@@ -1769,7 +1825,7 @@ var LlmExecutorWithFunctions = class extends LlmExecutor {
1769
1825
  constructor(llmConfiguration, options) {
1770
1826
  super(
1771
1827
  Object.assign({}, llmConfiguration, {
1772
- parser: new LlmNativeFunctionParser({
1828
+ parser: new LlmFunctionParser({
1773
1829
  parser: llmConfiguration.parser || new StringParser()
1774
1830
  })
1775
1831
  }),
@@ -1780,7 +1836,23 @@ var LlmExecutorWithFunctions = class extends LlmExecutor {
1780
1836
  return super.execute(_input, _options);
1781
1837
  }
1782
1838
  };
1783
- var LlmExecutorOpenAiFunctions = class extends LlmExecutorWithFunctions {
1839
+ var LlmExecutorOpenAiFunctions = class extends LlmExecutor {
1840
+ constructor(llmConfiguration, options) {
1841
+ super(
1842
+ Object.assign({}, llmConfiguration, {
1843
+ parser: new LlmNativeFunctionParser({
1844
+ parser: llmConfiguration.parser || new StringParser()
1845
+ })
1846
+ }),
1847
+ options
1848
+ );
1849
+ console.warn(
1850
+ `LlmExecutorOpenAiFunctions is deprecated. Please migrate to LlmExecutorWithFunctions`
1851
+ );
1852
+ }
1853
+ async execute(_input, _options) {
1854
+ return super.execute(_input, _options);
1855
+ }
1784
1856
  };
1785
1857
 
1786
1858
  // src/executor/_functions.ts
@@ -1985,6 +2057,39 @@ function getEnvironmentVariable(name) {
1985
2057
  }
1986
2058
  }
1987
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
+
1988
2093
  // src/llm/config/openai/index.ts
1989
2094
  var openAiChatV1 = {
1990
2095
  key: "openai.chat.v1",
@@ -2003,12 +2108,7 @@ var openAiChatV1 = {
2003
2108
  mapBody: {
2004
2109
  prompt: {
2005
2110
  key: "messages",
2006
- sanitize: (v) => {
2007
- if (typeof v === "string") {
2008
- return [{ role: "user", content: v }];
2009
- }
2010
- return v;
2011
- }
2111
+ sanitize: openaiPromptSanitize
2012
2112
  },
2013
2113
  model: {
2014
2114
  key: "model"
@@ -2059,14 +2159,54 @@ var openai = {
2059
2159
  "openai.gpt-4o-mini": withDefaultModel(openAiChatV1, "gpt-4o-mini")
2060
2160
  };
2061
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
+
2062
2195
  // src/llm/config/anthropic/promptSanitize.ts
2063
2196
  function anthropicPromptSanitize(_messages, _inputBodyObj, _outputObj) {
2064
2197
  if (typeof _messages === "string") {
2065
- return [{ role: "user", content: _messages }];
2198
+ return [{ role: "user", content: _messages }].map(
2199
+ anthropicPromptMessageCallback
2200
+ );
2066
2201
  }
2067
- const [first, ...messages] = [..._messages.map((a) => ({ ...a }))];
2202
+ const [first, ...messages] = [
2203
+ ..._messages.map((a) => ({ ...a }))
2204
+ ];
2068
2205
  if (first.role === "system" && messages.length === 0) {
2069
- return [{ role: "user", content: first.content }, ...messages];
2206
+ return [
2207
+ { role: "user", content: first.content },
2208
+ ...messages
2209
+ ].map(anthropicPromptMessageCallback);
2070
2210
  }
2071
2211
  if (first.role === "system" && messages.length > 0) {
2072
2212
  _outputObj.system = first.content;
@@ -2075,7 +2215,7 @@ function anthropicPromptSanitize(_messages, _inputBodyObj, _outputObj) {
2075
2215
  return { ...m, role: "user" };
2076
2216
  }
2077
2217
  return m;
2078
- });
2218
+ }).map(anthropicPromptMessageCallback);
2079
2219
  }
2080
2220
  return [
2081
2221
  first,
@@ -2085,7 +2225,7 @@ function anthropicPromptSanitize(_messages, _inputBodyObj, _outputObj) {
2085
2225
  }
2086
2226
  return m;
2087
2227
  })
2088
- ];
2228
+ ].map(anthropicPromptMessageCallback);
2089
2229
  }
2090
2230
 
2091
2231
  // src/llm/config/bedrock/index.ts
@@ -2210,6 +2350,14 @@ var anthropicChatV1 = {
2210
2350
  };
2211
2351
  var anthropic = {
2212
2352
  "anthropic.chat.v1": anthropicChatV1,
2353
+ "anthropic.claude-sonnet-4-0": withDefaultModel(
2354
+ anthropicChatV1,
2355
+ "claude-sonnet-4-0"
2356
+ ),
2357
+ "anthropic.claude-opus-4-0": withDefaultModel(
2358
+ anthropicChatV1,
2359
+ "claude-sonnet-4-0"
2360
+ ),
2213
2361
  "anthropic.claude-3-7-sonnet": withDefaultModel(
2214
2362
  anthropicChatV1,
2215
2363
  "claude-3-7-sonnet-latest"
@@ -2222,6 +2370,7 @@ var anthropic = {
2222
2370
  anthropicChatV1,
2223
2371
  "claude-3-5-haiku-latest"
2224
2372
  ),
2373
+ // Deprecated
2225
2374
  "anthropic.claude-3-opus": withDefaultModel(
2226
2375
  anthropicChatV1,
2227
2376
  "claude-3-opus-latest"
@@ -2246,12 +2395,7 @@ var xaiChatV1 = {
2246
2395
  mapBody: {
2247
2396
  prompt: {
2248
2397
  key: "messages",
2249
- sanitize: (v) => {
2250
- if (typeof v === "string") {
2251
- return [{ role: "user", content: v }];
2252
- }
2253
- return v;
2254
- }
2398
+ sanitize: openaiPromptSanitize
2255
2399
  },
2256
2400
  model: {
2257
2401
  key: "model"
@@ -2267,7 +2411,9 @@ var xaiChatV1 = {
2267
2411
  };
2268
2412
  var xai = {
2269
2413
  "xai.chat.v1": xaiChatV1,
2270
- "xai.grok-2": withDefaultModel(xaiChatV1, "grok-2-latest")
2414
+ "xai.grok-2": withDefaultModel(xaiChatV1, "grok-2-latest"),
2415
+ "xai.grok-3": withDefaultModel(xaiChatV1, "grok-3"),
2416
+ "xai.grok-4": withDefaultModel(xaiChatV1, "grok-4")
2271
2417
  };
2272
2418
 
2273
2419
  // src/llm/config/ollama/index.ts
@@ -2304,30 +2450,49 @@ var ollama = {
2304
2450
  "ollama.qwq": withDefaultModel(ollamaChatV1, "qwq")
2305
2451
  };
2306
2452
 
2307
- // src/utils/modules/modifyPromptRoleChange.ts
2308
- function modifyPromptRoleChange(messages, roleChanges) {
2309
- const roleChangeMap = new Map(roleChanges.map(({ from, to }) => [from, to]));
2310
- if (Array.isArray(messages)) {
2311
- return messages.map((message) => {
2312
- const newRole2 = roleChangeMap.get(message.role);
2313
- return newRole2 ? { ...message, role: newRole2 } : message;
2314
- });
2315
- }
2316
- const newRole = roleChangeMap.get(messages.role);
2317
- return newRole ? { ...messages, role: newRole } : messages;
2318
- }
2319
-
2320
2453
  // src/llm/config/google/promptSanitizeMessageCallback.ts
2321
2454
  function googleGeminiPromptMessageCallback(_message) {
2322
2455
  let message = { ..._message };
2323
- message = modifyPromptRoleChange(_message, [
2324
- { from: "assistant", to: "model" }
2325
- ]);
2326
- const { role, ...payload } = message;
2327
2456
  const parts = [];
2457
+ if (message.role === "assistant") {
2458
+ message.role = "model";
2459
+ }
2460
+ if (message.role === "system") {
2461
+ message.role = "model";
2462
+ }
2463
+ let { role, ...payload } = message;
2328
2464
  if (typeof payload.content === "string") {
2329
2465
  parts.push({ text: message.content });
2330
2466
  }
2467
+ if (message.role === "function") {
2468
+ role = "user";
2469
+ parts.push({
2470
+ functionResponse: {
2471
+ name: message.name,
2472
+ response: {
2473
+ result: message.content
2474
+ }
2475
+ }
2476
+ });
2477
+ delete message.id;
2478
+ }
2479
+ if (message?.function_call) {
2480
+ const { function_call } = message;
2481
+ const toolsArr = Array.isArray(function_call) ? function_call : [function_call];
2482
+ role = "model";
2483
+ parts.push(
2484
+ ...toolsArr.map((call) => {
2485
+ const { name, arguments: input } = call;
2486
+ return {
2487
+ functionCall: {
2488
+ name,
2489
+ args: maybeParseJSON(input)
2490
+ }
2491
+ };
2492
+ })
2493
+ );
2494
+ delete message.function_call;
2495
+ }
2331
2496
  return {
2332
2497
  role,
2333
2498
  parts
@@ -2357,7 +2522,9 @@ function googleGeminiPromptSanitize(_messages, _inputBodyObj, _outputObj) {
2357
2522
  (message) => message.role !== "system"
2358
2523
  );
2359
2524
  _outputObj.system_instruction = {
2360
- parts: theSystemInstructions.map((message) => ({ text: message.content }))
2525
+ parts: theSystemInstructions.map((message) => ({
2526
+ text: message.content
2527
+ }))
2361
2528
  };
2362
2529
  return withoutSystemInstructions.map(googleGeminiPromptMessageCallback);
2363
2530
  }
@@ -2400,9 +2567,21 @@ var google = {
2400
2567
  googleGeminiChatV1,
2401
2568
  "gemini-2.0-flash-lite"
2402
2569
  ),
2570
+ "google.gemini-2.5-flash": withDefaultModel(
2571
+ googleGeminiChatV1,
2572
+ "gemini-2.5-flash"
2573
+ ),
2574
+ "google.gemini-2.5-flash-lite": withDefaultModel(
2575
+ googleGeminiChatV1,
2576
+ "gemini-2.5-flash-lite"
2577
+ ),
2403
2578
  "google.gemini-1.5-pro": withDefaultModel(
2404
2579
  googleGeminiChatV1,
2405
2580
  "gemini-1.5-pro"
2581
+ ),
2582
+ "google.gemini-2.5-pro": withDefaultModel(
2583
+ googleGeminiChatV1,
2584
+ "gemini-2.5-pro"
2406
2585
  )
2407
2586
  };
2408
2587
 
@@ -2424,12 +2603,7 @@ var deepseekChatV1 = {
2424
2603
  mapBody: {
2425
2604
  prompt: {
2426
2605
  key: "messages",
2427
- sanitize: (v) => {
2428
- if (typeof v === "string") {
2429
- return [{ role: "user", content: v }];
2430
- }
2431
- return v;
2432
- }
2606
+ sanitize: openaiPromptSanitize
2433
2607
  },
2434
2608
  model: {
2435
2609
  key: "model"
@@ -2478,7 +2652,7 @@ function getLlmConfig(provider) {
2478
2652
 
2479
2653
  // src/llm/output/_utils/getResultContent.ts
2480
2654
  function getResultContent(result, index) {
2481
- if (index && index > 0) {
2655
+ if (typeof index === "number" && index > 0) {
2482
2656
  const arr = result?.options || [];
2483
2657
  const val = arr[index];
2484
2658
  return val ? val : [];
@@ -2486,6 +2660,16 @@ function getResultContent(result, index) {
2486
2660
  return [...result.content];
2487
2661
  }
2488
2662
 
2663
+ // src/llm/output/_utils/getResultText.ts
2664
+ function getResultText(result, index) {
2665
+ if (typeof index === "number" && index > 0) {
2666
+ const arr = result?.options || [];
2667
+ const val = arr[index];
2668
+ return isOutputResultContentText(val?.[0]) ? val[0]?.text : "";
2669
+ }
2670
+ return isOutputResultContentText(result?.content?.[0]) ? result.content[0]?.text : "";
2671
+ }
2672
+
2489
2673
  // src/llm/output/base.ts
2490
2674
  function BaseLlmOutput2(result) {
2491
2675
  const __result = Object.freeze({
@@ -2510,7 +2694,7 @@ function BaseLlmOutput2(result) {
2510
2694
  }
2511
2695
  return {
2512
2696
  getResultContent: (index) => getResultContent(__result, index),
2513
- getResultText: () => getResultText(__result.content),
2697
+ getResultText: (index) => getResultText(__result, index),
2514
2698
  getResult
2515
2699
  };
2516
2700
  }
@@ -2534,36 +2718,27 @@ function formatOptions(response, handler) {
2534
2718
  }
2535
2719
  return out;
2536
2720
  }
2537
- function formatContent(response, handler) {
2538
- const out = [];
2539
- const result = handler(response);
2540
- if (result) {
2541
- out.push(result);
2542
- }
2543
- return out;
2544
- }
2545
2721
 
2546
2722
  // src/llm/output/openai.ts
2547
2723
  function formatResult(result) {
2724
+ const out = [];
2548
2725
  if (typeof result?.message?.content === "string") {
2549
- return {
2726
+ out.push({
2550
2727
  type: "text",
2551
2728
  text: result.message.content
2552
- };
2553
- } else if (result?.message && "tool_calls" in result.message) {
2554
- const tool_calls = result.message.tool_calls;
2555
- for (const call of tool_calls) {
2556
- return {
2729
+ });
2730
+ }
2731
+ if (result?.message?.tool_calls) {
2732
+ for (const call of result.message.tool_calls) {
2733
+ out.push({
2734
+ functionId: call.id,
2557
2735
  type: "function_use",
2558
2736
  name: call.function.name,
2559
- input: JSON.parse(call.function.arguments)
2560
- };
2737
+ input: maybeParseJSON(call.function.arguments)
2738
+ });
2561
2739
  }
2562
2740
  }
2563
- return {
2564
- type: "text",
2565
- text: ""
2566
- };
2741
+ return out;
2567
2742
  }
2568
2743
  function OutputOpenAIChat(result, _config) {
2569
2744
  const id = result.id;
@@ -2571,7 +2746,7 @@ function OutputOpenAIChat(result, _config) {
2571
2746
  const created = result.created;
2572
2747
  const [_content, ..._options] = result?.choices || [];
2573
2748
  const stopReason = _content?.finish_reason;
2574
- const content = formatContent(_content, formatResult);
2749
+ const content = formatResult(_content);
2575
2750
  const options = formatOptions(_options, formatResult);
2576
2751
  const usage = {
2577
2752
  output_tokens: result?.usage?.completion_tokens,
@@ -2602,6 +2777,7 @@ function formatResult2(response) {
2602
2777
  });
2603
2778
  } else if (result.type === "tool_use") {
2604
2779
  out.push({
2780
+ functionId: result.id,
2605
2781
  type: "function_use",
2606
2782
  name: result.name,
2607
2783
  input: result.input
@@ -2672,33 +2848,32 @@ function OutputDefault(result, _config) {
2672
2848
 
2673
2849
  // src/llm/output/xai.ts
2674
2850
  function formatResult3(result) {
2851
+ const out = [];
2675
2852
  if (typeof result?.message?.content === "string") {
2676
- return {
2853
+ out.push({
2677
2854
  type: "text",
2678
2855
  text: result.message.content
2679
- };
2680
- } else if (result?.message && "tool_calls" in result.message) {
2681
- const tool_calls = result.message.tool_calls;
2682
- for (const call of tool_calls) {
2683
- return {
2856
+ });
2857
+ }
2858
+ if (result?.message?.tool_calls) {
2859
+ for (const call of result.message.tool_calls) {
2860
+ out.push({
2861
+ functionId: call.id,
2684
2862
  type: "function_use",
2685
2863
  name: call.function.name,
2686
- input: JSON.parse(call.function.arguments)
2687
- };
2864
+ input: maybeParseJSON(call.function.arguments)
2865
+ });
2688
2866
  }
2689
2867
  }
2690
- return {
2691
- type: "text",
2692
- text: ""
2693
- };
2868
+ return out;
2694
2869
  }
2695
2870
  function OutputXAIChat(result, _config) {
2696
2871
  const id = result.id;
2697
- const name = result?.model;
2872
+ const name = result.model || _config?.model || "openai.unknown";
2698
2873
  const created = result.created;
2699
2874
  const [_content, ..._options] = result?.choices || [];
2700
2875
  const stopReason = _content?.finish_reason;
2701
- const content = formatContent(_content, formatResult3);
2876
+ const content = formatResult3(_content);
2702
2877
  const options = formatOptions(_options, formatResult3);
2703
2878
  const usage = {
2704
2879
  output_tokens: result?.usage?.completion_tokens,
@@ -2789,37 +2964,36 @@ function OutputOllamaChat(result, _config) {
2789
2964
  }
2790
2965
 
2791
2966
  // src/llm/output/google.gemini/formatResult.ts
2792
- function formatResult4(result) {
2967
+ function formatResult4(result, id) {
2793
2968
  const { parts = [] } = result?.content || {};
2794
- if (parts.length === 1) {
2795
- const answer = parts[0];
2796
- if (!!answer?.functionCall && typeof answer?.functionCall === "object") {
2797
- return {
2798
- type: "function_use",
2799
- name: answer.functionCall.name,
2800
- input: JSON.parse(answer.functionCall.args)
2801
- };
2802
- } else {
2803
- return {
2969
+ const out = [];
2970
+ for (let i = 0; i < parts.length; i++) {
2971
+ const part = parts[i];
2972
+ if (typeof part.text === "string") {
2973
+ out.push({
2804
2974
  type: "text",
2805
- text: answer.text || ""
2806
- };
2975
+ text: part.text
2976
+ });
2977
+ } else if (part?.functionCall) {
2978
+ out.push({
2979
+ functionId: `${id || uuidv4()}-${i}`,
2980
+ type: "function_use",
2981
+ name: part.functionCall.name,
2982
+ input: maybeParseJSON(part.functionCall.args)
2983
+ });
2807
2984
  }
2808
2985
  }
2809
- return {
2810
- type: "text",
2811
- text: ""
2812
- };
2986
+ return out;
2813
2987
  }
2814
2988
 
2815
2989
  // src/llm/output/google.gemini/index.ts
2816
2990
  function OutputGoogleGeminiChat(result, _config) {
2817
- const id = "result.id";
2818
- const name = result.modelVersion;
2991
+ const id = result.responseId;
2992
+ const name = result.modelVersion || _config?.model || "gemini";
2819
2993
  const created = (/* @__PURE__ */ new Date()).getTime();
2820
2994
  const [_content, ..._options] = result?.candidates || [];
2821
2995
  const stopReason = _content?.finishReason?.toLowerCase();
2822
- const content = formatContent(_content, formatResult4);
2996
+ const content = formatResult4(_content, id);
2823
2997
  const options = formatOptions(_options, formatResult4);
2824
2998
  const usage = {
2825
2999
  output_tokens: result?.usageMetadata?.candidatesTokenCount,
@@ -2837,8 +3011,53 @@ function OutputGoogleGeminiChat(result, _config) {
2837
3011
  });
2838
3012
  }
2839
3013
 
3014
+ // src/llm/output/deepseek.ts
3015
+ function formatResult5(result) {
3016
+ const out = [];
3017
+ if (typeof result?.message?.content === "string" && result?.message?.content) {
3018
+ out.push({
3019
+ type: "text",
3020
+ text: result.message.content
3021
+ });
3022
+ }
3023
+ if (result?.message?.tool_calls) {
3024
+ for (const call of result.message.tool_calls) {
3025
+ out.push({
3026
+ functionId: call.id,
3027
+ type: "function_use",
3028
+ name: call.function.name,
3029
+ input: maybeParseJSON(call.function.arguments)
3030
+ });
3031
+ }
3032
+ }
3033
+ return out;
3034
+ }
3035
+ function OutputDeepSeekChat(result, _config) {
3036
+ const id = result.id;
3037
+ const name = result.model || _config?.model || "deepseek.unknown";
3038
+ const created = result.created;
3039
+ const [_content, ..._options] = result?.choices || [];
3040
+ const stopReason = _content?.finish_reason;
3041
+ const content = formatResult5(_content);
3042
+ const options = formatOptions(_options, formatResult5);
3043
+ const usage = {
3044
+ output_tokens: result?.usage?.completion_tokens,
3045
+ input_tokens: result?.usage?.prompt_tokens,
3046
+ total_tokens: result?.usage?.total_tokens
3047
+ };
3048
+ return BaseLlmOutput2({
3049
+ id,
3050
+ name,
3051
+ created,
3052
+ usage,
3053
+ stopReason,
3054
+ content,
3055
+ options
3056
+ });
3057
+ }
3058
+
2840
3059
  // src/llm/output/index.ts
2841
- function getOutputParser(config, response) {
3060
+ function normalizeLlmOutputToInternalFormat(config, response) {
2842
3061
  switch (config?.key) {
2843
3062
  case "openai.chat.v1":
2844
3063
  case "openai.chat-mock.v1":
@@ -2857,7 +3076,7 @@ function getOutputParser(config, response) {
2857
3076
  case "google.chat.v1":
2858
3077
  return OutputGoogleGeminiChat(response, config);
2859
3078
  case "deepseek.chat.v1":
2860
- return OutputOpenAIChat(response, config);
3079
+ return OutputDeepSeekChat(response, config);
2861
3080
  // use oai for now
2862
3081
  default: {
2863
3082
  if (config?.key?.startsWith("custom:")) {
@@ -3087,9 +3306,9 @@ async function parseHeaders(config, replacements, payload) {
3087
3306
  // src/llm/output/_utils/cleanJsonSchemaFor.ts
3088
3307
  var providerFieldExclusions = {
3089
3308
  "openai.chat": ["default"],
3090
- // fields to exclude for openai.chat
3091
- "anthropic.chat": []
3092
- // fields to exclude for openai.chat
3309
+ // fields to exclude for openai.chat, xai, deepseek
3310
+ "anthropic.chat": [],
3311
+ "google.chat": ["additionalProperties"]
3093
3312
  };
3094
3313
  function cleanJsonSchemaFor(schema = {}, provider) {
3095
3314
  const clone = deepClone(schema);
@@ -3128,7 +3347,7 @@ async function useLlm_call(state, messages, _options) {
3128
3347
  })
3129
3348
  );
3130
3349
  if (_options && _options?.jsonSchema) {
3131
- if (state.provider.startsWith("openai")) {
3350
+ if (state.provider.startsWith("openai") || state.provider.startsWith("deepseek") || state.provider.startsWith("xai")) {
3132
3351
  const curr = input["response_format"] || {};
3133
3352
  input["response_format"] = Object.assign(curr, {
3134
3353
  type: "json_schema",
@@ -3149,11 +3368,17 @@ async function useLlm_call(state, messages, _options) {
3149
3368
  } else {
3150
3369
  input["tool_choice"] = _options?.functionCall;
3151
3370
  }
3152
- } else if (state.provider.startsWith("openai")) {
3371
+ } else if (state.provider.startsWith("openai") || state.provider.startsWith("deepseek") || state.provider.startsWith("xai")) {
3153
3372
  input["tool_choice"] = normalizeFunctionCall(
3154
3373
  _options?.functionCall,
3155
3374
  "openai"
3156
3375
  );
3376
+ } else if (state.provider.startsWith("google")) {
3377
+ input["toolConfig"] = {
3378
+ functionCallingConfig: {
3379
+ mode: normalizeFunctionCall(_options?.functionCall, "google")
3380
+ }
3381
+ };
3157
3382
  }
3158
3383
  }
3159
3384
  if (_options && _options?.functions?.length) {
@@ -3163,7 +3388,7 @@ async function useLlm_call(state, messages, _options) {
3163
3388
  description: f.description,
3164
3389
  input_schema: cleanJsonSchemaFor(f.parameters, "anthropic.chat")
3165
3390
  }));
3166
- } else if (state.provider.startsWith("openai")) {
3391
+ } else if (state.provider.startsWith("openai") || state.provider.startsWith("deepseek") || state.provider.startsWith("xai")) {
3167
3392
  input["tools"] = _options.functions.map((f) => {
3168
3393
  const props = {
3169
3394
  name: f?.name,
@@ -3181,6 +3406,16 @@ async function useLlm_call(state, messages, _options) {
3181
3406
  )
3182
3407
  };
3183
3408
  });
3409
+ } else if (state.provider.startsWith("google")) {
3410
+ input["tools"] = [
3411
+ {
3412
+ functionDeclarations: _options.functions.map((f) => ({
3413
+ name: f.name,
3414
+ description: f.description,
3415
+ parameters: cleanJsonSchemaFor(f.parameters, "google.chat")
3416
+ }))
3417
+ }
3418
+ ];
3184
3419
  }
3185
3420
  }
3186
3421
  const body = JSON.stringify(input);
@@ -3210,7 +3445,7 @@ async function useLlm_call(state, messages, _options) {
3210
3445
  body,
3211
3446
  headers
3212
3447
  });
3213
- return getOutputParser(state, response);
3448
+ return normalizeLlmOutputToInternalFormat(state, response);
3214
3449
  }
3215
3450
 
3216
3451
  // src/llm/_utils.stateFromOptions.ts
@@ -3782,7 +4017,7 @@ var ChatPrompt = class extends BasePrompt {
3782
4017
  this.parseUserTemplates = options?.allowUnsafeUserTemplate;
3783
4018
  }
3784
4019
  }
3785
- addToPrompt(content, role, name) {
4020
+ addToPrompt(content, role, name, id) {
3786
4021
  if (content) {
3787
4022
  switch (role) {
3788
4023
  case "system":
@@ -3796,11 +4031,11 @@ var ChatPrompt = class extends BasePrompt {
3796
4031
  break;
3797
4032
  case "function":
3798
4033
  assert(name, "Function message requires name");
3799
- this.addFunctionMessage(content, name);
4034
+ this.addFunctionMessage(content, name, id);
3800
4035
  break;
3801
4036
  case "function_call":
3802
4037
  assert(name, "Function message requires name");
3803
- this.addFunctionCallMessage({ name, arguments: content });
4038
+ this.addFunctionCallMessage({ name, arguments: content, id });
3804
4039
  break;
3805
4040
  }
3806
4041
  }
@@ -3840,11 +4075,12 @@ var ChatPrompt = class extends BasePrompt {
3840
4075
  * @param content The message content.
3841
4076
  * @return ChatPrompt so it can be chained.
3842
4077
  */
3843
- addFunctionMessage(content, name) {
4078
+ addFunctionMessage(content, name, id) {
3844
4079
  this.messages.push({
3845
4080
  role: "function",
3846
4081
  name,
3847
- content
4082
+ content,
4083
+ id
3848
4084
  });
3849
4085
  return this;
3850
4086
  }
@@ -3856,8 +4092,9 @@ var ChatPrompt = class extends BasePrompt {
3856
4092
  addFunctionCallMessage(function_call) {
3857
4093
  if (function_call) {
3858
4094
  this.messages.push({
3859
- role: "assistant",
4095
+ role: "function_call",
3860
4096
  function_call: {
4097
+ id: function_call.id,
3861
4098
  name: function_call.name,
3862
4099
  arguments: maybeStringifyJSON(function_call.arguments)
3863
4100
  },
@@ -3879,17 +4116,16 @@ var ChatPrompt = class extends BasePrompt {
3879
4116
  this.addUserMessage(message.content, message?.name);
3880
4117
  break;
3881
4118
  case "assistant":
3882
- if (message.function_call) {
3883
- this.addFunctionCallMessage(message.function_call);
3884
- } else if (message?.content) {
3885
- this.addAssistantMessage(message?.content);
3886
- }
4119
+ this.addAssistantMessage(message?.content);
3887
4120
  break;
3888
4121
  case "system":
3889
4122
  this.addSystemMessage(message.content);
3890
4123
  break;
4124
+ case "function_call":
4125
+ this.addFunctionCallMessage(message.function_call);
4126
+ break;
3891
4127
  case "function":
3892
- this.addFunctionMessage(message.content, message.name);
4128
+ this.addFunctionMessage(message.content, message.name, message.id);
3893
4129
  break;
3894
4130
  }
3895
4131
  }
@@ -3953,20 +4189,19 @@ var ChatPrompt = class extends BasePrompt {
3953
4189
  break;
3954
4190
  }
3955
4191
  case "assistant": {
3956
- if (message.function_call) {
3957
- messagesOut.push({
3958
- role: "assistant",
3959
- content: null,
3960
- function_call: message.function_call
3961
- });
3962
- } else if (message?.content) {
3963
- messagesOut.push({
3964
- role: "assistant",
3965
- content: message.content
3966
- });
3967
- }
4192
+ messagesOut.push({
4193
+ role: "assistant",
4194
+ content: message.content
4195
+ });
3968
4196
  break;
3969
4197
  }
4198
+ case "function_call":
4199
+ messagesOut.push({
4200
+ role: "function_call",
4201
+ content: null,
4202
+ function_call: message.function_call
4203
+ });
4204
+ break;
3970
4205
  case "function":
3971
4206
  messagesOut.push({
3972
4207
  role: "function",
@@ -4145,20 +4380,19 @@ var ChatPrompt = class extends BasePrompt {
4145
4380
  break;
4146
4381
  }
4147
4382
  case "assistant": {
4148
- if (message2.function_call) {
4149
- messagesOut.push({
4150
- role: "assistant",
4151
- content: null,
4152
- function_call: message2.function_call
4153
- });
4154
- } else if (message2?.content) {
4155
- messagesOut.push({
4156
- role: "assistant",
4157
- content: message2.content
4158
- });
4159
- }
4383
+ messagesOut.push({
4384
+ role: "assistant",
4385
+ content: message2.content
4386
+ });
4160
4387
  break;
4161
4388
  }
4389
+ case "function_call":
4390
+ messagesOut.push({
4391
+ role: "function_call",
4392
+ content: null,
4393
+ function_call: message2.function_call
4394
+ });
4395
+ break;
4162
4396
  case "function":
4163
4397
  messagesOut.push({
4164
4398
  role: "function",
@@ -4382,10 +4616,17 @@ var Dialogue = class extends BaseStateItem {
4382
4616
  }
4383
4617
  setAssistantMessage(content) {
4384
4618
  if (content) {
4385
- this.value.push({
4386
- role: "assistant",
4387
- content
4388
- });
4619
+ if (isOutputResultContentText(content)) {
4620
+ this.value.push({
4621
+ role: "assistant",
4622
+ content: content.text
4623
+ });
4624
+ } else {
4625
+ this.value.push({
4626
+ role: "assistant",
4627
+ content
4628
+ });
4629
+ }
4389
4630
  }
4390
4631
  return this;
4391
4632
  }
@@ -4398,28 +4639,57 @@ var Dialogue = class extends BaseStateItem {
4398
4639
  }
4399
4640
  return this;
4400
4641
  }
4401
- setFunctionMessage(content, name) {
4642
+ setToolMessage(content, name, id) {
4643
+ this.setFunctionMessage(content, name, id);
4644
+ }
4645
+ setFunctionMessage(content, name, id) {
4402
4646
  if (content) {
4403
4647
  this.value.push({
4404
4648
  role: "function",
4649
+ id,
4405
4650
  name,
4406
4651
  content
4407
4652
  });
4408
4653
  }
4409
4654
  return this;
4410
4655
  }
4656
+ /**
4657
+ * Set
4658
+ */
4659
+ setToolCallMessage(input) {
4660
+ this.setFunctionCallMessage(input);
4661
+ }
4411
4662
  setFunctionCallMessage(input) {
4412
- if (!input?.function_call) {
4663
+ if (!input || typeof input !== "object") {
4413
4664
  throw new LlmExeError(`Invalid arguments`, "state", {
4414
- error: `Invalid arguments: missing required function_call`,
4665
+ error: `Invalid arguments: input must be an object`,
4415
4666
  module: "dialogue"
4416
4667
  });
4417
4668
  }
4669
+ if ("function_call" in input) {
4670
+ if (!input.function_call || typeof input.function_call !== "object") {
4671
+ throw new LlmExeError(`Invalid arguments`, "state", {
4672
+ error: `Invalid arguments: input must be an object`,
4673
+ module: "dialogue"
4674
+ });
4675
+ }
4676
+ this.value.push({
4677
+ role: "function_call",
4678
+ function_call: {
4679
+ id: input?.function_call.id,
4680
+ name: input?.function_call.name,
4681
+ arguments: maybeStringifyJSON(input?.function_call.arguments)
4682
+ },
4683
+ content: null
4684
+ });
4685
+ return this;
4686
+ }
4418
4687
  this.value.push({
4419
- role: "assistant",
4688
+ role: "function_call",
4420
4689
  function_call: {
4421
- name: input?.function_call.name,
4422
- arguments: maybeStringifyJSON(input?.function_call.arguments)
4690
+ id: input?.id,
4691
+ name: input?.name,
4692
+ arguments: maybeStringifyJSON(input?.arguments)
4423
4693
  },
4424
4694
  content: null
4425
4695
  });
@@ -4437,21 +4707,26 @@ var Dialogue = class extends BaseStateItem {
4437
4707
  case "user":
4438
4708
  this.setUserMessage(message?.content, message?.name);
4439
4709
  break;
4710
+ case "model":
4440
4711
  case "assistant":
4441
- if (message.function_call) {
4442
- this.setFunctionCallMessage({
4443
- function_call: message.function_call
4444
- });
4445
- } else if (message?.content) {
4446
- this.setAssistantMessage(message?.content);
4447
- }
4712
+ this.setAssistantMessage(message?.content);
4448
4713
  break;
4449
4714
  case "system":
4450
4715
  this.setSystemMessage(message?.content);
4451
4716
  break;
4717
+ case "function_call":
4718
+ this.setFunctionCallMessage({
4719
+ function_call: message.function_call
4720
+ });
4721
+ break;
4452
4722
  case "function":
4453
4723
  this.setFunctionMessage(message?.content, message.name);
4454
4724
  break;
4725
+ default:
4726
+ this.value.push({
4727
+ role: message.role,
4728
+ content: message.content || ""
4729
+ });
4455
4730
  }
4456
4731
  }
4457
4732
  return this;
@@ -4467,6 +4742,30 @@ var Dialogue = class extends BaseStateItem {
4467
4742
  };
4468
4743
  }
4469
4744
  // deserialize() {}
4745
+ /**
4746
+ * Add LLM output to dialogue history in the order it was returned
4747
+ *
4748
+ * @param output - The LLM output result from llm.call()
4749
+ * @returns this for chaining
4750
+ */
4751
+ addFromOutput(output) {
4752
+ const result = "getResult" in output ? output.getResult() : output;
4753
+ if (!result || typeof result !== "object") {
4754
+ return this;
4755
+ }
4756
+ for (const item of result.content) {
4757
+ if (item.type === "text") {
4758
+ this.setAssistantMessage(item.text);
4759
+ } else if (item.type === "function_use") {
4760
+ this.setToolCallMessage({
4761
+ name: item.name,
4762
+ arguments: maybeStringifyJSON(item.input),
4763
+ id: item.functionId
4764
+ });
4765
+ }
4766
+ }
4767
+ return this;
4768
+ }
4470
4769
  };
4471
4770
 
4472
4771
  // src/state/_base.ts
@@ -4590,6 +4889,7 @@ export {
4590
4889
  createState,
4591
4890
  createStateItem,
4592
4891
  defineSchema,
4892
+ guards_exports as guards,
4593
4893
  registerHelpers,
4594
4894
  registerPartials,
4595
4895
  useExecutors,