llm-exe 2.3.4 → 2.3.6

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
@@ -557,6 +557,21 @@ function toNumber(value) {
557
557
  return NaN;
558
558
  }
559
559
 
560
+ // src/utils/modules/errors.ts
561
+ var LlmExeError = class extends Error {
562
+ constructor(message, code, context) {
563
+ super(message ?? "");
564
+ __publicField(this, "code");
565
+ __publicField(this, "context");
566
+ this.name = this.constructor.name;
567
+ this.code = code ?? "unknown";
568
+ this.context = context;
569
+ if (Error.captureStackTrace) {
570
+ Error.captureStackTrace(this, this.constructor);
571
+ }
572
+ }
573
+ };
574
+
560
575
  // src/parser/parsers/NumberParser.ts
561
576
  var NumberParser = class extends BaseParser {
562
577
  constructor(options) {
@@ -564,7 +579,18 @@ var NumberParser = class extends BaseParser {
564
579
  }
565
580
  parse(text) {
566
581
  const match = text.match(/-?\d+(\.\d+)?/);
567
- return match && isFinite(toNumber(match[0])) ? toNumber(match[0]) : -1;
582
+ if (match && isFinite(toNumber(match[0]))) {
583
+ return toNumber(match[0]);
584
+ }
585
+ throw new LlmExeError(
586
+ `No numeric value found in input.`,
587
+ "parser",
588
+ {
589
+ parser: "number",
590
+ output: text,
591
+ error: `No numeric value found in input.`
592
+ }
593
+ );
568
594
  }
569
595
  };
570
596
 
@@ -1461,7 +1487,7 @@ var asyncCallWithTimeout = async (asyncPromise, timeLimit = 1e4) => {
1461
1487
  const timeoutPromise = new Promise((_resolve, reject) => {
1462
1488
  timeoutHandle = setTimeout(() => {
1463
1489
  return reject(
1464
- new Error("Unable to perform action. Try again, or use another action.")
1490
+ new Error(`LLM call timed out after ${timeLimit}ms`)
1465
1491
  );
1466
1492
  }, timeLimit);
1467
1493
  });
@@ -1549,21 +1575,6 @@ function validateParserSchema(schema, parsed) {
1549
1575
  return null;
1550
1576
  }
1551
1577
 
1552
- // src/utils/modules/errors.ts
1553
- var LlmExeError = class extends Error {
1554
- constructor(message, code, context) {
1555
- super(message ?? "");
1556
- __publicField(this, "code");
1557
- __publicField(this, "context");
1558
- this.name = this.constructor.name;
1559
- this.code = code ?? "unknown";
1560
- this.context = context;
1561
- if (Error.captureStackTrace) {
1562
- Error.captureStackTrace(this, this.constructor);
1563
- }
1564
- }
1565
- };
1566
-
1567
1578
  // src/parser/parsers/JsonParser.ts
1568
1579
  var JsonParser = class extends BaseParserWithJson {
1569
1580
  constructor(options = {}) {
@@ -1607,6 +1618,8 @@ function camelCase(input) {
1607
1618
  var ListToJsonParser = class extends BaseParserWithJson {
1608
1619
  constructor(options = {}) {
1609
1620
  super("listToJson", options);
1621
+ __publicField(this, "keyTransform");
1622
+ this.keyTransform = options.keyTransform ?? "camelCase";
1610
1623
  }
1611
1624
  parse(text) {
1612
1625
  const lines = text.split("\n");
@@ -1617,7 +1630,8 @@ var ListToJsonParser = class extends BaseParserWithJson {
1617
1630
  const key = line.slice(0, colonIndex);
1618
1631
  const value = line.slice(colonIndex + 1).trim();
1619
1632
  if (value) {
1620
- output[camelCase(key)] = value;
1633
+ const transformedKey = this.keyTransform === "preserve" ? key.trim() : camelCase(key);
1634
+ output[transformedKey] = value;
1621
1635
  }
1622
1636
  }
1623
1637
  });
@@ -1790,7 +1804,15 @@ var StringExtractParser = class extends BaseParser {
1790
1804
  return option;
1791
1805
  }
1792
1806
  }
1793
- return "";
1807
+ throw new LlmExeError(
1808
+ `No matching enum value found in input.`,
1809
+ "parser",
1810
+ {
1811
+ parser: "stringExtract",
1812
+ output: text,
1813
+ error: `No matching enum value found in input. Expected one of: ${this.enum.join(", ")}`
1814
+ }
1815
+ );
1794
1816
  }
1795
1817
  };
1796
1818
 
@@ -2307,6 +2329,7 @@ function cleanJsonSchemaFor(schema = {}, provider) {
2307
2329
  // src/llm/config/openai/compatible.ts
2308
2330
  function createOpenAiCompatibleConfiguration(overrides) {
2309
2331
  const [apiKeyPropertyKey, apiKeyPropertyValue] = overrides.apiKeyMapping;
2332
+ const isReasoningModel = overrides.isReasoningModel ?? (() => false);
2310
2333
  const config = {
2311
2334
  key: overrides.key,
2312
2335
  provider: overrides.provider,
@@ -2314,7 +2337,12 @@ function createOpenAiCompatibleConfiguration(overrides) {
2314
2337
  options: {
2315
2338
  prompt: {},
2316
2339
  effort: {},
2340
+ temperature: {},
2317
2341
  topP: {},
2342
+ maxTokens: {},
2343
+ stopSequences: {},
2344
+ frequencyPenalty: {},
2345
+ logitBias: {},
2318
2346
  useJson: {},
2319
2347
  [apiKeyPropertyKey]: {
2320
2348
  default: getEnvironmentVariable(apiKeyPropertyValue)
@@ -2330,9 +2358,24 @@ function createOpenAiCompatibleConfiguration(overrides) {
2330
2358
  model: {
2331
2359
  key: "model"
2332
2360
  },
2361
+ temperature: {
2362
+ key: "temperature"
2363
+ },
2333
2364
  topP: {
2334
2365
  key: "top_p"
2335
2366
  },
2367
+ maxTokens: {
2368
+ key: "max_tokens"
2369
+ },
2370
+ stopSequences: {
2371
+ key: "stop"
2372
+ },
2373
+ frequencyPenalty: {
2374
+ key: "frequency_penalty"
2375
+ },
2376
+ logitBias: {
2377
+ key: "logit_bias"
2378
+ },
2336
2379
  useJson: {
2337
2380
  key: "response_format.type",
2338
2381
  transform: (v) => v ? "json_object" : "text"
@@ -2340,10 +2383,7 @@ function createOpenAiCompatibleConfiguration(overrides) {
2340
2383
  effort: {
2341
2384
  key: "reasoning_effort",
2342
2385
  transform: (v, _s) => {
2343
- if (
2344
- // only supported reasoning models
2345
- ["gpt-5"].includes(_s.model) && typeof v === "string" && ["minimal", "low", "medium", "high"].includes(v)
2346
- ) {
2386
+ if (typeof _s.model === "string" && isReasoningModel(_s.model) && typeof v === "string" && ["minimal", "low", "medium", "high"].includes(v)) {
2347
2387
  return v;
2348
2388
  }
2349
2389
  return void 0;
@@ -2390,7 +2430,8 @@ var openAiChatV1 = createOpenAiCompatibleConfiguration({
2390
2430
  key: "openai.chat.v1",
2391
2431
  provider: "openai.chat",
2392
2432
  endpoint: `https://api.openai.com/v1/chat/completions`,
2393
- apiKeyMapping: ["openAiApiKey", "OPENAI_API_KEY"]
2433
+ apiKeyMapping: ["openAiApiKey", "OPENAI_API_KEY"],
2434
+ isReasoningModel: (model) => model.startsWith("gpt-5") || model.startsWith("o3") || model.startsWith("o4")
2394
2435
  });
2395
2436
  var openAiChatMockV1 = {
2396
2437
  key: "openai.chat-mock.v1",
@@ -2436,10 +2477,12 @@ var openai = {
2436
2477
  "openai.gpt-4.1-nano": withDefaultModel(openAiChatV1, "gpt-4.1-nano"),
2437
2478
  // Reasoning models
2438
2479
  "openai.o3": withDefaultModel(openAiChatV1, "o3"),
2439
- "openai.o4-mini": withDefaultModel(openAiChatV1, "o4-mini"),
2440
2480
  // GPT-4o family
2481
+ "openai.gpt-4": withDefaultModel(openAiChatV1, "gpt-4"),
2441
2482
  "openai.gpt-4o": withDefaultModel(openAiChatV1, "gpt-4o"),
2442
- "openai.gpt-4o-mini": withDefaultModel(openAiChatV1, "gpt-4o-mini")
2483
+ "openai.gpt-4o-mini": withDefaultModel(openAiChatV1, "gpt-4o-mini"),
2484
+ // Deprecated
2485
+ "openai.o4-mini": withDefaultModel(openAiChatV1, "o4-mini")
2443
2486
  };
2444
2487
 
2445
2488
  // src/llm/config/anthropic/promptSanitizeMessageCallback.ts
@@ -2699,6 +2742,14 @@ var bedrock = {
2699
2742
 
2700
2743
  // src/llm/config/anthropic/index.ts
2701
2744
  var ANTHROPIC_VERSION = "2023-06-01";
2745
+ var MODELS_REJECTING_SAMPLING_PARAMS = ["claude-opus-4-7"];
2746
+ var isClaude4x = (model) => /^claude-(opus|sonnet|haiku)-4-/.test(model);
2747
+ var dropIfModelRejectsSamplingParams = (v, body) => MODELS_REJECTING_SAMPLING_PARAMS.includes(body.model) ? void 0 : v;
2748
+ var topPTransform = (v, body) => {
2749
+ if (MODELS_REJECTING_SAMPLING_PARAMS.includes(body.model)) return void 0;
2750
+ if (isClaude4x(body.model) && body.temperature !== void 0) return void 0;
2751
+ return v;
2752
+ };
2702
2753
  var anthropicChatV1 = {
2703
2754
  key: "anthropic.chat.v1",
2704
2755
  provider: "anthropic.chat",
@@ -2731,13 +2782,16 @@ var anthropicChatV1 = {
2731
2782
  transform: anthropicPromptSanitize
2732
2783
  },
2733
2784
  temperature: {
2734
- key: "temperature"
2785
+ key: "temperature",
2786
+ transform: dropIfModelRejectsSamplingParams
2735
2787
  },
2736
2788
  topP: {
2737
- key: "top_p"
2789
+ key: "top_p",
2790
+ transform: topPTransform
2738
2791
  },
2739
2792
  topK: {
2740
- key: "top_k"
2793
+ key: "top_k",
2794
+ transform: dropIfModelRejectsSamplingParams
2741
2795
  },
2742
2796
  stopSequences: {
2743
2797
  key: "stop_sequences"
@@ -2773,6 +2827,11 @@ var anthropicChatV1 = {
2773
2827
  };
2774
2828
  var anthropic = {
2775
2829
  "anthropic.chat.v1": anthropicChatV1,
2830
+ // Claude 4.7 models
2831
+ "anthropic.claude-opus-4-7": withDefaultModel(
2832
+ anthropicChatV1,
2833
+ "claude-opus-4-7"
2834
+ ),
2776
2835
  // Claude 4.6 models
2777
2836
  "anthropic.claude-opus-4-6": withDefaultModel(
2778
2837
  anthropicChatV1,
@@ -2782,7 +2841,20 @@ var anthropic = {
2782
2841
  anthropicChatV1,
2783
2842
  "claude-sonnet-4-6"
2784
2843
  ),
2785
- // Claude 4 models
2844
+ // Claude 4.5 models
2845
+ "anthropic.claude-haiku-4-5": withDefaultModel(
2846
+ anthropicChatV1,
2847
+ "claude-haiku-4-5"
2848
+ ),
2849
+ "anthropic.claude-sonnet-4-5": withDefaultModel(
2850
+ anthropicChatV1,
2851
+ "claude-sonnet-4-5"
2852
+ ),
2853
+ // Deprecated
2854
+ "anthropic.claude-opus-4-1": withDefaultModel(
2855
+ anthropicChatV1,
2856
+ "claude-opus-4-1-20250805"
2857
+ ),
2786
2858
  "anthropic.claude-sonnet-4": withDefaultModel(
2787
2859
  anthropicChatV1,
2788
2860
  "claude-sonnet-4-0"
@@ -2795,7 +2867,6 @@ var anthropic = {
2795
2867
  anthropicChatV1,
2796
2868
  "claude-3-7-sonnet-20250219"
2797
2869
  ),
2798
- // Claude 3.5 models
2799
2870
  "anthropic.claude-3-5-sonnet": withDefaultModel(
2800
2871
  anthropicChatV1,
2801
2872
  "claude-3-5-sonnet-latest"
@@ -2804,14 +2875,9 @@ var anthropic = {
2804
2875
  anthropicChatV1,
2805
2876
  "claude-3-5-haiku-latest"
2806
2877
  ),
2807
- // Deprecated
2808
2878
  "anthropic.claude-3-opus": withDefaultModel(
2809
2879
  anthropicChatV1,
2810
2880
  "claude-3-opus-20240229"
2811
- ),
2812
- "anthropic.claude-3-haiku": withDefaultModel(
2813
- anthropicChatV1,
2814
- "claude-3-haiku-20240307"
2815
2881
  )
2816
2882
  };
2817
2883
 
@@ -2820,7 +2886,13 @@ var xaiChatV1 = createOpenAiCompatibleConfiguration({
2820
2886
  key: "xai.chat.v1",
2821
2887
  provider: "xai.chat",
2822
2888
  endpoint: `https://api.x.ai/v1/chat/completions`,
2823
- apiKeyMapping: ["xAiApiKey", "XAI_API_KEY"]
2889
+ apiKeyMapping: ["xAiApiKey", "XAI_API_KEY"],
2890
+ // Per xAI docs (checked 2026-05-13), grok-4 errors if `reasoning_effort` is
2891
+ // sent; grok-3-mini and the fast-non-reasoning variants don't accept it
2892
+ // either. Only grok-4.3 and grok-4.20-multi-agent support it, and neither
2893
+ // has a shorthand here yet. Leave the predicate empty so effort is dropped
2894
+ // for every currently-shipped xAI shorthand.
2895
+ isReasoningModel: () => false
2824
2896
  });
2825
2897
  var xai = {
2826
2898
  "xai.chat.v1": xaiChatV1,
@@ -2828,7 +2900,8 @@ var xai = {
2828
2900
  "xai.grok-3": withDefaultModel(xaiChatV1, "grok-3"),
2829
2901
  "xai.grok-3-mini": withDefaultModel(xaiChatV1, "grok-3-mini"),
2830
2902
  "xai.grok-4": withDefaultModel(xaiChatV1, "grok-4"),
2831
- "xai.grok-4-fast": withDefaultModel(xaiChatV1, "grok-4-fast-non-reasoning")
2903
+ "xai.grok-4-fast": withDefaultModel(xaiChatV1, "grok-4-fast-non-reasoning"),
2904
+ "xai.grok-4-1-fast": withDefaultModel(xaiChatV1, "grok-4-1-fast-non-reasoning")
2832
2905
  };
2833
2906
 
2834
2907
  // src/llm/output/_utils/combineJsonl.ts
@@ -2935,7 +3008,11 @@ var ollama = {
2935
3008
  "ollama.llama3.3": withDefaultModel(ollamaChatV1, "llama3.3"),
2936
3009
  "ollama.llama3.2": withDefaultModel(ollamaChatV1, "llama3.2"),
2937
3010
  "ollama.llama3.1": withDefaultModel(ollamaChatV1, "llama3.1"),
2938
- "ollama.qwq": withDefaultModel(ollamaChatV1, "qwq")
3011
+ "ollama.qwq": withDefaultModel(ollamaChatV1, "qwq"),
3012
+ "ollama.gemma3": withDefaultModel(ollamaChatV1, "gemma3"),
3013
+ "ollama.mistral": withDefaultModel(ollamaChatV1, "mistral"),
3014
+ "ollama.qwen2.5": withDefaultModel(ollamaChatV1, "qwen2.5"),
3015
+ "ollama.qwen3": withDefaultModel(ollamaChatV1, "qwen3")
2939
3016
  };
2940
3017
 
2941
3018
  // src/llm/config/google/promptSanitizeMessageCallback.ts
@@ -3152,14 +3229,6 @@ var googleGeminiChatV1 = {
3152
3229
  };
3153
3230
  var google = {
3154
3231
  "google.chat.v1": googleGeminiChatV1,
3155
- "google.gemini-2.0-flash": withDefaultModel(
3156
- googleGeminiChatV1,
3157
- "gemini-2.0-flash"
3158
- ),
3159
- "google.gemini-2.0-flash-lite": withDefaultModel(
3160
- googleGeminiChatV1,
3161
- "gemini-2.0-flash-lite"
3162
- ),
3163
3232
  "google.gemini-2.5-flash": withDefaultModel(
3164
3233
  googleGeminiChatV1,
3165
3234
  "gemini-2.5-flash"
@@ -3168,13 +3237,22 @@ var google = {
3168
3237
  googleGeminiChatV1,
3169
3238
  "gemini-2.5-flash-lite"
3170
3239
  ),
3171
- "google.gemini-1.5-pro": withDefaultModel(
3172
- googleGeminiChatV1,
3173
- "gemini-1.5-pro"
3174
- ),
3175
3240
  "google.gemini-2.5-pro": withDefaultModel(
3176
3241
  googleGeminiChatV1,
3177
3242
  "gemini-2.5-pro"
3243
+ ),
3244
+ // Deprecated
3245
+ "google.gemini-2.0-flash": withDefaultModel(
3246
+ googleGeminiChatV1,
3247
+ "gemini-2.0-flash"
3248
+ ),
3249
+ "google.gemini-2.0-flash-lite": withDefaultModel(
3250
+ googleGeminiChatV1,
3251
+ "gemini-2.0-flash-lite"
3252
+ ),
3253
+ "google.gemini-1.5-pro": withDefaultModel(
3254
+ googleGeminiChatV1,
3255
+ "gemini-1.5-pro"
3178
3256
  )
3179
3257
  };
3180
3258
 
@@ -3187,7 +3265,9 @@ var deepseekChatV1 = createOpenAiCompatibleConfiguration({
3187
3265
  });
3188
3266
  var deepseek = {
3189
3267
  "deepseek.chat.v1": deepseekChatV1,
3190
- "deepseek.chat": withDefaultModel(deepseekChatV1, "deepseek-chat")
3268
+ "deepseek.chat": withDefaultModel(deepseekChatV1, "deepseek-chat"),
3269
+ "deepseek.v4-flash": withDefaultModel(deepseekChatV1, "deepseek-v4-flash"),
3270
+ "deepseek.v4-pro": withDefaultModel(deepseekChatV1, "deepseek-v4-pro")
3191
3271
  };
3192
3272
 
3193
3273
  // src/llm/config.ts
@@ -3302,12 +3382,19 @@ async function apiRequest(url, options) {
3302
3382
  const response = await fetch(url, finalOptions);
3303
3383
  if (!response.ok) {
3304
3384
  let message = `HTTP error. Status: ${response.status}. Error Message: ${response?.statusText || "Unknown error."}`;
3305
- if (url.startsWith("https://api.openai.com/")) {
3306
- try {
3307
- const body = await response.json();
3308
- message = `HTTP error. Status Code: ${response.status}. Error Message: ${body?.error?.message || "No further details provided."}`;
3309
- } catch (error) {
3385
+ try {
3386
+ const text = await response.text();
3387
+ if (text) {
3388
+ let detail = text;
3389
+ try {
3390
+ const body = JSON.parse(text);
3391
+ detail = body?.error?.message || body?.error || body?.message || text;
3392
+ if (typeof detail !== "string") detail = JSON.stringify(detail);
3393
+ } catch {
3394
+ }
3395
+ message = `HTTP error. Status Code: ${response.status}. Error Message: ${detail}`;
3310
3396
  }
3397
+ } catch {
3311
3398
  }
3312
3399
  throw new Error(message);
3313
3400
  }
@@ -4139,6 +4226,11 @@ var BasePrompt = class {
4139
4226
  return promptValue;
4140
4227
  }
4141
4228
  getReplacements(values) {
4229
+ if (values === void 0 || values === null) {
4230
+ throw new Error(
4231
+ "format() requires an input object. Did you forget to pass arguments?"
4232
+ );
4233
+ }
4142
4234
  const { input = "", ...restOfValues } = values;
4143
4235
  const replacements = Object.assign(
4144
4236
  {},
@@ -4151,11 +4243,11 @@ var BasePrompt = class {
4151
4243
  return replacements;
4152
4244
  }
4153
4245
  /**
4154
- * validate description
4155
- * @return {boolean} Returns false if the template is not valid.
4246
+ * Validates the prompt structure.
4247
+ * @return {boolean} Returns false if the prompt has no messages defined.
4156
4248
  */
4157
4249
  validate() {
4158
- return true;
4250
+ return this.messages.length > 0;
4159
4251
  }
4160
4252
  };
4161
4253
 
@@ -4752,14 +4844,6 @@ var ChatPrompt = class extends BasePrompt {
4752
4844
  }
4753
4845
  return messagesOut;
4754
4846
  }
4755
- /**
4756
- * validate Ensures there are not unresolved tokens in prompt.
4757
- * @TODO Make this work!
4758
- * @return Returns false if the template is not valid.
4759
- */
4760
- validate() {
4761
- return true;
4762
- }
4763
4847
  };
4764
4848
 
4765
4849
  // src/prompt/_functions.ts
@@ -4786,10 +4870,12 @@ var BaseStateItem = class {
4786
4870
  this.initialValue = initialValue;
4787
4871
  }
4788
4872
  setValue(value) {
4789
- assert(
4790
- typeof value === typeof this.value,
4791
- `Invalid value type. Expected ${typeof this.value}, received ${typeof value}`
4792
- );
4873
+ if (this.value !== void 0 && this.value !== null) {
4874
+ assert(
4875
+ typeof value === typeof this.value,
4876
+ `Invalid value type. Expected ${typeof this.value}, received ${typeof value}`
4877
+ );
4878
+ }
4793
4879
  this.value = value;
4794
4880
  }
4795
4881
  getKey() {
@@ -4925,11 +5011,42 @@ var Dialogue = class extends BaseStateItem {
4925
5011
  return this;
4926
5012
  }
4927
5013
  setMessageTurn(userMessage, assistantMessage, systemMessage = "") {
5014
+ this.setSystemMessage(systemMessage);
4928
5015
  this.setUserMessage(userMessage);
4929
5016
  this.setAssistantMessage(assistantMessage);
4930
- this.setSystemMessage(systemMessage);
4931
5017
  return this;
4932
5018
  }
5019
+ /**
5020
+ * Aliases using `add*` naming to match ChatPrompt's API.
5021
+ * These delegate to the corresponding `set*` methods.
5022
+ */
5023
+ addUserMessage(content, name) {
5024
+ return this.setUserMessage(content, name);
5025
+ }
5026
+ addAssistantMessage(content) {
5027
+ return this.setAssistantMessage(content);
5028
+ }
5029
+ addSystemMessage(content) {
5030
+ return this.setSystemMessage(content);
5031
+ }
5032
+ addToolMessage(content, name, id) {
5033
+ return this.setToolMessage(content, name, id);
5034
+ }
5035
+ addToolCallMessage(input) {
5036
+ return this.setToolCallMessage(input);
5037
+ }
5038
+ addFunctionMessage(content, name, id) {
5039
+ return this.setFunctionMessage(content, name, id);
5040
+ }
5041
+ addFunctionCallMessage(input) {
5042
+ return this.setFunctionCallMessage(input);
5043
+ }
5044
+ addMessageTurn(userMessage, assistantMessage, systemMessage = "") {
5045
+ return this.setMessageTurn(userMessage, assistantMessage, systemMessage);
5046
+ }
5047
+ addHistory(messages) {
5048
+ return this.setHistory(messages);
5049
+ }
4933
5050
  setHistory(messages) {
4934
5051
  for (const message of messages) {
4935
5052
  switch (message?.role) {