llm-exe 2.3.0 → 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,16 +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
- }
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
2411
2735
  };
2412
2736
  var anthropic = {
2413
2737
  "anthropic.chat.v1": anthropicChatV1,
2414
- "anthropic.claude-3-7-sonnet": withDefaultModel(
2738
+ // Claude 4 models (latest generation)
2739
+ "anthropic.claude-sonnet-4": withDefaultModel(
2415
2740
  anthropicChatV1,
2416
- "claude-3-7-sonnet-latest"
2741
+ "claude-sonnet-4-0"
2417
2742
  ),
2743
+ "anthropic.claude-opus-4": withDefaultModel(
2744
+ anthropicChatV1,
2745
+ "claude-opus-4-0"
2746
+ ),
2747
+ "anthropic.claude-3-7-sonnet": withDefaultModel(
2748
+ anthropicChatV1,
2749
+ "claude-3-7-sonnet-20250219"
2750
+ ),
2751
+ // Claude 3.5 models
2418
2752
  "anthropic.claude-3-5-sonnet": withDefaultModel(
2419
2753
  anthropicChatV1,
2420
2754
  "claude-3-5-sonnet-latest"
@@ -2423,54 +2757,103 @@ var anthropic = {
2423
2757
  anthropicChatV1,
2424
2758
  "claude-3-5-haiku-latest"
2425
2759
  ),
2760
+ // Deprecated
2426
2761
  "anthropic.claude-3-opus": withDefaultModel(
2427
2762
  anthropicChatV1,
2428
- "claude-3-opus-latest"
2763
+ "claude-3-opus-20240229"
2764
+ ),
2765
+ "anthropic.claude-3-haiku": withDefaultModel(
2766
+ anthropicChatV1,
2767
+ "claude-3-haiku-20240307"
2429
2768
  )
2430
2769
  };
2431
2770
 
2432
2771
  // src/llm/config/x/index.ts
2433
- var xaiChatV1 = {
2772
+ var xaiChatV1 = createOpenAiCompatibleConfiguration({
2434
2773
  key: "xai.chat.v1",
2435
2774
  provider: "xai.chat",
2436
2775
  endpoint: `https://api.x.ai/v1/chat/completions`,
2437
- options: {
2438
- prompt: {},
2439
- topP: {},
2440
- useJson: {},
2441
- xAiApiKey: {
2442
- default: getEnvironmentVariable("XAI_API_KEY")
2443
- }
2444
- },
2445
- method: "POST",
2446
- headers: `{"Authorization":"Bearer {{xAiApiKey}}", "Content-Type": "application/json" }`,
2447
- mapBody: {
2448
- prompt: {
2449
- key: "messages",
2450
- sanitize: (v) => {
2451
- if (typeof v === "string") {
2452
- return [{ role: "user", content: v }];
2453
- }
2454
- return v;
2455
- }
2456
- },
2457
- model: {
2458
- key: "model"
2459
- },
2460
- topP: {
2461
- key: "top_p"
2462
- },
2463
- useJson: {
2464
- key: "response_format.type",
2465
- sanitize: (v) => v ? "json_object" : "text"
2466
- }
2467
- }
2468
- };
2776
+ apiKeyMapping: ["xAiApiKey", "XAI_API_KEY"]
2777
+ });
2469
2778
  var xai = {
2470
2779
  "xai.chat.v1": xaiChatV1,
2471
- "xai.grok-2": withDefaultModel(xaiChatV1, "grok-2-latest")
2780
+ "xai.grok-2": withDefaultModel(xaiChatV1, "grok-2-latest"),
2781
+ "xai.grok-3": withDefaultModel(xaiChatV1, "grok-3"),
2782
+ "xai.grok-4": withDefaultModel(xaiChatV1, "grok-4")
2472
2783
  };
2473
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
+
2474
2857
  // src/llm/config/ollama/index.ts
2475
2858
  var ollamaChatV1 = {
2476
2859
  key: "ollama.chat.v1",
@@ -2484,7 +2867,7 @@ var ollamaChatV1 = {
2484
2867
  mapBody: {
2485
2868
  prompt: {
2486
2869
  key: "messages",
2487
- sanitize: (v) => {
2870
+ transform: (v) => {
2488
2871
  if (typeof v === "string") {
2489
2872
  return [{ role: "user", content: v }];
2490
2873
  }
@@ -2494,7 +2877,8 @@ var ollamaChatV1 = {
2494
2877
  model: {
2495
2878
  key: "model"
2496
2879
  }
2497
- }
2880
+ },
2881
+ transformResponse: OutputOllamaChat
2498
2882
  };
2499
2883
  var ollama = {
2500
2884
  "ollama.chat.v1": ollamaChatV1,
@@ -2524,507 +2908,72 @@ function googleGeminiPromptMessageCallback(_message) {
2524
2908
  parts.push({
2525
2909
  functionResponse: {
2526
2910
  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
- }
2551
- return {
2552
- role,
2553
- parts
2554
- };
2555
- }
2556
-
2557
- // src/llm/config/google/promptSanitize.ts
2558
- function googleGeminiPromptSanitize(_messages, _inputBodyObj, _outputObj) {
2559
- if (typeof _messages === "string") {
2560
- return [{ role: "user", parts: [{ text: _messages }] }];
2561
- }
2562
- if (Array.isArray(_messages)) {
2563
- if (_messages.length === 0) {
2564
- throw new Error("Empty messages array");
2565
- }
2566
- if (_messages.length === 1 && _messages[0].role === "system") {
2567
- return [{ role: "user", parts: [{ text: _messages[0].content }] }];
2568
- }
2569
- const hasSystemInstruction = _messages.some(
2570
- (message) => message.role === "system"
2571
- );
2572
- if (hasSystemInstruction) {
2573
- const theSystemInstructions = _messages.filter(
2574
- (message) => message.role === "system"
2575
- );
2576
- const withoutSystemInstructions = _messages.filter(
2577
- (message) => message.role !== "system"
2578
- );
2579
- _outputObj.system_instruction = {
2580
- parts: theSystemInstructions.map((message) => ({
2581
- text: message.content
2582
- }))
2583
- };
2584
- return withoutSystemInstructions.map(googleGeminiPromptMessageCallback);
2585
- }
2586
- return _messages.map(googleGeminiPromptMessageCallback);
2587
- }
2588
- throw new Error("Invalid messages format");
2589
- }
2590
-
2591
- // src/llm/config/google/index.ts
2592
- var googleGeminiChatV1 = {
2593
- key: "google.chat.v1",
2594
- provider: "google.chat",
2595
- endpoint: `https://generativelanguage.googleapis.com/v1beta/models/{{model}}:generateContent?key={{geminiApiKey}}`,
2596
- options: {
2597
- prompt: {},
2598
- // topP: {},
2599
- geminiApiKey: {
2600
- default: getEnvironmentVariable("GEMINI_API_KEY")
2601
- }
2602
- },
2603
- method: "POST",
2604
- headers: `{"Content-Type": "application/json" }`,
2605
- mapBody: {
2606
- prompt: {
2607
- key: "contents",
2608
- sanitize: googleGeminiPromptSanitize
2609
- }
2610
- // topP: {
2611
- // key: "top_p",
2612
- // }
2613
- }
2614
- };
2615
- var google = {
2616
- "google.chat.v1": googleGeminiChatV1,
2617
- "google.gemini-2.0-flash": withDefaultModel(
2618
- googleGeminiChatV1,
2619
- "gemini-2.0-flash"
2620
- ),
2621
- "google.gemini-2.0-flash-lite": withDefaultModel(
2622
- googleGeminiChatV1,
2623
- "gemini-2.0-flash-lite"
2624
- ),
2625
- "google.gemini-1.5-pro": withDefaultModel(
2626
- googleGeminiChatV1,
2627
- "gemini-1.5-pro"
2628
- )
2629
- };
2630
-
2631
- // src/llm/config/deepseek/index.ts
2632
- var deepseekChatV1 = {
2633
- key: "deepseek.chat.v1",
2634
- provider: "deepseek.chat",
2635
- endpoint: `https://api.deepseek.com/v1/chat/completions`,
2636
- options: {
2637
- prompt: {},
2638
- topP: {},
2639
- useJson: {},
2640
- deepseekApiKey: {
2641
- default: getEnvironmentVariable("DEEPSEEK_API_KEY")
2642
- }
2643
- },
2644
- method: "POST",
2645
- headers: `{"Authorization":"Bearer {{deepseekApiKey}}", "Content-Type": "application/json" }`,
2646
- mapBody: {
2647
- prompt: {
2648
- key: "messages",
2649
- sanitize: (v) => {
2650
- if (typeof v === "string") {
2651
- return [{ role: "user", content: v }];
2652
- }
2653
- return v;
2654
- }
2655
- },
2656
- model: {
2657
- key: "model"
2658
- },
2659
- topP: {
2660
- key: "top_p"
2661
- },
2662
- useJson: {
2663
- key: "response_format.type",
2664
- sanitize: (v) => v ? "json_object" : "text"
2665
- }
2666
- }
2667
- };
2668
- var deepseek = {
2669
- "deepseek.chat.v1": deepseekChatV1,
2670
- "deepseek.chat": withDefaultModel(deepseekChatV1, "deepseek-chat")
2671
- };
2672
-
2673
- // src/llm/config.ts
2674
- var configs = {
2675
- ...openai,
2676
- ...anthropic,
2677
- ...bedrock,
2678
- ...xai,
2679
- ...ollama,
2680
- ...google,
2681
- ...deepseek
2682
- };
2683
- function getLlmConfig(provider) {
2684
- if (!provider) {
2685
- throw new LlmExeError(`Missing provider`, "unknown", {
2686
- error: "Missing provider",
2687
- resolution: "Provide a valid provider"
2688
- });
2689
- }
2690
- const pick2 = configs[provider];
2691
- if (pick2) {
2692
- return pick2;
2693
- }
2694
- throw new LlmExeError(`Invalid provider: ${provider}`, "unknown", {
2695
- provider,
2696
- error: `Invalid provider: ${provider}`,
2697
- resolution: "Provide a valid provider"
2698
- });
2699
- }
2700
-
2701
- // src/llm/output/_utils/getResultContent.ts
2702
- function getResultContent(result, index) {
2703
- if (typeof index === "number" && index > 0) {
2704
- const arr = result?.options || [];
2705
- const val = arr[index];
2706
- return val ? val : [];
2707
- }
2708
- return [...result.content];
2709
- }
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
-
2721
- // src/llm/output/base.ts
2722
- function BaseLlmOutput2(result) {
2723
- const __result = Object.freeze({
2724
- id: result.id || (0, import_uuid.v4)(),
2725
- name: result.name,
2726
- usage: result.usage,
2727
- stopReason: result.stopReason,
2728
- options: [...result?.options || []],
2729
- content: [...result.content],
2730
- created: result?.created || (/* @__PURE__ */ new Date()).getTime()
2731
- });
2732
- function getResult() {
2733
- return {
2734
- id: __result.id,
2735
- name: __result.name,
2736
- created: __result.created,
2737
- usage: __result.usage,
2738
- options: __result.options,
2739
- content: __result.content,
2740
- stopReason: __result.stopReason
2741
- };
2742
- }
2743
- return {
2744
- getResultContent: (index) => getResultContent(__result, index),
2745
- getResultText: (index) => getResultText(__result, index),
2746
- getResult
2747
- };
2748
- }
2749
-
2750
- // src/llm/output/_util.ts
2751
- function normalizeFunctionCall(input, provider) {
2752
- if (input === "any") {
2753
- if (provider === "openai") {
2754
- return "required";
2755
- }
2756
- }
2757
- return input;
2758
- }
2759
- function formatOptions(response, handler) {
2760
- const out = [];
2761
- for (const item of response) {
2762
- const result = handler(item);
2763
- if (result) {
2764
- out.push([result]);
2765
- }
2766
- }
2767
- return out;
2768
- }
2769
- function formatContent(response, handler) {
2770
- const out = [];
2771
- const result = handler(response);
2772
- if (result) {
2773
- out.push(result);
2774
- }
2775
- return out;
2776
- }
2777
-
2778
- // src/llm/output/openai.ts
2779
- function formatResult(result) {
2780
- const out = [];
2781
- if (typeof result?.message?.content === "string") {
2782
- out.push({
2783
- type: "text",
2784
- text: result.message.content
2785
- });
2786
- }
2787
- if (result?.message?.tool_calls) {
2788
- for (const call of result.message.tool_calls) {
2789
- out.push({
2790
- functionId: call.id,
2791
- type: "function_use",
2792
- name: call.function.name,
2793
- input: maybeParseJSON(call.function.arguments)
2794
- });
2795
- }
2796
- }
2797
- return out;
2798
- }
2799
- function OutputOpenAIChat(result, _config) {
2800
- const id = result.id;
2801
- const name = result.model || _config?.model || "openai.unknown";
2802
- const created = result.created;
2803
- const [_content, ..._options] = result?.choices || [];
2804
- const stopReason = _content?.finish_reason;
2805
- const content = formatResult(_content);
2806
- const options = formatOptions(_options, formatResult);
2807
- const usage = {
2808
- output_tokens: result?.usage?.completion_tokens,
2809
- input_tokens: result?.usage?.prompt_tokens,
2810
- total_tokens: result?.usage?.total_tokens
2811
- };
2812
- return BaseLlmOutput2({
2813
- id,
2814
- name,
2815
- created,
2816
- usage,
2817
- stopReason,
2818
- content,
2819
- options
2820
- });
2821
- }
2822
-
2823
- // src/llm/output/claude.ts
2824
- function formatResult2(response) {
2825
- const content = response?.content || [];
2826
- const out = [];
2827
- for (let i = 0; i < content.length; i++) {
2828
- const result = content[i];
2829
- if (result.type === "text") {
2830
- out.push({
2831
- type: "text",
2832
- text: result.text
2833
- });
2834
- } else if (result.type === "tool_use") {
2835
- out.push({
2836
- functionId: result.id,
2837
- type: "function_use",
2838
- name: result.name,
2839
- input: result.input
2840
- });
2841
- }
2842
- }
2843
- return out;
2844
- }
2845
- function OutputAnthropicClaude3Chat(result, _config) {
2846
- const id = result.id;
2847
- const name = result.model || _config?.model || "anthropic.unknown";
2848
- const stopReason = result.stop_reason;
2849
- const content = formatResult2(result);
2850
- const usage = {
2851
- input_tokens: result?.usage?.input_tokens,
2852
- output_tokens: result?.usage?.output_tokens,
2853
- total_tokens: result?.usage?.input_tokens + result?.usage?.input_tokens
2854
- };
2855
- return BaseLlmOutput2({
2856
- id,
2857
- name,
2858
- usage,
2859
- stopReason,
2860
- content
2861
- });
2862
- }
2863
-
2864
- // src/llm/output/llama.ts
2865
- function OutputMetaLlama3Chat(result, _config) {
2866
- const name = _config?.model || "meta";
2867
- const stopReason = result.stop_reason;
2868
- const content = [
2869
- { type: "text", text: result.generation }
2870
- ];
2871
- const usage = {
2872
- output_tokens: result?.generation_token_count,
2873
- input_tokens: result?.prompt_token_count,
2874
- total_tokens: result?.generation_token_count + result?.prompt_token_count
2875
- };
2876
- return BaseLlmOutput2({
2877
- name,
2878
- usage,
2879
- stopReason,
2880
- content
2881
- });
2882
- }
2883
-
2884
- // src/llm/output/default.ts
2885
- function OutputDefault(result, _config) {
2886
- const name = _config.model || "unknown";
2887
- const stopReason = result?.stopReason || "stop";
2888
- const content = [];
2889
- if (result?.text) {
2890
- content.push({ type: "text", text: result.text });
2891
- }
2892
- const usage = {
2893
- output_tokens: result?.output_tokens || 0,
2894
- input_tokens: result?.input_tokens || 0,
2895
- total_tokens: (result?.input_tokens || 0) + (result?.output_tokens || 0)
2896
- };
2897
- return BaseLlmOutput2({
2898
- name,
2899
- usage,
2900
- stopReason,
2901
- content
2902
- });
2903
- }
2904
-
2905
- // src/llm/output/xai.ts
2906
- function formatResult3(result) {
2907
- if (typeof result?.message?.content === "string") {
2908
- return {
2909
- type: "text",
2910
- text: result.message.content
2911
- };
2912
- } else if (result?.message && "tool_calls" in result.message) {
2913
- const tool_calls = result.message.tool_calls;
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
- }
2923
- }
2924
- }
2925
- return {
2926
- type: "text",
2927
- text: ""
2928
- };
2929
- }
2930
- function OutputXAIChat(result, _config) {
2931
- const id = result.id;
2932
- const name = result?.model;
2933
- const created = result.created;
2934
- const [_content, ..._options] = result?.choices || [];
2935
- const stopReason = _content?.finish_reason;
2936
- const content = formatContent(_content, formatResult3);
2937
- const options = formatOptions(_options, formatResult3);
2938
- const usage = {
2939
- output_tokens: result?.usage?.completion_tokens,
2940
- input_tokens: result?.usage?.prompt_tokens,
2941
- total_tokens: result?.usage?.total_tokens
2942
- };
2943
- return BaseLlmOutput2({
2944
- id,
2945
- name,
2946
- created,
2947
- usage,
2948
- stopReason,
2949
- content,
2950
- options
2951
- });
2952
- }
2953
-
2954
- // src/llm/output/_utils/combineJsonl.ts
2955
- function combineJsonl(jsonl) {
2956
- const lines = jsonl.trim().split("\n").map((line) => line.trim()).filter((line) => line.length > 0).map((line) => {
2957
- try {
2958
- return JSON.parse(line);
2959
- } catch (e) {
2960
- throw new Error(`Invalid JSON: ${line}`);
2961
- }
2962
- });
2963
- if (lines.length === 0) {
2964
- throw new Error("No JSON lines provided.");
2911
+ response: {
2912
+ result: message.content
2913
+ }
2914
+ }
2915
+ });
2916
+ delete message.id;
2965
2917
  }
2966
- lines.sort(
2967
- (a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime()
2968
- );
2969
- let combinedContent = lines.map((line) => line?.message?.content ?? "").join("");
2970
- combinedContent = combinedContent.replace(/\\u003c/g, "<").replace(/\\u003e/g, ">");
2971
- const finalLine = lines.find((line) => line.done === true);
2972
- if (!finalLine) {
2973
- throw new Error("No line found where done = true.");
2918
+ if (message?.function_call) {
2919
+ const { function_call } = message;
2920
+ const toolsArr = Array.isArray(function_call) ? function_call : [function_call];
2921
+ role = "model";
2922
+ parts.push(
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;
2974
2934
  }
2975
- const result = {
2976
- model: finalLine.model,
2977
- created_at: finalLine.created_at,
2978
- message: {
2979
- role: finalLine?.message?.role || "assistant",
2980
- content: combinedContent
2981
- },
2982
- done_reason: finalLine.done_reason,
2983
- done: finalLine.done,
2984
- total_duration: finalLine.total_duration,
2985
- load_duration: finalLine.load_duration,
2986
- prompt_eval_count: finalLine.prompt_eval_count,
2987
- prompt_eval_duration: finalLine.prompt_eval_duration,
2988
- eval_count: finalLine.eval_count,
2989
- eval_duration: finalLine.eval_duration
2990
- };
2991
- const content = {
2992
- type: "text",
2993
- text: combinedContent
2994
- };
2995
2935
  return {
2996
- lines,
2997
- result,
2998
- content
2936
+ role,
2937
+ parts
2999
2938
  };
3000
2939
  }
3001
2940
 
3002
- // src/llm/output/ollama.ts
3003
- function OutputOllamaChat(result, _config) {
3004
- const combined = combineJsonl(result);
3005
- const id = `${combined.result.model}.${combined.result.created_at}`;
3006
- const name = combined.result.model || _config?.model || "ollama.unknown";
3007
- const created = (/* @__PURE__ */ new Date(`${combined.result.created_at}`)).getTime();
3008
- const stopReason = `${combined?.result?.done_reason || "stop"}`;
3009
- const content = [combined.content];
3010
- const usage = {
3011
- output_tokens: 0,
3012
- input_tokens: 0,
3013
- total_tokens: 0
3014
- };
3015
- return BaseLlmOutput2({
3016
- id,
3017
- name,
3018
- created,
3019
- usage,
3020
- stopReason,
3021
- content,
3022
- options: []
3023
- });
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");
3024
2973
  }
3025
2974
 
3026
2975
  // src/llm/output/google.gemini/formatResult.ts
3027
- function formatResult4(result, id) {
2976
+ function formatResult3(result, id) {
3028
2977
  const { parts = [] } = result?.content || {};
3029
2978
  const out = [];
3030
2979
  for (let i = 0; i < parts.length; i++) {
@@ -3049,18 +2998,18 @@ function formatResult4(result, id) {
3049
2998
  // src/llm/output/google.gemini/index.ts
3050
2999
  function OutputGoogleGeminiChat(result, _config) {
3051
3000
  const id = result.responseId;
3052
- const name = result.modelVersion || _config?.model || "gemini";
3001
+ const name = result.modelVersion || _config?.options.model?.default || "gemini";
3053
3002
  const created = (/* @__PURE__ */ new Date()).getTime();
3054
3003
  const [_content, ..._options] = result?.candidates || [];
3055
3004
  const stopReason = _content?.finishReason?.toLowerCase();
3056
- const content = formatResult4(_content, id);
3057
- const options = formatOptions(_options, formatResult4);
3005
+ const content = formatResult3(_content, id);
3006
+ const options = formatOptions(_options, formatResult3);
3058
3007
  const usage = {
3059
3008
  output_tokens: result?.usageMetadata?.candidatesTokenCount,
3060
3009
  input_tokens: result?.usageMetadata?.promptTokenCount,
3061
3010
  total_tokens: result?.usageMetadata?.totalTokenCount
3062
3011
  };
3063
- return BaseLlmOutput2({
3012
+ return {
3064
3013
  id,
3065
3014
  name,
3066
3015
  created,
@@ -3068,38 +3017,152 @@ function OutputGoogleGeminiChat(result, _config) {
3068
3017
  stopReason,
3069
3018
  content,
3070
3019
  options
3071
- });
3020
+ };
3072
3021
  }
3073
3022
 
3074
- // src/llm/output/index.ts
3075
- function normalizeLlmOutputToInternalFormat(config, response) {
3076
- switch (config?.key) {
3077
- case "openai.chat.v1":
3078
- case "openai.chat-mock.v1":
3079
- return OutputOpenAIChat(response, config);
3080
- case "anthropic.chat.v1":
3081
- case "amazon:anthropic.chat.v1":
3082
- return OutputAnthropicClaude3Chat(response, config);
3083
- case "amazon:meta.chat.v1":
3084
- return OutputMetaLlama3Chat(response, config);
3085
- // case "amazon:nova.chat.v1":
3086
- // return OutputDefault(response, config);
3087
- case "xai.chat.v1":
3088
- return OutputXAIChat(response, config);
3089
- case "ollama.chat.v1":
3090
- return OutputOllamaChat(response, config);
3091
- case "google.chat.v1":
3092
- return OutputGoogleGeminiChat(response, config);
3093
- case "deepseek.chat.v1":
3094
- return OutputOpenAIChat(response, config);
3095
- // use oai for now
3096
- default: {
3097
- if (config?.key?.startsWith("custom:")) {
3098
- return OutputDefault(response, config);
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;
3099
3061
  }
3100
- throw new Error("Unsupported provider");
3101
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"
3141
+ });
3142
+ }
3143
+ const pick2 = configs[provider];
3144
+ if (pick2) {
3145
+ return pick2;
3102
3146
  }
3147
+ throw new LlmExeError(`Invalid provider: ${provider}`, "unknown", {
3148
+ provider,
3149
+ error: `Invalid provider: ${provider}`,
3150
+ resolution: "Provide a valid provider"
3151
+ });
3152
+ }
3153
+
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}`;
3164
+ }
3165
+ );
3103
3166
  }
3104
3167
 
3105
3168
  // src/utils/modules/debug.ts
@@ -3125,7 +3188,15 @@ function debug(...args) {
3125
3188
  logs.push(arg.toString());
3126
3189
  } else {
3127
3190
  try {
3128
- 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);
3129
3200
  } catch (error) {
3130
3201
  console.error("Error parsing object:", error);
3131
3202
  }
@@ -3173,7 +3244,8 @@ async function apiRequest(url, options) {
3173
3244
  }
3174
3245
  throw new Error(message);
3175
3246
  }
3176
- if (response.headers.get("content-type")?.includes("application/json")) {
3247
+ const contentType = response.headers.get("content-type");
3248
+ if (contentType?.includes("application/json")) {
3177
3249
  const responseData = await response.json();
3178
3250
  return responseData;
3179
3251
  } else {
@@ -3190,20 +3262,26 @@ async function apiRequest(url, options) {
3190
3262
  function convertDotNotation(obj) {
3191
3263
  const result = {};
3192
3264
  for (const key in obj) {
3193
- if (obj.hasOwnProperty(key)) {
3194
- if (key.includes(".")) {
3195
- const keys = key.split(".");
3196
- let currentLevel = result;
3197
- for (let i = 0; i < keys.length; i++) {
3198
- if (i === keys.length - 1) {
3199
- currentLevel[keys[i]] = obj[key];
3200
- } else {
3201
- currentLevel[keys[i]] = currentLevel[keys[i]] || {};
3202
- 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] = {};
3203
3282
  }
3283
+ currentLevel = currentLevel[currentKey];
3204
3284
  }
3205
- } else {
3206
- result[key] = obj[key];
3207
3285
  }
3208
3286
  }
3209
3287
  }
@@ -3220,8 +3298,8 @@ function mapBody(template, body) {
3220
3298
  const { key: providerSpecificKey, default: defaultValue } = providerSpecificSettings;
3221
3299
  if (providerSpecificKey) {
3222
3300
  let valueForThisKey = body[genericInputKey];
3223
- if (providerSpecificSettings.sanitize && typeof providerSpecificSettings.sanitize === "function") {
3224
- valueForThisKey = providerSpecificSettings.sanitize(
3301
+ if (providerSpecificSettings.transform && typeof providerSpecificSettings.transform === "function") {
3302
+ valueForThisKey = providerSpecificSettings.transform(
3225
3303
  valueForThisKey,
3226
3304
  Object.freeze({ ...body }),
3227
3305
  output
@@ -3245,28 +3323,70 @@ var import_sha256_js = require("@aws-crypto/sha256-js");
3245
3323
 
3246
3324
  // src/utils/modules/runWithTemporaryEnv.ts
3247
3325
  async function runWithTemporaryEnv(env, handler) {
3248
- const previousEnv = { ...process.env };
3326
+ const modifiedKeys = [];
3327
+ const originalValues = {};
3328
+ const envBefore = { ...process.env };
3249
3329
  try {
3250
- 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
+ }
3251
3361
  const value = await handler();
3252
3362
  return value;
3253
3363
  } finally {
3254
- 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
+ }
3255
3372
  }
3256
3373
  }
3257
3374
 
3258
3375
  // src/utils/modules/getAwsAuthorizationHeaders.ts
3259
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
+ }
3260
3380
  const providerChain = (0, import_credential_providers.fromNodeProviderChain)();
3261
3381
  const credentials = await runWithTemporaryEnv(
3262
3382
  () => {
3263
- if (props.awsAccessKey) {
3383
+ if (props.awsAccessKey && typeof props.awsAccessKey === "string") {
3264
3384
  process.env["AWS_ACCESS_KEY_ID"] = props.awsAccessKey;
3265
3385
  }
3266
- if (props.awsSecretKey) {
3386
+ if (props.awsSecretKey && typeof props.awsSecretKey === "string") {
3267
3387
  process.env["AWS_SECRET_ACCESS_KEY"] = props.awsSecretKey;
3268
3388
  }
3269
- if (props.awsSessionToken) {
3389
+ if (props.awsSessionToken && typeof props.awsSessionToken === "string") {
3270
3390
  process.env["AWS_SESSION_TOKEN"] = props.awsSessionToken;
3271
3391
  }
3272
3392
  },
@@ -3296,8 +3416,21 @@ async function getAwsAuthorizationHeaders(req, props) {
3296
3416
  // src/llm/_utils.parseHeaders.ts
3297
3417
  async function parseHeaders(config, replacements, payload) {
3298
3418
  const replace = replaceTemplateStringSimple(config.headers, replacements);
3299
- const parse = replace ? JSON.parse(replace) : {};
3300
- 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);
3301
3434
  if (config.provider.startsWith("amazon:") || config.provider.startsWith("amazon.")) {
3302
3435
  const url = payload.url;
3303
3436
  return getAwsAuthorizationHeaders(
@@ -3318,122 +3451,129 @@ async function parseHeaders(config, replacements, payload) {
3318
3451
  }
3319
3452
  }
3320
3453
 
3321
- // src/llm/output/_utils/cleanJsonSchemaFor.ts
3322
- var providerFieldExclusions = {
3323
- "openai.chat": ["default"],
3324
- // fields to exclude for openai.chat
3325
- "anthropic.chat": []
3326
- // fields to exclude for openai.chat
3327
- };
3328
- function cleanJsonSchemaFor(schema = {}, provider) {
3329
- const clone = deepClone(schema);
3330
- 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() {
3331
3507
  return {
3332
- type: "object",
3333
- properties: {},
3334
- 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
3335
3515
  };
3336
3516
  }
3337
- const exclusions = providerFieldExclusions[provider] || [];
3338
- function removeDisallowedFields(obj) {
3339
- if (Array.isArray(obj)) {
3340
- return obj.map(removeDisallowedFields);
3341
- } else if (typeof obj === "object" && obj !== null) {
3342
- return Object.keys(obj).reduce((acc, key) => {
3343
- if (!exclusions.includes(key)) {
3344
- acc[key] = removeDisallowedFields(obj[key]);
3345
- }
3346
- return acc;
3347
- }, {});
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 };
3348
3544
  }
3349
- return obj;
3350
3545
  }
3351
- 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;
3352
3564
  }
3353
3565
 
3354
3566
  // src/llm/llm.call.ts
3355
3567
  async function useLlm_call(state, messages, _options) {
3356
3568
  const config = getLlmConfig(state.key);
3357
- const { functionCallStrictInput = false } = _options || {};
3358
- const input = mapBody(
3569
+ const transformBody = mapBody(
3359
3570
  config.mapBody,
3360
3571
  Object.assign({}, state, {
3361
3572
  prompt: messages
3362
3573
  })
3363
3574
  );
3364
- if (_options && _options?.jsonSchema) {
3365
- if (state.provider.startsWith("openai")) {
3366
- const curr = input["response_format"] || {};
3367
- input["response_format"] = Object.assign(curr, {
3368
- type: "json_schema",
3369
- json_schema: {
3370
- name: "output",
3371
- strict: !!functionCallStrictInput,
3372
- schema: cleanJsonSchemaFor(_options?.jsonSchema, "openai.chat")
3373
- }
3374
- });
3375
- }
3376
- }
3377
- if (_options && _options?.functionCall) {
3378
- if (state.provider.startsWith("anthropic")) {
3379
- if (_options?.functionCall === "none") {
3380
- _options.functions = [];
3381
- } else if (_options?.functionCall === "auto" || _options?.functionCall === "any") {
3382
- input["tool_choice"] = { type: _options?.functionCall };
3383
- } else {
3384
- input["tool_choice"] = _options?.functionCall;
3385
- }
3386
- } else if (state.provider.startsWith("openai")) {
3387
- input["tool_choice"] = normalizeFunctionCall(
3388
- _options?.functionCall,
3389
- "openai"
3390
- );
3391
- } else if (state.provider.startsWith("google")) {
3392
- input["toolConfig"] = {
3393
- functionCallingConfig: {
3394
- mode: normalizeFunctionCall(_options?.functionCall, "google")
3395
- }
3396
- };
3397
- }
3398
- }
3399
- if (_options && _options?.functions?.length) {
3400
- if (state.provider.startsWith("anthropic")) {
3401
- input["tools"] = _options.functions.map((f) => ({
3402
- name: f.name,
3403
- description: f.description,
3404
- input_schema: cleanJsonSchemaFor(f.parameters, "anthropic.chat")
3405
- }));
3406
- } else if (state.provider.startsWith("openai")) {
3407
- input["tools"] = _options.functions.map((f) => {
3408
- const props = {
3409
- name: f?.name,
3410
- description: f?.description,
3411
- parameters: f?.parameters
3412
- };
3413
- return {
3414
- type: "function",
3415
- function: Object.assign(
3416
- props,
3417
- {
3418
- parameters: cleanJsonSchemaFor(props.parameters, "openai.chat")
3419
- },
3420
- { strict: functionCallStrictInput }
3421
- )
3422
- };
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
- ];
3434
- }
3435
- }
3436
- const body = JSON.stringify(input);
3575
+ const applyOptions = mapOptions(transformBody, _options, config);
3576
+ const body = JSON.stringify(applyOptions);
3437
3577
  const url = replaceTemplateStringSimple(config.endpoint, state);
3438
3578
  const headers = await parseHeaders(config, state, {
3439
3579
  url,
@@ -3460,7 +3600,9 @@ async function useLlm_call(state, messages, _options) {
3460
3600
  body,
3461
3601
  headers
3462
3602
  });
3463
- return normalizeLlmOutputToInternalFormat(state, response);
3603
+ const { transformResponse = OutputDefault } = config;
3604
+ const normalized = transformResponse(response, config);
3605
+ return BaseLlmOutput(normalized);
3464
3606
  }
3465
3607
 
3466
3608
  // src/llm/_utils.stateFromOptions.ts
@@ -3603,6 +3745,80 @@ function useLlm(provider, options = {}) {
3603
3745
  const config = getLlmConfig(provider);
3604
3746
  return apiRequestWrapper(config, options, useLlm_call);
3605
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
+ }
3606
3822
 
3607
3823
  // src/embedding/config.ts
3608
3824
  var embeddingConfigs = {
@@ -3635,7 +3851,8 @@ var embeddingConfigs = {
3635
3851
  encodingFormat: {
3636
3852
  key: "encoding_format"
3637
3853
  }
3638
- }
3854
+ },
3855
+ transformResponse: OpenAiEmbedding
3639
3856
  },
3640
3857
  "amazon.embedding.v1": {
3641
3858
  key: "amazon.embedding.v1",
@@ -3662,7 +3879,8 @@ var embeddingConfigs = {
3662
3879
  dimensions: {
3663
3880
  key: "dimensions"
3664
3881
  }
3665
- }
3882
+ },
3883
+ transformResponse: AmazonTitanEmbedding
3666
3884
  }
3667
3885
  };
3668
3886
  function getEmbeddingConfig(provider) {
@@ -3676,77 +3894,6 @@ function getEmbeddingConfig(provider) {
3676
3894
  throw new Error(`Invalid provider: ${provider}`);
3677
3895
  }
3678
3896
 
3679
- // src/embedding/output/BaseEmbeddingOutput.ts
3680
- function BaseEmbeddingOutput(result) {
3681
- const __result = Object.freeze({
3682
- id: result.id || (0, import_uuid.v4)(),
3683
- model: result.model,
3684
- usage: result.usage,
3685
- embedding: [...result?.embedding || []],
3686
- created: result?.created || (/* @__PURE__ */ new Date()).getTime()
3687
- });
3688
- function getResult() {
3689
- return {
3690
- id: __result.id,
3691
- model: __result.model,
3692
- created: __result.created,
3693
- usage: __result.usage,
3694
- embedding: __result.embedding
3695
- };
3696
- }
3697
- function getEmbedding(index) {
3698
- if (index && index > 0) {
3699
- const arr = __result?.embedding;
3700
- const val = arr[index];
3701
- return val ? val : [];
3702
- }
3703
- return __result.embedding[0];
3704
- }
3705
- return {
3706
- getEmbedding,
3707
- getResult
3708
- };
3709
- }
3710
-
3711
- // src/embedding/output/AmazonTitan.ts
3712
- function AmazonTitanEmbedding(result, config) {
3713
- const __result = deepClone(result);
3714
- const model = config.model || "amazon.unknown";
3715
- const created = (/* @__PURE__ */ new Date()).getTime();
3716
- const embedding = [__result.embedding];
3717
- const usage = {
3718
- output_tokens: 0,
3719
- input_tokens: __result.inputTextTokenCount,
3720
- total_tokens: __result.inputTextTokenCount
3721
- };
3722
- return BaseEmbeddingOutput({
3723
- model,
3724
- created,
3725
- usage,
3726
- embedding
3727
- });
3728
- }
3729
-
3730
- // src/embedding/output/OpenAiEmbedding.ts
3731
- function OpenAiEmbedding(result, config) {
3732
- const __result = deepClone(result);
3733
- const model = __result.model || config.model || "openai.unknown";
3734
- const created = (/* @__PURE__ */ new Date()).getTime();
3735
- const results = result?.data || [];
3736
- const embedding = results.map((a) => a.embedding);
3737
- const usage = {
3738
- output_tokens: 0,
3739
- input_tokens: result?.usage?.prompt_tokens,
3740
- total_tokens: result?.usage?.total_tokens
3741
- };
3742
- return BaseEmbeddingOutput({
3743
- model,
3744
- created,
3745
- usage,
3746
- embedding
3747
- });
3748
- }
3749
-
3750
3897
  // src/embedding/output/getEmbeddingOutputParser.ts
3751
3898
  function getEmbeddingOutputParser(config, response) {
3752
3899
  switch (config.key) {
@@ -4764,6 +4911,9 @@ var Dialogue = class extends BaseStateItem {
4764
4911
  * @returns this for chaining
4765
4912
  */
4766
4913
  addFromOutput(output) {
4914
+ if (!output || typeof output !== "object") {
4915
+ return this;
4916
+ }
4767
4917
  const result = "getResult" in output ? output.getResult() : output;
4768
4918
  if (!result || typeof result !== "object") {
4769
4919
  return this;
@@ -4900,6 +5050,7 @@ function createStateItem(name, defaultValue) {
4900
5050
  createEmbedding,
4901
5051
  createLlmExecutor,
4902
5052
  createLlmFunctionExecutor,
5053
+ createOpenAiCompatibleConfiguration,
4903
5054
  createParser,
4904
5055
  createPrompt,
4905
5056
  createState,
@@ -4910,5 +5061,6 @@ function createStateItem(name, defaultValue) {
4910
5061
  registerPartials,
4911
5062
  useExecutors,
4912
5063
  useLlm,
5064
+ useLlmConfiguration,
4913
5065
  utils
4914
5066
  });