llm-exe 2.2.1 → 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.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
@@ -2364,30 +2505,49 @@ var ollama = {
2364
2505
  "ollama.qwq": withDefaultModel(ollamaChatV1, "qwq")
2365
2506
  };
2366
2507
 
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
2508
  // src/llm/config/google/promptSanitizeMessageCallback.ts
2381
2509
  function googleGeminiPromptMessageCallback(_message) {
2382
2510
  let message = { ..._message };
2383
- message = modifyPromptRoleChange(_message, [
2384
- { from: "assistant", to: "model" }
2385
- ]);
2386
- const { role, ...payload } = message;
2387
2511
  const parts = [];
2512
+ if (message.role === "assistant") {
2513
+ message.role = "model";
2514
+ }
2515
+ if (message.role === "system") {
2516
+ message.role = "model";
2517
+ }
2518
+ let { role, ...payload } = message;
2388
2519
  if (typeof payload.content === "string") {
2389
2520
  parts.push({ text: message.content });
2390
2521
  }
2522
+ if (message.role === "function") {
2523
+ role = "user";
2524
+ parts.push({
2525
+ functionResponse: {
2526
+ name: message.name,
2527
+ response: {
2528
+ result: message.content
2529
+ }
2530
+ }
2531
+ });
2532
+ delete message.id;
2533
+ }
2534
+ if (message?.function_call) {
2535
+ const { function_call } = message;
2536
+ const toolsArr = Array.isArray(function_call) ? function_call : [function_call];
2537
+ role = "model";
2538
+ parts.push(
2539
+ ...toolsArr.map((call) => {
2540
+ const { name, arguments: input } = call;
2541
+ return {
2542
+ functionCall: {
2543
+ name,
2544
+ args: maybeParseJSON(input)
2545
+ }
2546
+ };
2547
+ })
2548
+ );
2549
+ delete message.function_call;
2550
+ }
2391
2551
  return {
2392
2552
  role,
2393
2553
  parts
@@ -2417,7 +2577,9 @@ function googleGeminiPromptSanitize(_messages, _inputBodyObj, _outputObj) {
2417
2577
  (message) => message.role !== "system"
2418
2578
  );
2419
2579
  _outputObj.system_instruction = {
2420
- parts: theSystemInstructions.map((message) => ({ text: message.content }))
2580
+ parts: theSystemInstructions.map((message) => ({
2581
+ text: message.content
2582
+ }))
2421
2583
  };
2422
2584
  return withoutSystemInstructions.map(googleGeminiPromptMessageCallback);
2423
2585
  }
@@ -2538,7 +2700,7 @@ function getLlmConfig(provider) {
2538
2700
 
2539
2701
  // src/llm/output/_utils/getResultContent.ts
2540
2702
  function getResultContent(result, index) {
2541
- if (index && index > 0) {
2703
+ if (typeof index === "number" && index > 0) {
2542
2704
  const arr = result?.options || [];
2543
2705
  const val = arr[index];
2544
2706
  return val ? val : [];
@@ -2546,6 +2708,16 @@ function getResultContent(result, index) {
2546
2708
  return [...result.content];
2547
2709
  }
2548
2710
 
2711
+ // src/llm/output/_utils/getResultText.ts
2712
+ function getResultText(result, index) {
2713
+ if (typeof index === "number" && index > 0) {
2714
+ const arr = result?.options || [];
2715
+ const val = arr[index];
2716
+ return isOutputResultContentText(val?.[0]) ? val[0]?.text : "";
2717
+ }
2718
+ return isOutputResultContentText(result?.content?.[0]) ? result.content[0]?.text : "";
2719
+ }
2720
+
2549
2721
  // src/llm/output/base.ts
2550
2722
  function BaseLlmOutput2(result) {
2551
2723
  const __result = Object.freeze({
@@ -2570,7 +2742,7 @@ function BaseLlmOutput2(result) {
2570
2742
  }
2571
2743
  return {
2572
2744
  getResultContent: (index) => getResultContent(__result, index),
2573
- getResultText: () => getResultText(__result.content),
2745
+ getResultText: (index) => getResultText(__result, index),
2574
2746
  getResult
2575
2747
  };
2576
2748
  }
@@ -2605,25 +2777,24 @@ function formatContent(response, handler) {
2605
2777
 
2606
2778
  // src/llm/output/openai.ts
2607
2779
  function formatResult(result) {
2780
+ const out = [];
2608
2781
  if (typeof result?.message?.content === "string") {
2609
- return {
2782
+ out.push({
2610
2783
  type: "text",
2611
2784
  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 {
2785
+ });
2786
+ }
2787
+ if (result?.message?.tool_calls) {
2788
+ for (const call of result.message.tool_calls) {
2789
+ out.push({
2790
+ functionId: call.id,
2617
2791
  type: "function_use",
2618
2792
  name: call.function.name,
2619
- input: JSON.parse(call.function.arguments)
2620
- };
2793
+ input: maybeParseJSON(call.function.arguments)
2794
+ });
2621
2795
  }
2622
2796
  }
2623
- return {
2624
- type: "text",
2625
- text: ""
2626
- };
2797
+ return out;
2627
2798
  }
2628
2799
  function OutputOpenAIChat(result, _config) {
2629
2800
  const id = result.id;
@@ -2631,7 +2802,7 @@ function OutputOpenAIChat(result, _config) {
2631
2802
  const created = result.created;
2632
2803
  const [_content, ..._options] = result?.choices || [];
2633
2804
  const stopReason = _content?.finish_reason;
2634
- const content = formatContent(_content, formatResult);
2805
+ const content = formatResult(_content);
2635
2806
  const options = formatOptions(_options, formatResult);
2636
2807
  const usage = {
2637
2808
  output_tokens: result?.usage?.completion_tokens,
@@ -2662,6 +2833,7 @@ function formatResult2(response) {
2662
2833
  });
2663
2834
  } else if (result.type === "tool_use") {
2664
2835
  out.push({
2836
+ functionId: result.id,
2665
2837
  type: "function_use",
2666
2838
  name: result.name,
2667
2839
  input: result.input
@@ -2739,12 +2911,15 @@ function formatResult3(result) {
2739
2911
  };
2740
2912
  } else if (result?.message && "tool_calls" in result.message) {
2741
2913
  const tool_calls = result.message.tool_calls;
2742
- for (const call of tool_calls) {
2743
- return {
2744
- type: "function_use",
2745
- name: call.function.name,
2746
- input: JSON.parse(call.function.arguments)
2747
- };
2914
+ if (tool_calls) {
2915
+ for (const call of tool_calls) {
2916
+ return {
2917
+ functionId: call.id,
2918
+ type: "function_use",
2919
+ name: call.function.name,
2920
+ input: JSON.parse(call.function.arguments)
2921
+ };
2922
+ }
2748
2923
  }
2749
2924
  }
2750
2925
  return {
@@ -2849,37 +3024,36 @@ function OutputOllamaChat(result, _config) {
2849
3024
  }
2850
3025
 
2851
3026
  // src/llm/output/google.gemini/formatResult.ts
2852
- function formatResult4(result) {
3027
+ function formatResult4(result, id) {
2853
3028
  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 {
3029
+ const out = [];
3030
+ for (let i = 0; i < parts.length; i++) {
3031
+ const part = parts[i];
3032
+ if (typeof part.text === "string") {
3033
+ out.push({
2864
3034
  type: "text",
2865
- text: answer.text || ""
2866
- };
3035
+ text: part.text
3036
+ });
3037
+ } else if (part?.functionCall) {
3038
+ out.push({
3039
+ functionId: `${id || (0, import_uuid.v4)()}-${i}`,
3040
+ type: "function_use",
3041
+ name: part.functionCall.name,
3042
+ input: maybeParseJSON(part.functionCall.args)
3043
+ });
2867
3044
  }
2868
3045
  }
2869
- return {
2870
- type: "text",
2871
- text: ""
2872
- };
3046
+ return out;
2873
3047
  }
2874
3048
 
2875
3049
  // src/llm/output/google.gemini/index.ts
2876
3050
  function OutputGoogleGeminiChat(result, _config) {
2877
- const id = "result.id";
2878
- const name = result.modelVersion;
3051
+ const id = result.responseId;
3052
+ const name = result.modelVersion || _config?.model || "gemini";
2879
3053
  const created = (/* @__PURE__ */ new Date()).getTime();
2880
3054
  const [_content, ..._options] = result?.candidates || [];
2881
3055
  const stopReason = _content?.finishReason?.toLowerCase();
2882
- const content = formatContent(_content, formatResult4);
3056
+ const content = formatResult4(_content, id);
2883
3057
  const options = formatOptions(_options, formatResult4);
2884
3058
  const usage = {
2885
3059
  output_tokens: result?.usageMetadata?.candidatesTokenCount,
@@ -2898,7 +3072,7 @@ function OutputGoogleGeminiChat(result, _config) {
2898
3072
  }
2899
3073
 
2900
3074
  // src/llm/output/index.ts
2901
- function getOutputParser(config, response) {
3075
+ function normalizeLlmOutputToInternalFormat(config, response) {
2902
3076
  switch (config?.key) {
2903
3077
  case "openai.chat.v1":
2904
3078
  case "openai.chat-mock.v1":
@@ -3214,6 +3388,12 @@ async function useLlm_call(state, messages, _options) {
3214
3388
  _options?.functionCall,
3215
3389
  "openai"
3216
3390
  );
3391
+ } else if (state.provider.startsWith("google")) {
3392
+ input["toolConfig"] = {
3393
+ functionCallingConfig: {
3394
+ mode: normalizeFunctionCall(_options?.functionCall, "google")
3395
+ }
3396
+ };
3217
3397
  }
3218
3398
  }
3219
3399
  if (_options && _options?.functions?.length) {
@@ -3241,6 +3421,16 @@ async function useLlm_call(state, messages, _options) {
3241
3421
  )
3242
3422
  };
3243
3423
  });
3424
+ } else if (state.provider.startsWith("google")) {
3425
+ input["tools"] = [
3426
+ {
3427
+ functionDeclarations: _options.functions.map((f) => ({
3428
+ name: f.name,
3429
+ description: f.description,
3430
+ parameters: cleanJsonSchemaFor(f.parameters, "google.chat")
3431
+ }))
3432
+ }
3433
+ ];
3244
3434
  }
3245
3435
  }
3246
3436
  const body = JSON.stringify(input);
@@ -3270,7 +3460,7 @@ async function useLlm_call(state, messages, _options) {
3270
3460
  body,
3271
3461
  headers
3272
3462
  });
3273
- return getOutputParser(state, response);
3463
+ return normalizeLlmOutputToInternalFormat(state, response);
3274
3464
  }
3275
3465
 
3276
3466
  // src/llm/_utils.stateFromOptions.ts
@@ -3842,7 +4032,7 @@ var ChatPrompt = class extends BasePrompt {
3842
4032
  this.parseUserTemplates = options?.allowUnsafeUserTemplate;
3843
4033
  }
3844
4034
  }
3845
- addToPrompt(content, role, name) {
4035
+ addToPrompt(content, role, name, id) {
3846
4036
  if (content) {
3847
4037
  switch (role) {
3848
4038
  case "system":
@@ -3856,11 +4046,11 @@ var ChatPrompt = class extends BasePrompt {
3856
4046
  break;
3857
4047
  case "function":
3858
4048
  assert(name, "Function message requires name");
3859
- this.addFunctionMessage(content, name);
4049
+ this.addFunctionMessage(content, name, id);
3860
4050
  break;
3861
4051
  case "function_call":
3862
4052
  assert(name, "Function message requires name");
3863
- this.addFunctionCallMessage({ name, arguments: content });
4053
+ this.addFunctionCallMessage({ name, arguments: content, id });
3864
4054
  break;
3865
4055
  }
3866
4056
  }
@@ -3900,11 +4090,12 @@ var ChatPrompt = class extends BasePrompt {
3900
4090
  * @param content The message content.
3901
4091
  * @return ChatPrompt so it can be chained.
3902
4092
  */
3903
- addFunctionMessage(content, name) {
4093
+ addFunctionMessage(content, name, id) {
3904
4094
  this.messages.push({
3905
4095
  role: "function",
3906
4096
  name,
3907
- content
4097
+ content,
4098
+ id
3908
4099
  });
3909
4100
  return this;
3910
4101
  }
@@ -3916,8 +4107,9 @@ var ChatPrompt = class extends BasePrompt {
3916
4107
  addFunctionCallMessage(function_call) {
3917
4108
  if (function_call) {
3918
4109
  this.messages.push({
3919
- role: "assistant",
4110
+ role: "function_call",
3920
4111
  function_call: {
4112
+ id: function_call.id,
3921
4113
  name: function_call.name,
3922
4114
  arguments: maybeStringifyJSON(function_call.arguments)
3923
4115
  },
@@ -3939,17 +4131,16 @@ var ChatPrompt = class extends BasePrompt {
3939
4131
  this.addUserMessage(message.content, message?.name);
3940
4132
  break;
3941
4133
  case "assistant":
3942
- if (message.function_call) {
3943
- this.addFunctionCallMessage(message.function_call);
3944
- } else if (message?.content) {
3945
- this.addAssistantMessage(message?.content);
3946
- }
4134
+ this.addAssistantMessage(message?.content);
3947
4135
  break;
3948
4136
  case "system":
3949
4137
  this.addSystemMessage(message.content);
3950
4138
  break;
4139
+ case "function_call":
4140
+ this.addFunctionCallMessage(message.function_call);
4141
+ break;
3951
4142
  case "function":
3952
- this.addFunctionMessage(message.content, message.name);
4143
+ this.addFunctionMessage(message.content, message.name, message.id);
3953
4144
  break;
3954
4145
  }
3955
4146
  }
@@ -4013,20 +4204,19 @@ var ChatPrompt = class extends BasePrompt {
4013
4204
  break;
4014
4205
  }
4015
4206
  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
- }
4207
+ messagesOut.push({
4208
+ role: "assistant",
4209
+ content: message.content
4210
+ });
4028
4211
  break;
4029
4212
  }
4213
+ case "function_call":
4214
+ messagesOut.push({
4215
+ role: "function_call",
4216
+ content: null,
4217
+ function_call: message.function_call
4218
+ });
4219
+ break;
4030
4220
  case "function":
4031
4221
  messagesOut.push({
4032
4222
  role: "function",
@@ -4205,20 +4395,19 @@ var ChatPrompt = class extends BasePrompt {
4205
4395
  break;
4206
4396
  }
4207
4397
  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
- }
4398
+ messagesOut.push({
4399
+ role: "assistant",
4400
+ content: message2.content
4401
+ });
4220
4402
  break;
4221
4403
  }
4404
+ case "function_call":
4405
+ messagesOut.push({
4406
+ role: "function_call",
4407
+ content: null,
4408
+ function_call: message2.function_call
4409
+ });
4410
+ break;
4222
4411
  case "function":
4223
4412
  messagesOut.push({
4224
4413
  role: "function",
@@ -4442,10 +4631,17 @@ var Dialogue = class extends BaseStateItem {
4442
4631
  }
4443
4632
  setAssistantMessage(content) {
4444
4633
  if (content) {
4445
- this.value.push({
4446
- role: "assistant",
4447
- content
4448
- });
4634
+ if (isOutputResultContentText(content)) {
4635
+ this.value.push({
4636
+ role: "assistant",
4637
+ content: content.text
4638
+ });
4639
+ } else {
4640
+ this.value.push({
4641
+ role: "assistant",
4642
+ content
4643
+ });
4644
+ }
4449
4645
  }
4450
4646
  return this;
4451
4647
  }
@@ -4458,28 +4654,57 @@ var Dialogue = class extends BaseStateItem {
4458
4654
  }
4459
4655
  return this;
4460
4656
  }
4461
- setFunctionMessage(content, name) {
4657
+ setToolMessage(content, name, id) {
4658
+ this.setFunctionMessage(content, name, id);
4659
+ }
4660
+ setFunctionMessage(content, name, id) {
4462
4661
  if (content) {
4463
4662
  this.value.push({
4464
4663
  role: "function",
4664
+ id,
4465
4665
  name,
4466
4666
  content
4467
4667
  });
4468
4668
  }
4469
4669
  return this;
4470
4670
  }
4671
+ /**
4672
+ * Set
4673
+ */
4674
+ setToolCallMessage(input) {
4675
+ this.setFunctionCallMessage(input);
4676
+ }
4471
4677
  setFunctionCallMessage(input) {
4472
- if (!input?.function_call) {
4678
+ if (!input || typeof input !== "object") {
4473
4679
  throw new LlmExeError(`Invalid arguments`, "state", {
4474
- error: `Invalid arguments: missing required function_call`,
4680
+ error: `Invalid arguments: input must be an object`,
4475
4681
  module: "dialogue"
4476
4682
  });
4477
4683
  }
4684
+ if ("function_call" in input) {
4685
+ if (!input.function_call || typeof input.function_call !== "object") {
4686
+ throw new LlmExeError(`Invalid arguments`, "state", {
4687
+ error: `Invalid arguments: input must be an object`,
4688
+ module: "dialogue"
4689
+ });
4690
+ }
4691
+ this.value.push({
4692
+ role: "function_call",
4693
+ function_call: {
4694
+ id: input?.function_call.id,
4695
+ name: input?.function_call.name,
4696
+ arguments: maybeStringifyJSON(input?.function_call.arguments)
4697
+ },
4698
+ content: null
4699
+ });
4700
+ return this;
4701
+ }
4478
4702
  this.value.push({
4479
- role: "assistant",
4703
+ role: "function_call",
4480
4704
  function_call: {
4481
- name: input?.function_call.name,
4482
- arguments: maybeStringifyJSON(input?.function_call.arguments)
4705
+ id: input?.id,
4706
+ name: input?.name,
4707
+ arguments: maybeStringifyJSON(input?.arguments)
4483
4708
  },
4484
4709
  content: null
4485
4710
  });
@@ -4497,21 +4722,26 @@ var Dialogue = class extends BaseStateItem {
4497
4722
  case "user":
4498
4723
  this.setUserMessage(message?.content, message?.name);
4499
4724
  break;
4725
+ case "model":
4500
4726
  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
- }
4727
+ this.setAssistantMessage(message?.content);
4508
4728
  break;
4509
4729
  case "system":
4510
4730
  this.setSystemMessage(message?.content);
4511
4731
  break;
4732
+ case "function_call":
4733
+ this.setFunctionCallMessage({
4734
+ function_call: message.function_call
4735
+ });
4736
+ break;
4512
4737
  case "function":
4513
4738
  this.setFunctionMessage(message?.content, message.name);
4514
4739
  break;
4740
+ default:
4741
+ this.value.push({
4742
+ role: message.role,
4743
+ content: message.content || ""
4744
+ });
4515
4745
  }
4516
4746
  }
4517
4747
  return this;
@@ -4527,6 +4757,30 @@ var Dialogue = class extends BaseStateItem {
4527
4757
  };
4528
4758
  }
4529
4759
  // deserialize() {}
4760
+ /**
4761
+ * Add LLM output to dialogue history in the order it was returned
4762
+ *
4763
+ * @param output - The LLM output result from llm.call()
4764
+ * @returns this for chaining
4765
+ */
4766
+ addFromOutput(output) {
4767
+ const result = "getResult" in output ? output.getResult() : output;
4768
+ if (!result || typeof result !== "object") {
4769
+ return this;
4770
+ }
4771
+ for (const item of result.content) {
4772
+ if (item.type === "text") {
4773
+ this.setAssistantMessage(item.text);
4774
+ } else if (item.type === "function_use") {
4775
+ this.setToolCallMessage({
4776
+ name: item.name,
4777
+ arguments: maybeStringifyJSON(item.input),
4778
+ id: item.functionId
4779
+ });
4780
+ }
4781
+ }
4782
+ return this;
4783
+ }
4530
4784
  };
4531
4785
 
4532
4786
  // src/state/_base.ts
@@ -4651,6 +4905,7 @@ function createStateItem(name, defaultValue) {
4651
4905
  createState,
4652
4906
  createStateItem,
4653
4907
  defineSchema,
4908
+ guards,
4654
4909
  registerHelpers,
4655
4910
  registerPartials,
4656
4911
  useExecutors,