llm-exe 2.3.1 → 2.3.2

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
@@ -59,6 +59,7 @@ __export(index_exports, {
59
59
  createEmbedding: () => createEmbedding,
60
60
  createLlmExecutor: () => createLlmExecutor,
61
61
  createLlmFunctionExecutor: () => createLlmFunctionExecutor,
62
+ createOpenAiCompatibleConfiguration: () => createOpenAiCompatibleConfiguration,
62
63
  createParser: () => createParser,
63
64
  createPrompt: () => createPrompt,
64
65
  createState: () => createState,
@@ -69,6 +70,7 @@ __export(index_exports, {
69
70
  registerPartials: () => registerPartials,
70
71
  useExecutors: () => useExecutors,
71
72
  useLlm: () => useLlm,
73
+ useLlmConfiguration: () => useLlmConfiguration,
72
74
  utils: () => utils_exports
73
75
  });
74
76
  module.exports = __toCommonJS(index_exports);
@@ -186,6 +188,10 @@ var BaseExecutor = class {
186
188
  */
187
189
  __publicField(this, "hooks");
188
190
  __publicField(this, "allowedHooks", [hookOnComplete, hookOnError, hookOnSuccess]);
191
+ /**
192
+ * @property maxHooksPerEvent - Maximum number of hooks allowed per event
193
+ */
194
+ __publicField(this, "maxHooksPerEvent", 100);
189
195
  this.id = (0, import_uuid.v4)();
190
196
  this.type = type;
191
197
  this.name = name;
@@ -291,6 +297,11 @@ var BaseExecutor = class {
291
297
  const _hooks = Array.isArray(hookInput) ? hookInput : [hookInput];
292
298
  for (const hook of _hooks) {
293
299
  if (hook && typeof hook === "function" && !this.hooks[hookKey].find((h) => h === hook)) {
300
+ if (this.hooks[hookKey].length >= this.maxHooksPerEvent) {
301
+ throw new Error(
302
+ `Maximum number of hooks (${this.maxHooksPerEvent}) reached for event "${String(hookKey)}". Consider removing unused hooks or increasing the limit.`
303
+ );
304
+ }
294
305
  this.hooks[hookKey].push(hook);
295
306
  }
296
307
  }
@@ -318,10 +329,18 @@ var BaseExecutor = class {
318
329
  }
319
330
  once(eventName, fn) {
320
331
  if (typeof fn !== "function") return this;
332
+ if (this.hooks[eventName] && this.hooks[eventName].length >= this.maxHooksPerEvent) {
333
+ throw new Error(
334
+ `Maximum number of hooks (${this.maxHooksPerEvent}) reached for event "${String(eventName)}". Consider removing unused hooks or increasing the limit.`
335
+ );
336
+ }
321
337
  const onceWrapper = (...args) => {
322
338
  fn(...args);
323
339
  this.off(eventName, onceWrapper);
324
340
  };
341
+ if (!this.hooks[eventName]) {
342
+ this.hooks[eventName] = [];
343
+ }
325
344
  this.hooks[eventName].push(onceWrapper);
326
345
  return this;
327
346
  }
@@ -332,6 +351,40 @@ var BaseExecutor = class {
332
351
  getTraceId() {
333
352
  return this.traceId;
334
353
  }
354
+ /**
355
+ * Clear all hooks for a specific event or all events
356
+ * Useful for preventing memory leaks in long-running processes
357
+ * @param eventName - The event name to clear hooks for
358
+ */
359
+ clearHooks(eventName) {
360
+ if (eventName) {
361
+ if (this.hooks[eventName]) {
362
+ this.hooks[eventName] = [];
363
+ }
364
+ } else {
365
+ for (const key of this.allowedHooks) {
366
+ if (this.hooks[key]) {
367
+ this.hooks[key] = [];
368
+ }
369
+ }
370
+ }
371
+ return this;
372
+ }
373
+ /**
374
+ * Get the count of hooks for monitoring memory usage
375
+ * @param eventName - Optional event name to get count for
376
+ * @returns Hook count for specific event or all events
377
+ */
378
+ getHookCount(eventName) {
379
+ if (eventName) {
380
+ return this.hooks[eventName]?.length || 0;
381
+ }
382
+ const counts = {};
383
+ for (const key of this.allowedHooks) {
384
+ counts[key] = this.hooks[key]?.length || 0;
385
+ }
386
+ return counts;
387
+ }
335
388
  };
336
389
 
337
390
  // src/utils/modules/inferFunctionName.ts
@@ -2118,6 +2171,63 @@ function getEnvironmentVariable(name) {
2118
2171
  }
2119
2172
  }
2120
2173
 
2174
+ // src/llm/output/_util.ts
2175
+ function formatOptions(response, handler) {
2176
+ const out = [];
2177
+ for (const item of response) {
2178
+ const result = handler(item);
2179
+ if (result) {
2180
+ out.push([result]);
2181
+ }
2182
+ }
2183
+ return out;
2184
+ }
2185
+
2186
+ // src/llm/output/openai.ts
2187
+ function formatResult(result) {
2188
+ const out = [];
2189
+ if (typeof result?.message?.content === "string") {
2190
+ out.push({
2191
+ type: "text",
2192
+ text: result.message.content
2193
+ });
2194
+ }
2195
+ if (result?.message?.tool_calls) {
2196
+ for (const call of result.message.tool_calls) {
2197
+ out.push({
2198
+ functionId: call.id,
2199
+ type: "function_use",
2200
+ name: call.function.name,
2201
+ input: maybeParseJSON(call.function.arguments)
2202
+ });
2203
+ }
2204
+ }
2205
+ return out;
2206
+ }
2207
+ function OutputOpenAIChat(result, _config) {
2208
+ const id = result.id;
2209
+ const name = result.model || _config?.options.model?.default || "openai.unknown";
2210
+ const created = result.created;
2211
+ const [_content, ..._options] = result?.choices || [];
2212
+ const stopReason = _content?.finish_reason;
2213
+ const content = formatResult(_content);
2214
+ const options = formatOptions(_options, formatResult);
2215
+ const usage = {
2216
+ output_tokens: result?.usage?.completion_tokens,
2217
+ input_tokens: result?.usage?.prompt_tokens,
2218
+ total_tokens: result?.usage?.total_tokens
2219
+ };
2220
+ return {
2221
+ id,
2222
+ name,
2223
+ created,
2224
+ usage,
2225
+ stopReason,
2226
+ content,
2227
+ options
2228
+ };
2229
+ }
2230
+
2121
2231
  // src/llm/config/openai/promptSanitizeMessageCallback.ts
2122
2232
  function openaiPromptMessageCallback(_message) {
2123
2233
  let message = { ..._message };
@@ -2151,38 +2261,127 @@ function openaiPromptSanitize(_messages, _inputBodyObj, _outputObj) {
2151
2261
  return _messages.map(openaiPromptMessageCallback);
2152
2262
  }
2153
2263
 
2154
- // src/llm/config/openai/index.ts
2155
- var openAiChatV1 = {
2156
- key: "openai.chat.v1",
2157
- provider: "openai.chat",
2158
- endpoint: `https://api.openai.com/v1/chat/completions`,
2159
- options: {
2160
- prompt: {},
2161
- topP: {},
2162
- useJson: {},
2163
- openAiApiKey: {
2164
- default: getEnvironmentVariable("OPENAI_API_KEY")
2264
+ // src/llm/output/_utils/cleanJsonSchemaFor.ts
2265
+ var providerFieldExclusions = {
2266
+ "openai.chat": ["default"],
2267
+ // fields to exclude for openai.chat, xai, deepseek
2268
+ "anthropic.chat": [],
2269
+ "google.chat": ["additionalProperties"]
2270
+ };
2271
+ function cleanJsonSchemaFor(schema = {}, provider) {
2272
+ const clone = deepClone(schema);
2273
+ if (Object.keys(clone).length === 0) {
2274
+ return {
2275
+ type: "object",
2276
+ properties: {},
2277
+ required: []
2278
+ };
2279
+ }
2280
+ const exclusions = providerFieldExclusions[provider] || [];
2281
+ function removeDisallowedFields(obj) {
2282
+ if (Array.isArray(obj)) {
2283
+ return obj.map(removeDisallowedFields);
2284
+ } else if (typeof obj === "object" && obj !== null) {
2285
+ return Object.keys(obj).reduce((acc, key) => {
2286
+ if (!exclusions.includes(key)) {
2287
+ acc[key] = removeDisallowedFields(obj[key]);
2288
+ }
2289
+ return acc;
2290
+ }, {});
2165
2291
  }
2166
- },
2167
- method: "POST",
2168
- headers: `{"Authorization":"Bearer {{openAiApiKey}}", "Content-Type": "application/json" }`,
2169
- mapBody: {
2170
- prompt: {
2171
- key: "messages",
2172
- sanitize: openaiPromptSanitize
2292
+ return obj;
2293
+ }
2294
+ return removeDisallowedFields(clone);
2295
+ }
2296
+
2297
+ // src/llm/config/openai/compatible.ts
2298
+ function createOpenAiCompatibleConfiguration(overrides) {
2299
+ const [apiKeyPropertyKey, apiKeyPropertyValue] = overrides.apiKeyMapping;
2300
+ const config = {
2301
+ key: overrides.key,
2302
+ provider: overrides.provider,
2303
+ endpoint: overrides.endpoint,
2304
+ options: {
2305
+ prompt: {},
2306
+ effort: {},
2307
+ topP: {},
2308
+ useJson: {},
2309
+ [apiKeyPropertyKey]: {
2310
+ default: getEnvironmentVariable(apiKeyPropertyValue)
2311
+ }
2173
2312
  },
2174
- model: {
2175
- key: "model"
2313
+ method: "POST",
2314
+ headers: `{"Authorization":"Bearer {{${apiKeyPropertyKey}}}", "Content-Type": "application/json" }`,
2315
+ mapBody: {
2316
+ prompt: {
2317
+ key: "messages",
2318
+ transform: openaiPromptSanitize
2319
+ },
2320
+ model: {
2321
+ key: "model"
2322
+ },
2323
+ topP: {
2324
+ key: "top_p"
2325
+ },
2326
+ useJson: {
2327
+ key: "response_format.type",
2328
+ transform: (v) => v ? "json_object" : "text"
2329
+ },
2330
+ effort: {
2331
+ key: "reasoning_effort",
2332
+ transform: (v, _s) => {
2333
+ if (
2334
+ // only supported reasoning models
2335
+ ["gpt-5"].includes(_s.model) && typeof v === "string" && ["minimal", "low", "medium", "high"].includes(v)
2336
+ ) {
2337
+ return v;
2338
+ }
2339
+ return void 0;
2340
+ }
2341
+ }
2176
2342
  },
2177
- topP: {
2178
- key: "top_p"
2343
+ mapOptions: {
2344
+ jsonSchema: (schema, options, currentInput) => ({
2345
+ response_format: {
2346
+ ...currentInput?.response_format || {},
2347
+ type: "json_schema",
2348
+ json_schema: {
2349
+ name: "output",
2350
+ strict: !!options?.functionCallStrictInput,
2351
+ schema: cleanJsonSchemaFor(schema, "openai.chat")
2352
+ }
2353
+ }
2354
+ }),
2355
+ functionCall: (call) => {
2356
+ if (call === "any") return { tool_choice: "required" };
2357
+ if (call === "none") return { tool_choice: "none" };
2358
+ if (call === "auto") return { tool_choice: "auto" };
2359
+ return { tool_choice: call };
2360
+ },
2361
+ functions: (functions, options) => ({
2362
+ tools: functions.map((f) => ({
2363
+ type: "function",
2364
+ function: {
2365
+ name: f.name,
2366
+ description: f.description,
2367
+ parameters: cleanJsonSchemaFor(f.parameters, "openai.chat"),
2368
+ strict: !!options?.functionCallStrictInput
2369
+ }
2370
+ }))
2371
+ })
2179
2372
  },
2180
- useJson: {
2181
- key: "response_format.type",
2182
- sanitize: (v) => v ? "json_object" : "text"
2183
- }
2184
- }
2185
- };
2373
+ transformResponse: overrides.transformResponse ?? OutputOpenAIChat
2374
+ };
2375
+ return config;
2376
+ }
2377
+
2378
+ // src/llm/config/openai/index.ts
2379
+ var openAiChatV1 = createOpenAiCompatibleConfiguration({
2380
+ key: "openai.chat.v1",
2381
+ provider: "openai.chat",
2382
+ endpoint: `https://api.openai.com/v1/chat/completions`,
2383
+ apiKeyMapping: ["openAiApiKey", "OPENAI_API_KEY"]
2384
+ });
2186
2385
  var openAiChatMockV1 = {
2187
2386
  key: "openai.chat-mock.v1",
2188
2387
  provider: "openai.chat-mock",
@@ -2209,9 +2408,10 @@ var openAiChatMockV1 = {
2209
2408
  },
2210
2409
  useJson: {
2211
2410
  key: "response_format.type",
2212
- sanitize: (v) => v ? "json_object" : "text"
2411
+ transform: (v) => v ? "json_object" : "text"
2213
2412
  }
2214
- }
2413
+ },
2414
+ transformResponse: OutputOpenAIChat
2215
2415
  };
2216
2416
  var openai = {
2217
2417
  "openai.chat.v1": openAiChatV1,
@@ -2289,8 +2489,75 @@ function anthropicPromptSanitize(_messages, _inputBodyObj, _outputObj) {
2289
2489
  ].map(anthropicPromptMessageCallback);
2290
2490
  }
2291
2491
 
2492
+ // src/llm/output/claude.ts
2493
+ function formatResult2(response) {
2494
+ const content = response?.content || [];
2495
+ const out = [];
2496
+ for (let i = 0; i < content.length; i++) {
2497
+ const result = content[i];
2498
+ if (result.type === "text") {
2499
+ out.push({
2500
+ type: "text",
2501
+ text: result.text
2502
+ });
2503
+ } else if (result.type === "tool_use") {
2504
+ out.push({
2505
+ functionId: result.id,
2506
+ type: "function_use",
2507
+ name: result.name,
2508
+ input: result.input
2509
+ });
2510
+ }
2511
+ }
2512
+ return out;
2513
+ }
2514
+ function OutputAnthropicClaude3Chat(result, _config) {
2515
+ const id = result.id;
2516
+ const name = result.model || _config?.options.model?.default || "anthropic.unknown";
2517
+ const stopReason = result.stop_reason;
2518
+ const content = formatResult2(result);
2519
+ const usage = {
2520
+ input_tokens: result?.usage?.input_tokens,
2521
+ output_tokens: result?.usage?.output_tokens,
2522
+ total_tokens: result?.usage?.input_tokens + result?.usage?.output_tokens
2523
+ };
2524
+ return {
2525
+ id,
2526
+ name,
2527
+ created: Date.now(),
2528
+ usage,
2529
+ stopReason,
2530
+ content
2531
+ };
2532
+ }
2533
+
2534
+ // src/llm/output/llama.ts
2535
+ function OutputMetaLlama3Chat(result, _config) {
2536
+ const id = (0, import_uuid.v4)();
2537
+ const name = _config?.options?.model?.default || "meta";
2538
+ const created = (/* @__PURE__ */ new Date()).getTime();
2539
+ const stopReason = result.stop_reason;
2540
+ const content = [
2541
+ { type: "text", text: result.generation }
2542
+ ];
2543
+ const usage = {
2544
+ output_tokens: result?.generation_token_count,
2545
+ input_tokens: result?.prompt_token_count,
2546
+ total_tokens: result?.generation_token_count + result?.prompt_token_count
2547
+ };
2548
+ return {
2549
+ id,
2550
+ name,
2551
+ created,
2552
+ usage,
2553
+ stopReason,
2554
+ content,
2555
+ options: []
2556
+ };
2557
+ }
2558
+
2292
2559
  // src/llm/config/bedrock/index.ts
2293
- var ANTORPIC_BEDROCK_VERSION = "bedrock-2023-05-31";
2560
+ var ANTHROPIC_BEDROCK_VERSION = "bedrock-2023-05-31";
2294
2561
  var amazonAnthropicChatV1 = {
2295
2562
  key: "amazon:anthropic.chat.v1",
2296
2563
  provider: "amazon:anthropic.chat",
@@ -2311,7 +2578,7 @@ var amazonAnthropicChatV1 = {
2311
2578
  mapBody: {
2312
2579
  prompt: {
2313
2580
  key: "messages",
2314
- sanitize: anthropicPromptSanitize
2581
+ transform: anthropicPromptSanitize
2315
2582
  },
2316
2583
  topP: {
2317
2584
  key: "top_p"
@@ -2322,9 +2589,26 @@ var amazonAnthropicChatV1 = {
2322
2589
  },
2323
2590
  anthropic_version: {
2324
2591
  key: "anthropic_version",
2325
- default: ANTORPIC_BEDROCK_VERSION
2592
+ default: ANTHROPIC_BEDROCK_VERSION
2326
2593
  }
2327
- }
2594
+ },
2595
+ mapOptions: {
2596
+ functionCall: (call, _options) => {
2597
+ if (call === "none") return { _clearFunctions: true };
2598
+ if (call === "auto" || call === "any") {
2599
+ return { tool_choice: { type: call } };
2600
+ }
2601
+ return { tool_choice: call };
2602
+ },
2603
+ functions: (functions) => ({
2604
+ tools: functions.map((f) => ({
2605
+ name: f.name,
2606
+ description: f.description,
2607
+ input_schema: cleanJsonSchemaFor(f.parameters, "anthropic.chat")
2608
+ }))
2609
+ })
2610
+ },
2611
+ transformResponse: OutputAnthropicClaude3Chat
2328
2612
  };
2329
2613
  var amazonMetaChatV1 = {
2330
2614
  key: "amazon:meta.chat.v1",
@@ -2346,7 +2630,7 @@ var amazonMetaChatV1 = {
2346
2630
  mapBody: {
2347
2631
  prompt: {
2348
2632
  key: "prompt",
2349
- sanitize: (messages) => {
2633
+ transform: (messages) => {
2350
2634
  if (typeof messages === "string") {
2351
2635
  return messages;
2352
2636
  } else {
@@ -2366,7 +2650,8 @@ var amazonMetaChatV1 = {
2366
2650
  key: "max_gen_len",
2367
2651
  default: 2048
2368
2652
  }
2369
- }
2653
+ },
2654
+ transformResponse: OutputMetaLlama3Chat
2370
2655
  };
2371
2656
  var bedrock = {
2372
2657
  "amazon:anthropic.chat.v1": amazonAnthropicChatV1,
@@ -2405,24 +2690,65 @@ var anthropicChatV1 = {
2405
2690
  },
2406
2691
  prompt: {
2407
2692
  key: "messages",
2408
- sanitize: anthropicPromptSanitize
2693
+ transform: anthropicPromptSanitize
2694
+ },
2695
+ temperature: {
2696
+ key: "temperature"
2697
+ },
2698
+ topP: {
2699
+ key: "top_p"
2700
+ },
2701
+ topK: {
2702
+ key: "top_k"
2703
+ },
2704
+ stopSequences: {
2705
+ key: "stop_sequences"
2706
+ },
2707
+ stream: {
2708
+ key: "stream"
2709
+ },
2710
+ metadata: {
2711
+ key: "metadata"
2712
+ },
2713
+ serviceTier: {
2714
+ key: "service_tier"
2715
+ // Map camelCase to snake_case
2409
2716
  }
2410
- }
2411
- };
2412
- var anthropic = {
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(
2717
+ },
2718
+ mapOptions: {
2719
+ functionCall: (call, _options) => {
2720
+ if (call === "none") return { _clearFunctions: true };
2721
+ if (call === "auto" || call === "any") {
2722
+ return { tool_choice: { type: call } };
2723
+ }
2724
+ return { tool_choice: call };
2725
+ },
2726
+ functions: (functions) => ({
2727
+ tools: functions.map((f) => ({
2728
+ name: f.name,
2729
+ description: f.description,
2730
+ input_schema: cleanJsonSchemaFor(f.parameters, "anthropic.chat")
2731
+ }))
2732
+ })
2733
+ },
2734
+ transformResponse: OutputAnthropicClaude3Chat
2735
+ };
2736
+ var anthropic = {
2737
+ "anthropic.chat.v1": anthropicChatV1,
2738
+ // Claude 4 models (latest generation)
2739
+ "anthropic.claude-sonnet-4": withDefaultModel(
2419
2740
  anthropicChatV1,
2420
2741
  "claude-sonnet-4-0"
2421
2742
  ),
2743
+ "anthropic.claude-opus-4": withDefaultModel(
2744
+ anthropicChatV1,
2745
+ "claude-opus-4-0"
2746
+ ),
2422
2747
  "anthropic.claude-3-7-sonnet": withDefaultModel(
2423
2748
  anthropicChatV1,
2424
- "claude-3-7-sonnet-latest"
2749
+ "claude-3-7-sonnet-20250219"
2425
2750
  ),
2751
+ // Claude 3.5 models
2426
2752
  "anthropic.claude-3-5-sonnet": withDefaultModel(
2427
2753
  anthropicChatV1,
2428
2754
  "claude-3-5-sonnet-latest"
@@ -2434,42 +2760,21 @@ var anthropic = {
2434
2760
  // Deprecated
2435
2761
  "anthropic.claude-3-opus": withDefaultModel(
2436
2762
  anthropicChatV1,
2437
- "claude-3-opus-latest"
2763
+ "claude-3-opus-20240229"
2764
+ ),
2765
+ "anthropic.claude-3-haiku": withDefaultModel(
2766
+ anthropicChatV1,
2767
+ "claude-3-haiku-20240307"
2438
2768
  )
2439
2769
  };
2440
2770
 
2441
2771
  // src/llm/config/x/index.ts
2442
- var xaiChatV1 = {
2772
+ var xaiChatV1 = createOpenAiCompatibleConfiguration({
2443
2773
  key: "xai.chat.v1",
2444
2774
  provider: "xai.chat",
2445
2775
  endpoint: `https://api.x.ai/v1/chat/completions`,
2446
- options: {
2447
- prompt: {},
2448
- topP: {},
2449
- useJson: {},
2450
- xAiApiKey: {
2451
- default: getEnvironmentVariable("XAI_API_KEY")
2452
- }
2453
- },
2454
- method: "POST",
2455
- headers: `{"Authorization":"Bearer {{xAiApiKey}}", "Content-Type": "application/json" }`,
2456
- mapBody: {
2457
- prompt: {
2458
- key: "messages",
2459
- sanitize: openaiPromptSanitize
2460
- },
2461
- model: {
2462
- key: "model"
2463
- },
2464
- topP: {
2465
- key: "top_p"
2466
- },
2467
- useJson: {
2468
- key: "response_format.type",
2469
- sanitize: (v) => v ? "json_object" : "text"
2470
- }
2471
- }
2472
- };
2776
+ apiKeyMapping: ["xAiApiKey", "XAI_API_KEY"]
2777
+ });
2473
2778
  var xai = {
2474
2779
  "xai.chat.v1": xaiChatV1,
2475
2780
  "xai.grok-2": withDefaultModel(xaiChatV1, "grok-2-latest"),
@@ -2477,6 +2782,78 @@ var xai = {
2477
2782
  "xai.grok-4": withDefaultModel(xaiChatV1, "grok-4")
2478
2783
  };
2479
2784
 
2785
+ // src/llm/output/_utils/combineJsonl.ts
2786
+ function combineJsonl(jsonl) {
2787
+ const lines = jsonl.trim().split("\n").map((line) => line.trim()).filter((line) => line.length > 0).map((line) => {
2788
+ try {
2789
+ return JSON.parse(line);
2790
+ } catch (e) {
2791
+ throw new Error(`Invalid JSON: ${line}`);
2792
+ }
2793
+ });
2794
+ if (lines.length === 0) {
2795
+ throw new Error("No JSON lines provided.");
2796
+ }
2797
+ lines.sort(
2798
+ (a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime()
2799
+ );
2800
+ let combinedContent = lines.map((line) => line?.message?.content ?? "").join("");
2801
+ combinedContent = combinedContent.replace(/\\u003c/g, "<").replace(/\\u003e/g, ">");
2802
+ const finalLine = lines.find((line) => line.done === true);
2803
+ if (!finalLine) {
2804
+ throw new Error("No line found where done = true.");
2805
+ }
2806
+ const result = {
2807
+ model: finalLine.model,
2808
+ created_at: finalLine.created_at,
2809
+ message: {
2810
+ role: finalLine?.message?.role || "assistant",
2811
+ content: combinedContent
2812
+ },
2813
+ done_reason: finalLine.done_reason,
2814
+ done: finalLine.done,
2815
+ total_duration: finalLine.total_duration,
2816
+ load_duration: finalLine.load_duration,
2817
+ prompt_eval_count: finalLine.prompt_eval_count,
2818
+ prompt_eval_duration: finalLine.prompt_eval_duration,
2819
+ eval_count: finalLine.eval_count,
2820
+ eval_duration: finalLine.eval_duration
2821
+ };
2822
+ const content = {
2823
+ type: "text",
2824
+ text: combinedContent
2825
+ };
2826
+ return {
2827
+ lines,
2828
+ result,
2829
+ content
2830
+ };
2831
+ }
2832
+
2833
+ // src/llm/output/ollama.ts
2834
+ function OutputOllamaChat(result, _config) {
2835
+ const combined = combineJsonl(result);
2836
+ const id = `${combined.result.model}.${combined.result.created_at}`;
2837
+ const name = combined.result.model || _config?.options.model?.default || "ollama.unknown";
2838
+ const created = (/* @__PURE__ */ new Date(`${combined.result.created_at}`)).getTime();
2839
+ const stopReason = `${combined?.result?.done_reason || "stop"}`;
2840
+ const content = [combined.content];
2841
+ const usage = {
2842
+ output_tokens: 0,
2843
+ input_tokens: 0,
2844
+ total_tokens: 0
2845
+ };
2846
+ return {
2847
+ id,
2848
+ name,
2849
+ created,
2850
+ usage,
2851
+ stopReason,
2852
+ content,
2853
+ options: []
2854
+ };
2855
+ }
2856
+
2480
2857
  // src/llm/config/ollama/index.ts
2481
2858
  var ollamaChatV1 = {
2482
2859
  key: "ollama.chat.v1",
@@ -2490,7 +2867,7 @@ var ollamaChatV1 = {
2490
2867
  mapBody: {
2491
2868
  prompt: {
2492
2869
  key: "messages",
2493
- sanitize: (v) => {
2870
+ transform: (v) => {
2494
2871
  if (typeof v === "string") {
2495
2872
  return [{ role: "user", content: v }];
2496
2873
  }
@@ -2500,7 +2877,8 @@ var ollamaChatV1 = {
2500
2877
  model: {
2501
2878
  key: "model"
2502
2879
  }
2503
- }
2880
+ },
2881
+ transformResponse: OutputOllamaChat
2504
2882
  };
2505
2883
  var ollama = {
2506
2884
  "ollama.chat.v1": ollamaChatV1,
@@ -2542,490 +2920,60 @@ function googleGeminiPromptMessageCallback(_message) {
2542
2920
  const toolsArr = Array.isArray(function_call) ? function_call : [function_call];
2543
2921
  role = "model";
2544
2922
  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
- }
2557
- return {
2558
- role,
2559
- parts
2560
- };
2561
- }
2562
-
2563
- // src/llm/config/google/promptSanitize.ts
2564
- function googleGeminiPromptSanitize(_messages, _inputBodyObj, _outputObj) {
2565
- if (typeof _messages === "string") {
2566
- return [{ role: "user", parts: [{ text: _messages }] }];
2567
- }
2568
- if (Array.isArray(_messages)) {
2569
- if (_messages.length === 0) {
2570
- throw new Error("Empty messages array");
2571
- }
2572
- if (_messages.length === 1 && _messages[0].role === "system") {
2573
- return [{ role: "user", parts: [{ text: _messages[0].content }] }];
2574
- }
2575
- const hasSystemInstruction = _messages.some(
2576
- (message) => message.role === "system"
2577
- );
2578
- if (hasSystemInstruction) {
2579
- const theSystemInstructions = _messages.filter(
2580
- (message) => message.role === "system"
2581
- );
2582
- const withoutSystemInstructions = _messages.filter(
2583
- (message) => message.role !== "system"
2584
- );
2585
- _outputObj.system_instruction = {
2586
- parts: theSystemInstructions.map((message) => ({
2587
- text: message.content
2588
- }))
2589
- };
2590
- return withoutSystemInstructions.map(googleGeminiPromptMessageCallback);
2591
- }
2592
- return _messages.map(googleGeminiPromptMessageCallback);
2593
- }
2594
- throw new Error("Invalid messages format");
2595
- }
2596
-
2597
- // src/llm/config/google/index.ts
2598
- var googleGeminiChatV1 = {
2599
- key: "google.chat.v1",
2600
- provider: "google.chat",
2601
- endpoint: `https://generativelanguage.googleapis.com/v1beta/models/{{model}}:generateContent?key={{geminiApiKey}}`,
2602
- options: {
2603
- prompt: {},
2604
- // topP: {},
2605
- geminiApiKey: {
2606
- default: getEnvironmentVariable("GEMINI_API_KEY")
2607
- }
2608
- },
2609
- method: "POST",
2610
- headers: `{"Content-Type": "application/json" }`,
2611
- mapBody: {
2612
- prompt: {
2613
- key: "contents",
2614
- sanitize: googleGeminiPromptSanitize
2615
- }
2616
- // topP: {
2617
- // key: "top_p",
2618
- // }
2619
- }
2620
- };
2621
- var google = {
2622
- "google.chat.v1": googleGeminiChatV1,
2623
- "google.gemini-2.0-flash": withDefaultModel(
2624
- googleGeminiChatV1,
2625
- "gemini-2.0-flash"
2626
- ),
2627
- "google.gemini-2.0-flash-lite": withDefaultModel(
2628
- googleGeminiChatV1,
2629
- "gemini-2.0-flash-lite"
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
- ),
2639
- "google.gemini-1.5-pro": withDefaultModel(
2640
- googleGeminiChatV1,
2641
- "gemini-1.5-pro"
2642
- ),
2643
- "google.gemini-2.5-pro": withDefaultModel(
2644
- googleGeminiChatV1,
2645
- "gemini-2.5-pro"
2646
- )
2647
- };
2648
-
2649
- // src/llm/config/deepseek/index.ts
2650
- var deepseekChatV1 = {
2651
- key: "deepseek.chat.v1",
2652
- provider: "deepseek.chat",
2653
- endpoint: `https://api.deepseek.com/v1/chat/completions`,
2654
- options: {
2655
- prompt: {},
2656
- topP: {},
2657
- useJson: {},
2658
- deepseekApiKey: {
2659
- default: getEnvironmentVariable("DEEPSEEK_API_KEY")
2660
- }
2661
- },
2662
- method: "POST",
2663
- headers: `{"Authorization":"Bearer {{deepseekApiKey}}", "Content-Type": "application/json" }`,
2664
- mapBody: {
2665
- prompt: {
2666
- key: "messages",
2667
- sanitize: openaiPromptSanitize
2668
- },
2669
- model: {
2670
- key: "model"
2671
- },
2672
- topP: {
2673
- key: "top_p"
2674
- },
2675
- useJson: {
2676
- key: "response_format.type",
2677
- sanitize: (v) => v ? "json_object" : "text"
2678
- }
2679
- }
2680
- };
2681
- var deepseek = {
2682
- "deepseek.chat.v1": deepseekChatV1,
2683
- "deepseek.chat": withDefaultModel(deepseekChatV1, "deepseek-chat")
2684
- };
2685
-
2686
- // src/llm/config.ts
2687
- var configs = {
2688
- ...openai,
2689
- ...anthropic,
2690
- ...bedrock,
2691
- ...xai,
2692
- ...ollama,
2693
- ...google,
2694
- ...deepseek
2695
- };
2696
- function getLlmConfig(provider) {
2697
- if (!provider) {
2698
- throw new LlmExeError(`Missing provider`, "unknown", {
2699
- error: "Missing provider",
2700
- resolution: "Provide a valid provider"
2701
- });
2702
- }
2703
- const pick2 = configs[provider];
2704
- if (pick2) {
2705
- return pick2;
2706
- }
2707
- throw new LlmExeError(`Invalid provider: ${provider}`, "unknown", {
2708
- provider,
2709
- error: `Invalid provider: ${provider}`,
2710
- resolution: "Provide a valid provider"
2711
- });
2712
- }
2713
-
2714
- // src/llm/output/_utils/getResultContent.ts
2715
- function getResultContent(result, index) {
2716
- if (typeof index === "number" && index > 0) {
2717
- const arr = result?.options || [];
2718
- const val = arr[index];
2719
- return val ? val : [];
2720
- }
2721
- return [...result.content];
2722
- }
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
-
2734
- // src/llm/output/base.ts
2735
- function BaseLlmOutput2(result) {
2736
- const __result = Object.freeze({
2737
- id: result.id || (0, import_uuid.v4)(),
2738
- name: result.name,
2739
- usage: result.usage,
2740
- stopReason: result.stopReason,
2741
- options: [...result?.options || []],
2742
- content: [...result.content],
2743
- created: result?.created || (/* @__PURE__ */ new Date()).getTime()
2744
- });
2745
- function getResult() {
2746
- return {
2747
- id: __result.id,
2748
- name: __result.name,
2749
- created: __result.created,
2750
- usage: __result.usage,
2751
- options: __result.options,
2752
- content: __result.content,
2753
- stopReason: __result.stopReason
2754
- };
2755
- }
2756
- return {
2757
- getResultContent: (index) => getResultContent(__result, index),
2758
- getResultText: (index) => getResultText(__result, index),
2759
- getResult
2760
- };
2761
- }
2762
-
2763
- // src/llm/output/_util.ts
2764
- function normalizeFunctionCall(input, provider) {
2765
- if (input === "any") {
2766
- if (provider === "openai") {
2767
- return "required";
2768
- }
2769
- }
2770
- return input;
2771
- }
2772
- function formatOptions(response, handler) {
2773
- const out = [];
2774
- for (const item of response) {
2775
- const result = handler(item);
2776
- if (result) {
2777
- out.push([result]);
2778
- }
2779
- }
2780
- return out;
2781
- }
2782
-
2783
- // src/llm/output/openai.ts
2784
- function formatResult(result) {
2785
- const out = [];
2786
- if (typeof result?.message?.content === "string") {
2787
- out.push({
2788
- type: "text",
2789
- text: result.message.content
2790
- });
2791
- }
2792
- if (result?.message?.tool_calls) {
2793
- for (const call of result.message.tool_calls) {
2794
- out.push({
2795
- functionId: call.id,
2796
- type: "function_use",
2797
- name: call.function.name,
2798
- input: maybeParseJSON(call.function.arguments)
2799
- });
2800
- }
2801
- }
2802
- return out;
2803
- }
2804
- function OutputOpenAIChat(result, _config) {
2805
- const id = result.id;
2806
- const name = result.model || _config?.model || "openai.unknown";
2807
- const created = result.created;
2808
- const [_content, ..._options] = result?.choices || [];
2809
- const stopReason = _content?.finish_reason;
2810
- const content = formatResult(_content);
2811
- const options = formatOptions(_options, formatResult);
2812
- const usage = {
2813
- output_tokens: result?.usage?.completion_tokens,
2814
- input_tokens: result?.usage?.prompt_tokens,
2815
- total_tokens: result?.usage?.total_tokens
2816
- };
2817
- return BaseLlmOutput2({
2818
- id,
2819
- name,
2820
- created,
2821
- usage,
2822
- stopReason,
2823
- content,
2824
- options
2825
- });
2826
- }
2827
-
2828
- // src/llm/output/claude.ts
2829
- function formatResult2(response) {
2830
- const content = response?.content || [];
2831
- const out = [];
2832
- for (let i = 0; i < content.length; i++) {
2833
- const result = content[i];
2834
- if (result.type === "text") {
2835
- out.push({
2836
- type: "text",
2837
- text: result.text
2838
- });
2839
- } else if (result.type === "tool_use") {
2840
- out.push({
2841
- functionId: result.id,
2842
- type: "function_use",
2843
- name: result.name,
2844
- input: result.input
2845
- });
2846
- }
2847
- }
2848
- return out;
2849
- }
2850
- function OutputAnthropicClaude3Chat(result, _config) {
2851
- const id = result.id;
2852
- const name = result.model || _config?.model || "anthropic.unknown";
2853
- const stopReason = result.stop_reason;
2854
- const content = formatResult2(result);
2855
- const usage = {
2856
- input_tokens: result?.usage?.input_tokens,
2857
- output_tokens: result?.usage?.output_tokens,
2858
- total_tokens: result?.usage?.input_tokens + result?.usage?.input_tokens
2859
- };
2860
- return BaseLlmOutput2({
2861
- id,
2862
- name,
2863
- usage,
2864
- stopReason,
2865
- content
2866
- });
2867
- }
2868
-
2869
- // src/llm/output/llama.ts
2870
- function OutputMetaLlama3Chat(result, _config) {
2871
- const name = _config?.model || "meta";
2872
- const stopReason = result.stop_reason;
2873
- const content = [
2874
- { type: "text", text: result.generation }
2875
- ];
2876
- const usage = {
2877
- output_tokens: result?.generation_token_count,
2878
- input_tokens: result?.prompt_token_count,
2879
- total_tokens: result?.generation_token_count + result?.prompt_token_count
2880
- };
2881
- return BaseLlmOutput2({
2882
- name,
2883
- usage,
2884
- stopReason,
2885
- content
2886
- });
2887
- }
2888
-
2889
- // src/llm/output/default.ts
2890
- function OutputDefault(result, _config) {
2891
- const name = _config.model || "unknown";
2892
- const stopReason = result?.stopReason || "stop";
2893
- const content = [];
2894
- if (result?.text) {
2895
- content.push({ type: "text", text: result.text });
2896
- }
2897
- const usage = {
2898
- output_tokens: result?.output_tokens || 0,
2899
- input_tokens: result?.input_tokens || 0,
2900
- total_tokens: (result?.input_tokens || 0) + (result?.output_tokens || 0)
2901
- };
2902
- return BaseLlmOutput2({
2903
- name,
2904
- usage,
2905
- stopReason,
2906
- content
2907
- });
2908
- }
2909
-
2910
- // src/llm/output/xai.ts
2911
- function formatResult3(result) {
2912
- const out = [];
2913
- if (typeof result?.message?.content === "string") {
2914
- out.push({
2915
- type: "text",
2916
- text: result.message.content
2917
- });
2918
- }
2919
- if (result?.message?.tool_calls) {
2920
- for (const call of result.message.tool_calls) {
2921
- out.push({
2922
- functionId: call.id,
2923
- type: "function_use",
2924
- name: call.function.name,
2925
- input: maybeParseJSON(call.function.arguments)
2926
- });
2927
- }
2928
- }
2929
- return out;
2930
- }
2931
- function OutputXAIChat(result, _config) {
2932
- const id = result.id;
2933
- const name = result.model || _config?.model || "openai.unknown";
2934
- const created = result.created;
2935
- const [_content, ..._options] = result?.choices || [];
2936
- const stopReason = _content?.finish_reason;
2937
- const content = formatResult3(_content);
2938
- const options = formatOptions(_options, formatResult3);
2939
- const usage = {
2940
- output_tokens: result?.usage?.completion_tokens,
2941
- input_tokens: result?.usage?.prompt_tokens,
2942
- total_tokens: result?.usage?.total_tokens
2943
- };
2944
- return BaseLlmOutput2({
2945
- id,
2946
- name,
2947
- created,
2948
- usage,
2949
- stopReason,
2950
- content,
2951
- options
2952
- });
2953
- }
2954
-
2955
- // src/llm/output/_utils/combineJsonl.ts
2956
- function combineJsonl(jsonl) {
2957
- const lines = jsonl.trim().split("\n").map((line) => line.trim()).filter((line) => line.length > 0).map((line) => {
2958
- try {
2959
- return JSON.parse(line);
2960
- } catch (e) {
2961
- throw new Error(`Invalid JSON: ${line}`);
2962
- }
2963
- });
2964
- if (lines.length === 0) {
2965
- throw new Error("No JSON lines provided.");
2966
- }
2967
- lines.sort(
2968
- (a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime()
2969
- );
2970
- let combinedContent = lines.map((line) => line?.message?.content ?? "").join("");
2971
- combinedContent = combinedContent.replace(/\\u003c/g, "<").replace(/\\u003e/g, ">");
2972
- const finalLine = lines.find((line) => line.done === true);
2973
- if (!finalLine) {
2974
- throw new Error("No line found where done = true.");
2975
- }
2976
- const result = {
2977
- model: finalLine.model,
2978
- created_at: finalLine.created_at,
2979
- message: {
2980
- role: finalLine?.message?.role || "assistant",
2981
- content: combinedContent
2982
- },
2983
- done_reason: finalLine.done_reason,
2984
- done: finalLine.done,
2985
- total_duration: finalLine.total_duration,
2986
- load_duration: finalLine.load_duration,
2987
- prompt_eval_count: finalLine.prompt_eval_count,
2988
- prompt_eval_duration: finalLine.prompt_eval_duration,
2989
- eval_count: finalLine.eval_count,
2990
- eval_duration: finalLine.eval_duration
2991
- };
2992
- const content = {
2993
- type: "text",
2994
- text: combinedContent
2995
- };
2923
+ ...toolsArr.map((call) => {
2924
+ const { name, arguments: input } = call;
2925
+ return {
2926
+ functionCall: {
2927
+ name,
2928
+ args: maybeParseJSON(input)
2929
+ }
2930
+ };
2931
+ })
2932
+ );
2933
+ delete message.function_call;
2934
+ }
2996
2935
  return {
2997
- lines,
2998
- result,
2999
- content
2936
+ role,
2937
+ parts
3000
2938
  };
3001
2939
  }
3002
2940
 
3003
- // src/llm/output/ollama.ts
3004
- function OutputOllamaChat(result, _config) {
3005
- const combined = combineJsonl(result);
3006
- const id = `${combined.result.model}.${combined.result.created_at}`;
3007
- const name = combined.result.model || _config?.model || "ollama.unknown";
3008
- const created = (/* @__PURE__ */ new Date(`${combined.result.created_at}`)).getTime();
3009
- const stopReason = `${combined?.result?.done_reason || "stop"}`;
3010
- const content = [combined.content];
3011
- const usage = {
3012
- output_tokens: 0,
3013
- input_tokens: 0,
3014
- total_tokens: 0
3015
- };
3016
- return BaseLlmOutput2({
3017
- id,
3018
- name,
3019
- created,
3020
- usage,
3021
- stopReason,
3022
- content,
3023
- options: []
3024
- });
2941
+ // src/llm/config/google/promptSanitize.ts
2942
+ function googleGeminiPromptSanitize(_messages, _inputBodyObj, _outputObj) {
2943
+ if (typeof _messages === "string") {
2944
+ return [{ role: "user", parts: [{ text: _messages }] }];
2945
+ }
2946
+ if (Array.isArray(_messages)) {
2947
+ if (_messages.length === 0) {
2948
+ throw new Error("Empty messages array");
2949
+ }
2950
+ if (_messages.length === 1 && _messages[0].role === "system") {
2951
+ return [{ role: "user", parts: [{ text: _messages[0].content }] }];
2952
+ }
2953
+ const hasSystemInstruction = _messages.some(
2954
+ (message) => message.role === "system"
2955
+ );
2956
+ if (hasSystemInstruction) {
2957
+ const theSystemInstructions = _messages.filter(
2958
+ (message) => message.role === "system"
2959
+ );
2960
+ const withoutSystemInstructions = _messages.filter(
2961
+ (message) => message.role !== "system"
2962
+ );
2963
+ _outputObj.system_instruction = {
2964
+ parts: theSystemInstructions.map((message) => ({
2965
+ text: message.content
2966
+ }))
2967
+ };
2968
+ return withoutSystemInstructions.map(googleGeminiPromptMessageCallback);
2969
+ }
2970
+ return _messages.map(googleGeminiPromptMessageCallback);
2971
+ }
2972
+ throw new Error("Invalid messages format");
3025
2973
  }
3026
2974
 
3027
2975
  // src/llm/output/google.gemini/formatResult.ts
3028
- function formatResult4(result, id) {
2976
+ function formatResult3(result, id) {
3029
2977
  const { parts = [] } = result?.content || {};
3030
2978
  const out = [];
3031
2979
  for (let i = 0; i < parts.length; i++) {
@@ -3050,18 +2998,18 @@ function formatResult4(result, id) {
3050
2998
  // src/llm/output/google.gemini/index.ts
3051
2999
  function OutputGoogleGeminiChat(result, _config) {
3052
3000
  const id = result.responseId;
3053
- const name = result.modelVersion || _config?.model || "gemini";
3001
+ const name = result.modelVersion || _config?.options.model?.default || "gemini";
3054
3002
  const created = (/* @__PURE__ */ new Date()).getTime();
3055
3003
  const [_content, ..._options] = result?.candidates || [];
3056
3004
  const stopReason = _content?.finishReason?.toLowerCase();
3057
- const content = formatResult4(_content, id);
3058
- const options = formatOptions(_options, formatResult4);
3005
+ const content = formatResult3(_content, id);
3006
+ const options = formatOptions(_options, formatResult3);
3059
3007
  const usage = {
3060
3008
  output_tokens: result?.usageMetadata?.candidatesTokenCount,
3061
3009
  input_tokens: result?.usageMetadata?.promptTokenCount,
3062
3010
  total_tokens: result?.usageMetadata?.totalTokenCount
3063
3011
  };
3064
- return BaseLlmOutput2({
3012
+ return {
3065
3013
  id,
3066
3014
  name,
3067
3015
  created,
@@ -3069,83 +3017,152 @@ function OutputGoogleGeminiChat(result, _config) {
3069
3017
  stopReason,
3070
3018
  content,
3071
3019
  options
3072
- });
3020
+ };
3073
3021
  }
3074
3022
 
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
3023
+ // src/llm/config/google/index.ts
3024
+ var googleGeminiChatV1 = {
3025
+ key: "google.chat.v1",
3026
+ provider: "google.chat",
3027
+ endpoint: `https://generativelanguage.googleapis.com/v1beta/models/{{model}}:generateContent?key={{geminiApiKey}}`,
3028
+ options: {
3029
+ effort: {},
3030
+ prompt: {},
3031
+ // topP: {},
3032
+ geminiApiKey: {
3033
+ default: getEnvironmentVariable("GEMINI_API_KEY")
3034
+ }
3035
+ },
3036
+ method: "POST",
3037
+ headers: `{"Content-Type": "application/json" }`,
3038
+ mapBody: {
3039
+ prompt: {
3040
+ key: "contents",
3041
+ transform: googleGeminiPromptSanitize
3042
+ },
3043
+ effort: {
3044
+ key: "config.thinkingConfig.thinkingBudget",
3045
+ transform: (v, _s) => {
3046
+ if (
3047
+ // only supported reasoning models
3048
+ ["gemini-2.5-pro", "gemini-2.5-flash", "gemini-2.5-light"].includes(
3049
+ _s.model
3050
+ ) && typeof v === "string" && ["minimal", "low", "medium", "high"].includes(v)
3051
+ ) {
3052
+ if (v === "low" || v === "minimal") {
3053
+ return 1024;
3054
+ } else if (v === "medium") {
3055
+ return 8192;
3056
+ } else if (v === "high") {
3057
+ return 24576;
3058
+ }
3059
+ }
3060
+ return void 0;
3061
+ }
3062
+ }
3063
+ },
3064
+ mapOptions: {
3065
+ functionCall: (call) => ({
3066
+ toolConfig: {
3067
+ functionCallingConfig: {
3068
+ mode: call === "any" ? "any" : call === "none" ? "none" : "auto"
3069
+ }
3070
+ }
3071
+ }),
3072
+ functions: (functions) => ({
3073
+ tools: [
3074
+ {
3075
+ functionDeclarations: functions.map((f) => ({
3076
+ name: f.name,
3077
+ description: f.description,
3078
+ parameters: cleanJsonSchemaFor(f.parameters, "google.chat")
3079
+ }))
3080
+ }
3081
+ ]
3082
+ })
3083
+ },
3084
+ transformResponse: OutputGoogleGeminiChat
3085
+ };
3086
+ var google = {
3087
+ "google.chat.v1": googleGeminiChatV1,
3088
+ "google.gemini-2.0-flash": withDefaultModel(
3089
+ googleGeminiChatV1,
3090
+ "gemini-2.0-flash"
3091
+ ),
3092
+ "google.gemini-2.0-flash-lite": withDefaultModel(
3093
+ googleGeminiChatV1,
3094
+ "gemini-2.0-flash-lite"
3095
+ ),
3096
+ "google.gemini-2.5-flash": withDefaultModel(
3097
+ googleGeminiChatV1,
3098
+ "gemini-2.5-flash"
3099
+ ),
3100
+ "google.gemini-2.5-flash-lite": withDefaultModel(
3101
+ googleGeminiChatV1,
3102
+ "gemini-2.5-flash-lite"
3103
+ ),
3104
+ "google.gemini-1.5-pro": withDefaultModel(
3105
+ googleGeminiChatV1,
3106
+ "gemini-1.5-pro"
3107
+ ),
3108
+ "google.gemini-2.5-pro": withDefaultModel(
3109
+ googleGeminiChatV1,
3110
+ "gemini-2.5-pro"
3111
+ )
3112
+ };
3113
+
3114
+ // src/llm/config/deepseek/index.ts
3115
+ var deepseekChatV1 = createOpenAiCompatibleConfiguration({
3116
+ key: "deepseek.chat.v1",
3117
+ provider: "deepseek.chat",
3118
+ endpoint: `https://api.deepseek.com/v1/chat/completions`,
3119
+ apiKeyMapping: ["deepseekApiKey", "DEEPSEEK_API_KEY"]
3120
+ });
3121
+ var deepseek = {
3122
+ "deepseek.chat.v1": deepseekChatV1,
3123
+ "deepseek.chat": withDefaultModel(deepseekChatV1, "deepseek-chat")
3124
+ };
3125
+
3126
+ // src/llm/config.ts
3127
+ var configs = {
3128
+ ...openai,
3129
+ ...anthropic,
3130
+ ...bedrock,
3131
+ ...xai,
3132
+ ...ollama,
3133
+ ...google,
3134
+ ...deepseek
3135
+ };
3136
+ function getLlmConfig(provider) {
3137
+ if (!provider) {
3138
+ throw new LlmExeError(`Missing provider`, "unknown", {
3139
+ error: "Missing provider",
3140
+ resolution: "Provide a valid provider"
3082
3141
  });
3083
3142
  }
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
- }
3143
+ const pick2 = configs[provider];
3144
+ if (pick2) {
3145
+ return pick2;
3093
3146
  }
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
3147
+ throw new LlmExeError(`Invalid provider: ${provider}`, "unknown", {
3148
+ provider,
3149
+ error: `Invalid provider: ${provider}`,
3150
+ resolution: "Provide a valid provider"
3117
3151
  });
3118
3152
  }
3119
3153
 
3120
- // src/llm/output/index.ts
3121
- function normalizeLlmOutputToInternalFormat(config, response) {
3122
- switch (config?.key) {
3123
- case "openai.chat.v1":
3124
- case "openai.chat-mock.v1":
3125
- return OutputOpenAIChat(response, config);
3126
- case "anthropic.chat.v1":
3127
- case "amazon:anthropic.chat.v1":
3128
- return OutputAnthropicClaude3Chat(response, config);
3129
- case "amazon:meta.chat.v1":
3130
- return OutputMetaLlama3Chat(response, config);
3131
- // case "amazon:nova.chat.v1":
3132
- // return OutputDefault(response, config);
3133
- case "xai.chat.v1":
3134
- return OutputXAIChat(response, config);
3135
- case "ollama.chat.v1":
3136
- return OutputOllamaChat(response, config);
3137
- case "google.chat.v1":
3138
- return OutputGoogleGeminiChat(response, config);
3139
- case "deepseek.chat.v1":
3140
- return OutputDeepSeekChat(response, config);
3141
- // use oai for now
3142
- default: {
3143
- if (config?.key?.startsWith("custom:")) {
3144
- return OutputDefault(response, config);
3145
- }
3146
- throw new Error("Unsupported provider");
3154
+ // src/utils/modules/maskApiKeysInDebug.ts
3155
+ function maskApiKeys(log) {
3156
+ return log.replace(
3157
+ /\b(Bearer\s+[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_]+\.[A-Za-z0-9\-_]+|Bearer\s+[A-Za-z0-9\-_]{20,}|sk-[A-Za-z0-9]{20,}|AKIA[A-Z0-9]{16}|[A-Za-z0-9]{32,})\b/g,
3158
+ (match) => {
3159
+ if (match.length <= 8) return match;
3160
+ const prefix = match.substring(0, 4);
3161
+ const suffix = match.substring(match.length - 4);
3162
+ const maskLength = match.length - 8;
3163
+ return `${prefix}${"*".repeat(maskLength)}${suffix}`;
3147
3164
  }
3148
- }
3165
+ );
3149
3166
  }
3150
3167
 
3151
3168
  // src/utils/modules/debug.ts
@@ -3171,7 +3188,15 @@ function debug(...args) {
3171
3188
  logs.push(arg.toString());
3172
3189
  } else {
3173
3190
  try {
3174
- logs.push(JSON.stringify(arg, null, 2));
3191
+ let shouldMask = false;
3192
+ if (arg.headers && arg.headers.Authorization) {
3193
+ shouldMask = true;
3194
+ }
3195
+ let str = JSON.stringify(arg, null, 2);
3196
+ if (shouldMask) {
3197
+ str = maskApiKeys(str);
3198
+ }
3199
+ logs.push(str);
3175
3200
  } catch (error) {
3176
3201
  console.error("Error parsing object:", error);
3177
3202
  }
@@ -3219,7 +3244,8 @@ async function apiRequest(url, options) {
3219
3244
  }
3220
3245
  throw new Error(message);
3221
3246
  }
3222
- if (response.headers.get("content-type")?.includes("application/json")) {
3247
+ const contentType = response.headers.get("content-type");
3248
+ if (contentType?.includes("application/json")) {
3223
3249
  const responseData = await response.json();
3224
3250
  return responseData;
3225
3251
  } else {
@@ -3236,20 +3262,26 @@ async function apiRequest(url, options) {
3236
3262
  function convertDotNotation(obj) {
3237
3263
  const result = {};
3238
3264
  for (const key in obj) {
3239
- if (obj.hasOwnProperty(key)) {
3240
- if (key.includes(".")) {
3241
- const keys = key.split(".");
3242
- let currentLevel = result;
3243
- for (let i = 0; i < keys.length; i++) {
3244
- if (i === keys.length - 1) {
3245
- currentLevel[keys[i]] = obj[key];
3246
- } else {
3247
- currentLevel[keys[i]] = currentLevel[keys[i]] || {};
3248
- currentLevel = currentLevel[keys[i]];
3265
+ if (Object.prototype.hasOwnProperty.call(obj, key) && !key.includes(".")) {
3266
+ result[key] = obj[key];
3267
+ }
3268
+ }
3269
+ for (const key in obj) {
3270
+ if (Object.prototype.hasOwnProperty.call(obj, key) && key.includes(".")) {
3271
+ const keys = key.split(".");
3272
+ let currentLevel = result;
3273
+ for (let i = 0; i < keys.length; i++) {
3274
+ const currentKey = keys[i];
3275
+ if (i === keys.length - 1) {
3276
+ currentLevel[currentKey] = obj[key];
3277
+ } else {
3278
+ if (!(currentKey in currentLevel)) {
3279
+ currentLevel[currentKey] = {};
3280
+ } else if (typeof currentLevel[currentKey] !== "object" || currentLevel[currentKey] === null || Array.isArray(currentLevel[currentKey])) {
3281
+ currentLevel[currentKey] = {};
3249
3282
  }
3283
+ currentLevel = currentLevel[currentKey];
3250
3284
  }
3251
- } else {
3252
- result[key] = obj[key];
3253
3285
  }
3254
3286
  }
3255
3287
  }
@@ -3266,8 +3298,8 @@ function mapBody(template, body) {
3266
3298
  const { key: providerSpecificKey, default: defaultValue } = providerSpecificSettings;
3267
3299
  if (providerSpecificKey) {
3268
3300
  let valueForThisKey = body[genericInputKey];
3269
- if (providerSpecificSettings.sanitize && typeof providerSpecificSettings.sanitize === "function") {
3270
- valueForThisKey = providerSpecificSettings.sanitize(
3301
+ if (providerSpecificSettings.transform && typeof providerSpecificSettings.transform === "function") {
3302
+ valueForThisKey = providerSpecificSettings.transform(
3271
3303
  valueForThisKey,
3272
3304
  Object.freeze({ ...body }),
3273
3305
  output
@@ -3291,28 +3323,70 @@ var import_sha256_js = require("@aws-crypto/sha256-js");
3291
3323
 
3292
3324
  // src/utils/modules/runWithTemporaryEnv.ts
3293
3325
  async function runWithTemporaryEnv(env, handler) {
3294
- const previousEnv = { ...process.env };
3326
+ const modifiedKeys = [];
3327
+ const originalValues = {};
3328
+ const envBefore = { ...process.env };
3295
3329
  try {
3296
- env();
3330
+ try {
3331
+ env();
3332
+ } catch (envError) {
3333
+ const envAfter2 = process.env;
3334
+ for (const key in envAfter2) {
3335
+ if (envBefore[key] !== envAfter2[key]) {
3336
+ modifiedKeys.push(key);
3337
+ originalValues[key] = envBefore[key];
3338
+ }
3339
+ }
3340
+ for (const key in envBefore) {
3341
+ if (!(key in envAfter2) && !modifiedKeys.includes(key)) {
3342
+ modifiedKeys.push(key);
3343
+ originalValues[key] = envBefore[key];
3344
+ }
3345
+ }
3346
+ throw envError;
3347
+ }
3348
+ const envAfter = process.env;
3349
+ for (const key in envAfter) {
3350
+ if (envBefore[key] !== envAfter[key]) {
3351
+ modifiedKeys.push(key);
3352
+ originalValues[key] = envBefore[key];
3353
+ }
3354
+ }
3355
+ for (const key in envBefore) {
3356
+ if (!(key in envAfter) && !modifiedKeys.includes(key)) {
3357
+ modifiedKeys.push(key);
3358
+ originalValues[key] = envBefore[key];
3359
+ }
3360
+ }
3297
3361
  const value = await handler();
3298
3362
  return value;
3299
3363
  } finally {
3300
- process.env = previousEnv;
3364
+ for (const key of modifiedKeys) {
3365
+ const originalValue = originalValues[key];
3366
+ if (originalValue === void 0) {
3367
+ delete process.env[key];
3368
+ } else {
3369
+ process.env[key] = originalValue;
3370
+ }
3371
+ }
3301
3372
  }
3302
3373
  }
3303
3374
 
3304
3375
  // src/utils/modules/getAwsAuthorizationHeaders.ts
3305
3376
  async function getAwsAuthorizationHeaders(req, props) {
3377
+ if (!props.url || !props.regionName) {
3378
+ throw new Error("URL and region name are required for AWS authorization");
3379
+ }
3306
3380
  const providerChain = (0, import_credential_providers.fromNodeProviderChain)();
3307
3381
  const credentials = await runWithTemporaryEnv(
3308
3382
  () => {
3309
- if (props.awsAccessKey) {
3383
+ if (props.awsAccessKey && typeof props.awsAccessKey === "string") {
3310
3384
  process.env["AWS_ACCESS_KEY_ID"] = props.awsAccessKey;
3311
3385
  }
3312
- if (props.awsSecretKey) {
3386
+ if (props.awsSecretKey && typeof props.awsSecretKey === "string") {
3313
3387
  process.env["AWS_SECRET_ACCESS_KEY"] = props.awsSecretKey;
3314
3388
  }
3315
- if (props.awsSessionToken) {
3389
+ if (props.awsSessionToken && typeof props.awsSessionToken === "string") {
3316
3390
  process.env["AWS_SESSION_TOKEN"] = props.awsSessionToken;
3317
3391
  }
3318
3392
  },
@@ -3342,8 +3416,21 @@ async function getAwsAuthorizationHeaders(req, props) {
3342
3416
  // src/llm/_utils.parseHeaders.ts
3343
3417
  async function parseHeaders(config, replacements, payload) {
3344
3418
  const replace = replaceTemplateStringSimple(config.headers, replacements);
3345
- const parse = replace ? JSON.parse(replace) : {};
3346
- const headers = Object.assign({}, payload.headers, parse);
3419
+ let parsedHeaders = {};
3420
+ if (replace) {
3421
+ try {
3422
+ parsedHeaders = JSON.parse(replace);
3423
+ if (typeof parsedHeaders !== "object" || parsedHeaders === null || Array.isArray(parsedHeaders)) {
3424
+ throw new Error("Headers must be a JSON object");
3425
+ }
3426
+ } catch (error) {
3427
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
3428
+ throw new Error(
3429
+ `Failed to parse headers configuration: ${errorMessage}. Headers template: "${config.headers}". After replacement: "${replace}"`
3430
+ );
3431
+ }
3432
+ }
3433
+ const headers = Object.assign({}, payload.headers, parsedHeaders);
3347
3434
  if (config.provider.startsWith("amazon:") || config.provider.startsWith("amazon.")) {
3348
3435
  const url = payload.url;
3349
3436
  return getAwsAuthorizationHeaders(
@@ -3364,122 +3451,129 @@ async function parseHeaders(config, replacements, payload) {
3364
3451
  }
3365
3452
  }
3366
3453
 
3367
- // src/llm/output/_utils/cleanJsonSchemaFor.ts
3368
- var providerFieldExclusions = {
3369
- "openai.chat": ["default"],
3370
- // fields to exclude for openai.chat, xai, deepseek
3371
- "anthropic.chat": [],
3372
- "google.chat": ["additionalProperties"]
3373
- };
3374
- function cleanJsonSchemaFor(schema = {}, provider) {
3375
- const clone = deepClone(schema);
3376
- if (Object.keys(clone).length === 0) {
3454
+ // src/llm/output/default.ts
3455
+ function OutputDefault(result, _config) {
3456
+ const name = _config?.options.model?.default || "unknown";
3457
+ const stopReason = result?.stopReason || "stop";
3458
+ const content = [];
3459
+ if (result?.text) {
3460
+ content.push({ type: "text", text: result.text });
3461
+ }
3462
+ const usage = {
3463
+ output_tokens: result?.output_tokens || 0,
3464
+ input_tokens: result?.input_tokens || 0,
3465
+ total_tokens: (result?.input_tokens || 0) + (result?.output_tokens || 0)
3466
+ };
3467
+ return {
3468
+ name,
3469
+ usage,
3470
+ stopReason,
3471
+ content
3472
+ };
3473
+ }
3474
+
3475
+ // src/llm/output/_utils/getResultContent.ts
3476
+ function getResultContent(result, index) {
3477
+ if (typeof index === "number" && index > 0) {
3478
+ const arr = result?.options || [];
3479
+ const val = arr[index];
3480
+ return val ? val : [];
3481
+ }
3482
+ return [...result.content];
3483
+ }
3484
+
3485
+ // src/llm/output/_utils/getResultText.ts
3486
+ function getResultText(result, index) {
3487
+ if (typeof index === "number" && index > 0) {
3488
+ const arr = result?.options || [];
3489
+ const val = arr[index];
3490
+ return isOutputResultContentText(val?.[0]) ? val[0]?.text : "";
3491
+ }
3492
+ return isOutputResultContentText(result?.content?.[0]) ? result.content[0]?.text : "";
3493
+ }
3494
+
3495
+ // src/llm/output/base.ts
3496
+ function BaseLlmOutput(result) {
3497
+ const __result = Object.freeze({
3498
+ id: result.id || (0, import_uuid.v4)(),
3499
+ name: result.name,
3500
+ usage: result.usage,
3501
+ stopReason: result.stopReason,
3502
+ options: [...result?.options || []],
3503
+ content: [...result.content],
3504
+ created: result?.created || (/* @__PURE__ */ new Date()).getTime()
3505
+ });
3506
+ function getResult() {
3377
3507
  return {
3378
- type: "object",
3379
- properties: {},
3380
- required: []
3508
+ id: __result.id,
3509
+ name: __result.name,
3510
+ created: __result.created,
3511
+ usage: __result.usage,
3512
+ options: __result.options,
3513
+ content: __result.content,
3514
+ stopReason: __result.stopReason
3381
3515
  };
3382
3516
  }
3383
- const exclusions = providerFieldExclusions[provider] || [];
3384
- function removeDisallowedFields(obj) {
3385
- if (Array.isArray(obj)) {
3386
- return obj.map(removeDisallowedFields);
3387
- } else if (typeof obj === "object" && obj !== null) {
3388
- return Object.keys(obj).reduce((acc, key) => {
3389
- if (!exclusions.includes(key)) {
3390
- acc[key] = removeDisallowedFields(obj[key]);
3391
- }
3392
- return acc;
3393
- }, {});
3517
+ return {
3518
+ getResultContent: (index) => getResultContent(__result, index),
3519
+ getResultText: (index) => getResultText(__result, index),
3520
+ getResult
3521
+ };
3522
+ }
3523
+
3524
+ // src/llm/_utils.mapOptions.ts
3525
+ function mapOptions(input, options, config) {
3526
+ if (!config?.mapOptions || !options) {
3527
+ return input;
3528
+ }
3529
+ let result = { ...input };
3530
+ let processedOptions = options;
3531
+ if (options.functionCall && config.mapOptions.functionCall) {
3532
+ const mapping = config.mapOptions.functionCall(
3533
+ options.functionCall,
3534
+ options,
3535
+ result,
3536
+ config
3537
+ );
3538
+ if (mapping._clearFunctions) {
3539
+ processedOptions = { ...options, functions: [] };
3540
+ const { _clearFunctions, ...rest } = mapping;
3541
+ result = { ...result, ...rest };
3542
+ } else {
3543
+ result = { ...result, ...mapping };
3394
3544
  }
3395
- return obj;
3396
3545
  }
3397
- return removeDisallowedFields(clone);
3546
+ if (processedOptions.functions?.length && config.mapOptions.functions) {
3547
+ result = {
3548
+ ...result,
3549
+ ...config.mapOptions.functions(
3550
+ processedOptions.functions,
3551
+ processedOptions,
3552
+ result,
3553
+ config
3554
+ )
3555
+ };
3556
+ }
3557
+ if (options.jsonSchema && config.mapOptions.jsonSchema) {
3558
+ result = {
3559
+ ...result,
3560
+ ...config.mapOptions.jsonSchema(options.jsonSchema, options, result, config)
3561
+ };
3562
+ }
3563
+ return result;
3398
3564
  }
3399
3565
 
3400
3566
  // src/llm/llm.call.ts
3401
3567
  async function useLlm_call(state, messages, _options) {
3402
3568
  const config = getLlmConfig(state.key);
3403
- const { functionCallStrictInput = false } = _options || {};
3404
- const input = mapBody(
3569
+ const transformBody = mapBody(
3405
3570
  config.mapBody,
3406
3571
  Object.assign({}, state, {
3407
3572
  prompt: messages
3408
3573
  })
3409
3574
  );
3410
- if (_options && _options?.jsonSchema) {
3411
- if (state.provider.startsWith("openai") || state.provider.startsWith("deepseek") || state.provider.startsWith("xai")) {
3412
- const curr = input["response_format"] || {};
3413
- input["response_format"] = Object.assign(curr, {
3414
- type: "json_schema",
3415
- json_schema: {
3416
- name: "output",
3417
- strict: !!functionCallStrictInput,
3418
- schema: cleanJsonSchemaFor(_options?.jsonSchema, "openai.chat")
3419
- }
3420
- });
3421
- }
3422
- }
3423
- if (_options && _options?.functionCall) {
3424
- if (state.provider.startsWith("anthropic")) {
3425
- if (_options?.functionCall === "none") {
3426
- _options.functions = [];
3427
- } else if (_options?.functionCall === "auto" || _options?.functionCall === "any") {
3428
- input["tool_choice"] = { type: _options?.functionCall };
3429
- } else {
3430
- input["tool_choice"] = _options?.functionCall;
3431
- }
3432
- } else if (state.provider.startsWith("openai") || state.provider.startsWith("deepseek") || state.provider.startsWith("xai")) {
3433
- input["tool_choice"] = normalizeFunctionCall(
3434
- _options?.functionCall,
3435
- "openai"
3436
- );
3437
- } else if (state.provider.startsWith("google")) {
3438
- input["toolConfig"] = {
3439
- functionCallingConfig: {
3440
- mode: normalizeFunctionCall(_options?.functionCall, "google")
3441
- }
3442
- };
3443
- }
3444
- }
3445
- if (_options && _options?.functions?.length) {
3446
- if (state.provider.startsWith("anthropic")) {
3447
- input["tools"] = _options.functions.map((f) => ({
3448
- name: f.name,
3449
- description: f.description,
3450
- input_schema: cleanJsonSchemaFor(f.parameters, "anthropic.chat")
3451
- }));
3452
- } else if (state.provider.startsWith("openai") || state.provider.startsWith("deepseek") || state.provider.startsWith("xai")) {
3453
- input["tools"] = _options.functions.map((f) => {
3454
- const props = {
3455
- name: f?.name,
3456
- description: f?.description,
3457
- parameters: f?.parameters
3458
- };
3459
- return {
3460
- type: "function",
3461
- function: Object.assign(
3462
- props,
3463
- {
3464
- parameters: cleanJsonSchemaFor(props.parameters, "openai.chat")
3465
- },
3466
- { strict: functionCallStrictInput }
3467
- )
3468
- };
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
- ];
3480
- }
3481
- }
3482
- const body = JSON.stringify(input);
3575
+ const applyOptions = mapOptions(transformBody, _options, config);
3576
+ const body = JSON.stringify(applyOptions);
3483
3577
  const url = replaceTemplateStringSimple(config.endpoint, state);
3484
3578
  const headers = await parseHeaders(config, state, {
3485
3579
  url,
@@ -3506,7 +3600,9 @@ async function useLlm_call(state, messages, _options) {
3506
3600
  body,
3507
3601
  headers
3508
3602
  });
3509
- return normalizeLlmOutputToInternalFormat(state, response);
3603
+ const { transformResponse = OutputDefault } = config;
3604
+ const normalized = transformResponse(response, config);
3605
+ return BaseLlmOutput(normalized);
3510
3606
  }
3511
3607
 
3512
3608
  // src/llm/_utils.stateFromOptions.ts
@@ -3649,6 +3745,80 @@ function useLlm(provider, options = {}) {
3649
3745
  const config = getLlmConfig(provider);
3650
3746
  return apiRequestWrapper(config, options, useLlm_call);
3651
3747
  }
3748
+ function useLlmConfiguration(config) {
3749
+ return (options = {}) => apiRequestWrapper(config, options, useLlm_call);
3750
+ }
3751
+
3752
+ // src/embedding/output/BaseEmbeddingOutput.ts
3753
+ function BaseEmbeddingOutput(result) {
3754
+ const __result = Object.freeze({
3755
+ id: result.id || (0, import_uuid.v4)(),
3756
+ model: result.model,
3757
+ usage: result.usage,
3758
+ embedding: [...result?.embedding || []],
3759
+ created: result?.created || (/* @__PURE__ */ new Date()).getTime()
3760
+ });
3761
+ function getResult() {
3762
+ return {
3763
+ id: __result.id,
3764
+ model: __result.model,
3765
+ created: __result.created,
3766
+ usage: __result.usage,
3767
+ embedding: __result.embedding
3768
+ };
3769
+ }
3770
+ function getEmbedding(index) {
3771
+ if (index && index > 0) {
3772
+ const arr = __result?.embedding;
3773
+ const val = arr[index];
3774
+ return val ? val : [];
3775
+ }
3776
+ return __result.embedding[0];
3777
+ }
3778
+ return {
3779
+ getEmbedding,
3780
+ getResult
3781
+ };
3782
+ }
3783
+
3784
+ // src/embedding/output/OpenAiEmbedding.ts
3785
+ function OpenAiEmbedding(result, config) {
3786
+ const __result = deepClone(result);
3787
+ const model = __result.model || config.model || "openai.unknown";
3788
+ const created = (/* @__PURE__ */ new Date()).getTime();
3789
+ const results = result?.data || [];
3790
+ const embedding = results.map((a) => a.embedding);
3791
+ const usage = {
3792
+ output_tokens: 0,
3793
+ input_tokens: result?.usage?.prompt_tokens,
3794
+ total_tokens: result?.usage?.total_tokens
3795
+ };
3796
+ return BaseEmbeddingOutput({
3797
+ model,
3798
+ created,
3799
+ usage,
3800
+ embedding
3801
+ });
3802
+ }
3803
+
3804
+ // src/embedding/output/AmazonTitan.ts
3805
+ function AmazonTitanEmbedding(result, config) {
3806
+ const __result = deepClone(result);
3807
+ const model = config.model || "amazon.unknown";
3808
+ const created = (/* @__PURE__ */ new Date()).getTime();
3809
+ const embedding = [__result.embedding];
3810
+ const usage = {
3811
+ output_tokens: 0,
3812
+ input_tokens: __result.inputTextTokenCount,
3813
+ total_tokens: __result.inputTextTokenCount
3814
+ };
3815
+ return BaseEmbeddingOutput({
3816
+ model,
3817
+ created,
3818
+ usage,
3819
+ embedding
3820
+ });
3821
+ }
3652
3822
 
3653
3823
  // src/embedding/config.ts
3654
3824
  var embeddingConfigs = {
@@ -3681,7 +3851,8 @@ var embeddingConfigs = {
3681
3851
  encodingFormat: {
3682
3852
  key: "encoding_format"
3683
3853
  }
3684
- }
3854
+ },
3855
+ transformResponse: OpenAiEmbedding
3685
3856
  },
3686
3857
  "amazon.embedding.v1": {
3687
3858
  key: "amazon.embedding.v1",
@@ -3708,7 +3879,8 @@ var embeddingConfigs = {
3708
3879
  dimensions: {
3709
3880
  key: "dimensions"
3710
3881
  }
3711
- }
3882
+ },
3883
+ transformResponse: AmazonTitanEmbedding
3712
3884
  }
3713
3885
  };
3714
3886
  function getEmbeddingConfig(provider) {
@@ -3722,77 +3894,6 @@ function getEmbeddingConfig(provider) {
3722
3894
  throw new Error(`Invalid provider: ${provider}`);
3723
3895
  }
3724
3896
 
3725
- // src/embedding/output/BaseEmbeddingOutput.ts
3726
- function BaseEmbeddingOutput(result) {
3727
- const __result = Object.freeze({
3728
- id: result.id || (0, import_uuid.v4)(),
3729
- model: result.model,
3730
- usage: result.usage,
3731
- embedding: [...result?.embedding || []],
3732
- created: result?.created || (/* @__PURE__ */ new Date()).getTime()
3733
- });
3734
- function getResult() {
3735
- return {
3736
- id: __result.id,
3737
- model: __result.model,
3738
- created: __result.created,
3739
- usage: __result.usage,
3740
- embedding: __result.embedding
3741
- };
3742
- }
3743
- function getEmbedding(index) {
3744
- if (index && index > 0) {
3745
- const arr = __result?.embedding;
3746
- const val = arr[index];
3747
- return val ? val : [];
3748
- }
3749
- return __result.embedding[0];
3750
- }
3751
- return {
3752
- getEmbedding,
3753
- getResult
3754
- };
3755
- }
3756
-
3757
- // src/embedding/output/AmazonTitan.ts
3758
- function AmazonTitanEmbedding(result, config) {
3759
- const __result = deepClone(result);
3760
- const model = config.model || "amazon.unknown";
3761
- const created = (/* @__PURE__ */ new Date()).getTime();
3762
- const embedding = [__result.embedding];
3763
- const usage = {
3764
- output_tokens: 0,
3765
- input_tokens: __result.inputTextTokenCount,
3766
- total_tokens: __result.inputTextTokenCount
3767
- };
3768
- return BaseEmbeddingOutput({
3769
- model,
3770
- created,
3771
- usage,
3772
- embedding
3773
- });
3774
- }
3775
-
3776
- // src/embedding/output/OpenAiEmbedding.ts
3777
- function OpenAiEmbedding(result, config) {
3778
- const __result = deepClone(result);
3779
- const model = __result.model || config.model || "openai.unknown";
3780
- const created = (/* @__PURE__ */ new Date()).getTime();
3781
- const results = result?.data || [];
3782
- const embedding = results.map((a) => a.embedding);
3783
- const usage = {
3784
- output_tokens: 0,
3785
- input_tokens: result?.usage?.prompt_tokens,
3786
- total_tokens: result?.usage?.total_tokens
3787
- };
3788
- return BaseEmbeddingOutput({
3789
- model,
3790
- created,
3791
- usage,
3792
- embedding
3793
- });
3794
- }
3795
-
3796
3897
  // src/embedding/output/getEmbeddingOutputParser.ts
3797
3898
  function getEmbeddingOutputParser(config, response) {
3798
3899
  switch (config.key) {
@@ -4810,6 +4911,9 @@ var Dialogue = class extends BaseStateItem {
4810
4911
  * @returns this for chaining
4811
4912
  */
4812
4913
  addFromOutput(output) {
4914
+ if (!output || typeof output !== "object") {
4915
+ return this;
4916
+ }
4813
4917
  const result = "getResult" in output ? output.getResult() : output;
4814
4918
  if (!result || typeof result !== "object") {
4815
4919
  return this;
@@ -4946,6 +5050,7 @@ function createStateItem(name, defaultValue) {
4946
5050
  createEmbedding,
4947
5051
  createLlmExecutor,
4948
5052
  createLlmFunctionExecutor,
5053
+ createOpenAiCompatibleConfiguration,
4949
5054
  createParser,
4950
5055
  createPrompt,
4951
5056
  createState,
@@ -4956,5 +5061,6 @@ function createStateItem(name, defaultValue) {
4956
5061
  registerPartials,
4957
5062
  useExecutors,
4958
5063
  useLlm,
5064
+ useLlmConfiguration,
4959
5065
  utils
4960
5066
  });