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.mjs CHANGED
@@ -125,6 +125,10 @@ var BaseExecutor = class {
125
125
  */
126
126
  __publicField(this, "hooks");
127
127
  __publicField(this, "allowedHooks", [hookOnComplete, hookOnError, hookOnSuccess]);
128
+ /**
129
+ * @property maxHooksPerEvent - Maximum number of hooks allowed per event
130
+ */
131
+ __publicField(this, "maxHooksPerEvent", 100);
128
132
  this.id = uuidv4();
129
133
  this.type = type;
130
134
  this.name = name;
@@ -230,6 +234,11 @@ var BaseExecutor = class {
230
234
  const _hooks = Array.isArray(hookInput) ? hookInput : [hookInput];
231
235
  for (const hook of _hooks) {
232
236
  if (hook && typeof hook === "function" && !this.hooks[hookKey].find((h) => h === hook)) {
237
+ if (this.hooks[hookKey].length >= this.maxHooksPerEvent) {
238
+ throw new Error(
239
+ `Maximum number of hooks (${this.maxHooksPerEvent}) reached for event "${String(hookKey)}". Consider removing unused hooks or increasing the limit.`
240
+ );
241
+ }
233
242
  this.hooks[hookKey].push(hook);
234
243
  }
235
244
  }
@@ -257,10 +266,18 @@ var BaseExecutor = class {
257
266
  }
258
267
  once(eventName, fn) {
259
268
  if (typeof fn !== "function") return this;
269
+ if (this.hooks[eventName] && this.hooks[eventName].length >= this.maxHooksPerEvent) {
270
+ throw new Error(
271
+ `Maximum number of hooks (${this.maxHooksPerEvent}) reached for event "${String(eventName)}". Consider removing unused hooks or increasing the limit.`
272
+ );
273
+ }
260
274
  const onceWrapper = (...args) => {
261
275
  fn(...args);
262
276
  this.off(eventName, onceWrapper);
263
277
  };
278
+ if (!this.hooks[eventName]) {
279
+ this.hooks[eventName] = [];
280
+ }
264
281
  this.hooks[eventName].push(onceWrapper);
265
282
  return this;
266
283
  }
@@ -271,6 +288,40 @@ var BaseExecutor = class {
271
288
  getTraceId() {
272
289
  return this.traceId;
273
290
  }
291
+ /**
292
+ * Clear all hooks for a specific event or all events
293
+ * Useful for preventing memory leaks in long-running processes
294
+ * @param eventName - The event name to clear hooks for
295
+ */
296
+ clearHooks(eventName) {
297
+ if (eventName) {
298
+ if (this.hooks[eventName]) {
299
+ this.hooks[eventName] = [];
300
+ }
301
+ } else {
302
+ for (const key of this.allowedHooks) {
303
+ if (this.hooks[key]) {
304
+ this.hooks[key] = [];
305
+ }
306
+ }
307
+ }
308
+ return this;
309
+ }
310
+ /**
311
+ * Get the count of hooks for monitoring memory usage
312
+ * @param eventName - Optional event name to get count for
313
+ * @returns Hook count for specific event or all events
314
+ */
315
+ getHookCount(eventName) {
316
+ if (eventName) {
317
+ return this.hooks[eventName]?.length || 0;
318
+ }
319
+ const counts = {};
320
+ for (const key of this.allowedHooks) {
321
+ counts[key] = this.hooks[key]?.length || 0;
322
+ }
323
+ return counts;
324
+ }
274
325
  };
275
326
 
276
327
  // src/utils/modules/inferFunctionName.ts
@@ -2057,6 +2108,63 @@ function getEnvironmentVariable(name) {
2057
2108
  }
2058
2109
  }
2059
2110
 
2111
+ // src/llm/output/_util.ts
2112
+ function formatOptions(response, handler) {
2113
+ const out = [];
2114
+ for (const item of response) {
2115
+ const result = handler(item);
2116
+ if (result) {
2117
+ out.push([result]);
2118
+ }
2119
+ }
2120
+ return out;
2121
+ }
2122
+
2123
+ // src/llm/output/openai.ts
2124
+ function formatResult(result) {
2125
+ const out = [];
2126
+ if (typeof result?.message?.content === "string") {
2127
+ out.push({
2128
+ type: "text",
2129
+ text: result.message.content
2130
+ });
2131
+ }
2132
+ if (result?.message?.tool_calls) {
2133
+ for (const call of result.message.tool_calls) {
2134
+ out.push({
2135
+ functionId: call.id,
2136
+ type: "function_use",
2137
+ name: call.function.name,
2138
+ input: maybeParseJSON(call.function.arguments)
2139
+ });
2140
+ }
2141
+ }
2142
+ return out;
2143
+ }
2144
+ function OutputOpenAIChat(result, _config) {
2145
+ const id = result.id;
2146
+ const name = result.model || _config?.options.model?.default || "openai.unknown";
2147
+ const created = result.created;
2148
+ const [_content, ..._options] = result?.choices || [];
2149
+ const stopReason = _content?.finish_reason;
2150
+ const content = formatResult(_content);
2151
+ const options = formatOptions(_options, formatResult);
2152
+ const usage = {
2153
+ output_tokens: result?.usage?.completion_tokens,
2154
+ input_tokens: result?.usage?.prompt_tokens,
2155
+ total_tokens: result?.usage?.total_tokens
2156
+ };
2157
+ return {
2158
+ id,
2159
+ name,
2160
+ created,
2161
+ usage,
2162
+ stopReason,
2163
+ content,
2164
+ options
2165
+ };
2166
+ }
2167
+
2060
2168
  // src/llm/config/openai/promptSanitizeMessageCallback.ts
2061
2169
  function openaiPromptMessageCallback(_message) {
2062
2170
  let message = { ..._message };
@@ -2090,38 +2198,127 @@ function openaiPromptSanitize(_messages, _inputBodyObj, _outputObj) {
2090
2198
  return _messages.map(openaiPromptMessageCallback);
2091
2199
  }
2092
2200
 
2093
- // src/llm/config/openai/index.ts
2094
- var openAiChatV1 = {
2095
- key: "openai.chat.v1",
2096
- provider: "openai.chat",
2097
- endpoint: `https://api.openai.com/v1/chat/completions`,
2098
- options: {
2099
- prompt: {},
2100
- topP: {},
2101
- useJson: {},
2102
- openAiApiKey: {
2103
- default: getEnvironmentVariable("OPENAI_API_KEY")
2201
+ // src/llm/output/_utils/cleanJsonSchemaFor.ts
2202
+ var providerFieldExclusions = {
2203
+ "openai.chat": ["default"],
2204
+ // fields to exclude for openai.chat, xai, deepseek
2205
+ "anthropic.chat": [],
2206
+ "google.chat": ["additionalProperties"]
2207
+ };
2208
+ function cleanJsonSchemaFor(schema = {}, provider) {
2209
+ const clone = deepClone(schema);
2210
+ if (Object.keys(clone).length === 0) {
2211
+ return {
2212
+ type: "object",
2213
+ properties: {},
2214
+ required: []
2215
+ };
2216
+ }
2217
+ const exclusions = providerFieldExclusions[provider] || [];
2218
+ function removeDisallowedFields(obj) {
2219
+ if (Array.isArray(obj)) {
2220
+ return obj.map(removeDisallowedFields);
2221
+ } else if (typeof obj === "object" && obj !== null) {
2222
+ return Object.keys(obj).reduce((acc, key) => {
2223
+ if (!exclusions.includes(key)) {
2224
+ acc[key] = removeDisallowedFields(obj[key]);
2225
+ }
2226
+ return acc;
2227
+ }, {});
2104
2228
  }
2105
- },
2106
- method: "POST",
2107
- headers: `{"Authorization":"Bearer {{openAiApiKey}}", "Content-Type": "application/json" }`,
2108
- mapBody: {
2109
- prompt: {
2110
- key: "messages",
2111
- sanitize: openaiPromptSanitize
2229
+ return obj;
2230
+ }
2231
+ return removeDisallowedFields(clone);
2232
+ }
2233
+
2234
+ // src/llm/config/openai/compatible.ts
2235
+ function createOpenAiCompatibleConfiguration(overrides) {
2236
+ const [apiKeyPropertyKey, apiKeyPropertyValue] = overrides.apiKeyMapping;
2237
+ const config = {
2238
+ key: overrides.key,
2239
+ provider: overrides.provider,
2240
+ endpoint: overrides.endpoint,
2241
+ options: {
2242
+ prompt: {},
2243
+ effort: {},
2244
+ topP: {},
2245
+ useJson: {},
2246
+ [apiKeyPropertyKey]: {
2247
+ default: getEnvironmentVariable(apiKeyPropertyValue)
2248
+ }
2112
2249
  },
2113
- model: {
2114
- key: "model"
2250
+ method: "POST",
2251
+ headers: `{"Authorization":"Bearer {{${apiKeyPropertyKey}}}", "Content-Type": "application/json" }`,
2252
+ mapBody: {
2253
+ prompt: {
2254
+ key: "messages",
2255
+ transform: openaiPromptSanitize
2256
+ },
2257
+ model: {
2258
+ key: "model"
2259
+ },
2260
+ topP: {
2261
+ key: "top_p"
2262
+ },
2263
+ useJson: {
2264
+ key: "response_format.type",
2265
+ transform: (v) => v ? "json_object" : "text"
2266
+ },
2267
+ effort: {
2268
+ key: "reasoning_effort",
2269
+ transform: (v, _s) => {
2270
+ if (
2271
+ // only supported reasoning models
2272
+ ["gpt-5"].includes(_s.model) && typeof v === "string" && ["minimal", "low", "medium", "high"].includes(v)
2273
+ ) {
2274
+ return v;
2275
+ }
2276
+ return void 0;
2277
+ }
2278
+ }
2115
2279
  },
2116
- topP: {
2117
- key: "top_p"
2280
+ mapOptions: {
2281
+ jsonSchema: (schema, options, currentInput) => ({
2282
+ response_format: {
2283
+ ...currentInput?.response_format || {},
2284
+ type: "json_schema",
2285
+ json_schema: {
2286
+ name: "output",
2287
+ strict: !!options?.functionCallStrictInput,
2288
+ schema: cleanJsonSchemaFor(schema, "openai.chat")
2289
+ }
2290
+ }
2291
+ }),
2292
+ functionCall: (call) => {
2293
+ if (call === "any") return { tool_choice: "required" };
2294
+ if (call === "none") return { tool_choice: "none" };
2295
+ if (call === "auto") return { tool_choice: "auto" };
2296
+ return { tool_choice: call };
2297
+ },
2298
+ functions: (functions, options) => ({
2299
+ tools: functions.map((f) => ({
2300
+ type: "function",
2301
+ function: {
2302
+ name: f.name,
2303
+ description: f.description,
2304
+ parameters: cleanJsonSchemaFor(f.parameters, "openai.chat"),
2305
+ strict: !!options?.functionCallStrictInput
2306
+ }
2307
+ }))
2308
+ })
2118
2309
  },
2119
- useJson: {
2120
- key: "response_format.type",
2121
- sanitize: (v) => v ? "json_object" : "text"
2122
- }
2123
- }
2124
- };
2310
+ transformResponse: overrides.transformResponse ?? OutputOpenAIChat
2311
+ };
2312
+ return config;
2313
+ }
2314
+
2315
+ // src/llm/config/openai/index.ts
2316
+ var openAiChatV1 = createOpenAiCompatibleConfiguration({
2317
+ key: "openai.chat.v1",
2318
+ provider: "openai.chat",
2319
+ endpoint: `https://api.openai.com/v1/chat/completions`,
2320
+ apiKeyMapping: ["openAiApiKey", "OPENAI_API_KEY"]
2321
+ });
2125
2322
  var openAiChatMockV1 = {
2126
2323
  key: "openai.chat-mock.v1",
2127
2324
  provider: "openai.chat-mock",
@@ -2148,9 +2345,10 @@ var openAiChatMockV1 = {
2148
2345
  },
2149
2346
  useJson: {
2150
2347
  key: "response_format.type",
2151
- sanitize: (v) => v ? "json_object" : "text"
2348
+ transform: (v) => v ? "json_object" : "text"
2152
2349
  }
2153
- }
2350
+ },
2351
+ transformResponse: OutputOpenAIChat
2154
2352
  };
2155
2353
  var openai = {
2156
2354
  "openai.chat.v1": openAiChatV1,
@@ -2228,8 +2426,75 @@ function anthropicPromptSanitize(_messages, _inputBodyObj, _outputObj) {
2228
2426
  ].map(anthropicPromptMessageCallback);
2229
2427
  }
2230
2428
 
2429
+ // src/llm/output/claude.ts
2430
+ function formatResult2(response) {
2431
+ const content = response?.content || [];
2432
+ const out = [];
2433
+ for (let i = 0; i < content.length; i++) {
2434
+ const result = content[i];
2435
+ if (result.type === "text") {
2436
+ out.push({
2437
+ type: "text",
2438
+ text: result.text
2439
+ });
2440
+ } else if (result.type === "tool_use") {
2441
+ out.push({
2442
+ functionId: result.id,
2443
+ type: "function_use",
2444
+ name: result.name,
2445
+ input: result.input
2446
+ });
2447
+ }
2448
+ }
2449
+ return out;
2450
+ }
2451
+ function OutputAnthropicClaude3Chat(result, _config) {
2452
+ const id = result.id;
2453
+ const name = result.model || _config?.options.model?.default || "anthropic.unknown";
2454
+ const stopReason = result.stop_reason;
2455
+ const content = formatResult2(result);
2456
+ const usage = {
2457
+ input_tokens: result?.usage?.input_tokens,
2458
+ output_tokens: result?.usage?.output_tokens,
2459
+ total_tokens: result?.usage?.input_tokens + result?.usage?.output_tokens
2460
+ };
2461
+ return {
2462
+ id,
2463
+ name,
2464
+ created: Date.now(),
2465
+ usage,
2466
+ stopReason,
2467
+ content
2468
+ };
2469
+ }
2470
+
2471
+ // src/llm/output/llama.ts
2472
+ function OutputMetaLlama3Chat(result, _config) {
2473
+ const id = uuidv4();
2474
+ const name = _config?.options?.model?.default || "meta";
2475
+ const created = (/* @__PURE__ */ new Date()).getTime();
2476
+ const stopReason = result.stop_reason;
2477
+ const content = [
2478
+ { type: "text", text: result.generation }
2479
+ ];
2480
+ const usage = {
2481
+ output_tokens: result?.generation_token_count,
2482
+ input_tokens: result?.prompt_token_count,
2483
+ total_tokens: result?.generation_token_count + result?.prompt_token_count
2484
+ };
2485
+ return {
2486
+ id,
2487
+ name,
2488
+ created,
2489
+ usage,
2490
+ stopReason,
2491
+ content,
2492
+ options: []
2493
+ };
2494
+ }
2495
+
2231
2496
  // src/llm/config/bedrock/index.ts
2232
- var ANTORPIC_BEDROCK_VERSION = "bedrock-2023-05-31";
2497
+ var ANTHROPIC_BEDROCK_VERSION = "bedrock-2023-05-31";
2233
2498
  var amazonAnthropicChatV1 = {
2234
2499
  key: "amazon:anthropic.chat.v1",
2235
2500
  provider: "amazon:anthropic.chat",
@@ -2250,7 +2515,7 @@ var amazonAnthropicChatV1 = {
2250
2515
  mapBody: {
2251
2516
  prompt: {
2252
2517
  key: "messages",
2253
- sanitize: anthropicPromptSanitize
2518
+ transform: anthropicPromptSanitize
2254
2519
  },
2255
2520
  topP: {
2256
2521
  key: "top_p"
@@ -2261,9 +2526,26 @@ var amazonAnthropicChatV1 = {
2261
2526
  },
2262
2527
  anthropic_version: {
2263
2528
  key: "anthropic_version",
2264
- default: ANTORPIC_BEDROCK_VERSION
2529
+ default: ANTHROPIC_BEDROCK_VERSION
2265
2530
  }
2266
- }
2531
+ },
2532
+ mapOptions: {
2533
+ functionCall: (call, _options) => {
2534
+ if (call === "none") return { _clearFunctions: true };
2535
+ if (call === "auto" || call === "any") {
2536
+ return { tool_choice: { type: call } };
2537
+ }
2538
+ return { tool_choice: call };
2539
+ },
2540
+ functions: (functions) => ({
2541
+ tools: functions.map((f) => ({
2542
+ name: f.name,
2543
+ description: f.description,
2544
+ input_schema: cleanJsonSchemaFor(f.parameters, "anthropic.chat")
2545
+ }))
2546
+ })
2547
+ },
2548
+ transformResponse: OutputAnthropicClaude3Chat
2267
2549
  };
2268
2550
  var amazonMetaChatV1 = {
2269
2551
  key: "amazon:meta.chat.v1",
@@ -2285,7 +2567,7 @@ var amazonMetaChatV1 = {
2285
2567
  mapBody: {
2286
2568
  prompt: {
2287
2569
  key: "prompt",
2288
- sanitize: (messages) => {
2570
+ transform: (messages) => {
2289
2571
  if (typeof messages === "string") {
2290
2572
  return messages;
2291
2573
  } else {
@@ -2305,7 +2587,8 @@ var amazonMetaChatV1 = {
2305
2587
  key: "max_gen_len",
2306
2588
  default: 2048
2307
2589
  }
2308
- }
2590
+ },
2591
+ transformResponse: OutputMetaLlama3Chat
2309
2592
  };
2310
2593
  var bedrock = {
2311
2594
  "amazon:anthropic.chat.v1": amazonAnthropicChatV1,
@@ -2344,16 +2627,65 @@ var anthropicChatV1 = {
2344
2627
  },
2345
2628
  prompt: {
2346
2629
  key: "messages",
2347
- sanitize: anthropicPromptSanitize
2630
+ transform: anthropicPromptSanitize
2631
+ },
2632
+ temperature: {
2633
+ key: "temperature"
2634
+ },
2635
+ topP: {
2636
+ key: "top_p"
2637
+ },
2638
+ topK: {
2639
+ key: "top_k"
2640
+ },
2641
+ stopSequences: {
2642
+ key: "stop_sequences"
2643
+ },
2644
+ stream: {
2645
+ key: "stream"
2646
+ },
2647
+ metadata: {
2648
+ key: "metadata"
2649
+ },
2650
+ serviceTier: {
2651
+ key: "service_tier"
2652
+ // Map camelCase to snake_case
2348
2653
  }
2349
- }
2654
+ },
2655
+ mapOptions: {
2656
+ functionCall: (call, _options) => {
2657
+ if (call === "none") return { _clearFunctions: true };
2658
+ if (call === "auto" || call === "any") {
2659
+ return { tool_choice: { type: call } };
2660
+ }
2661
+ return { tool_choice: call };
2662
+ },
2663
+ functions: (functions) => ({
2664
+ tools: functions.map((f) => ({
2665
+ name: f.name,
2666
+ description: f.description,
2667
+ input_schema: cleanJsonSchemaFor(f.parameters, "anthropic.chat")
2668
+ }))
2669
+ })
2670
+ },
2671
+ transformResponse: OutputAnthropicClaude3Chat
2350
2672
  };
2351
2673
  var anthropic = {
2352
2674
  "anthropic.chat.v1": anthropicChatV1,
2353
- "anthropic.claude-3-7-sonnet": withDefaultModel(
2675
+ // Claude 4 models (latest generation)
2676
+ "anthropic.claude-sonnet-4": withDefaultModel(
2354
2677
  anthropicChatV1,
2355
- "claude-3-7-sonnet-latest"
2678
+ "claude-sonnet-4-0"
2356
2679
  ),
2680
+ "anthropic.claude-opus-4": withDefaultModel(
2681
+ anthropicChatV1,
2682
+ "claude-opus-4-0"
2683
+ ),
2684
+ "anthropic.claude-3-7-sonnet": withDefaultModel(
2685
+ anthropicChatV1,
2686
+ "claude-3-7-sonnet-20250219"
2687
+ ),
2688
+ // Claude 3.5 models
2357
2689
  "anthropic.claude-3-5-sonnet": withDefaultModel(
2358
2690
  anthropicChatV1,
2359
2691
  "claude-3-5-sonnet-latest"
@@ -2362,54 +2694,103 @@ var anthropic = {
2362
2694
  anthropicChatV1,
2363
2695
  "claude-3-5-haiku-latest"
2364
2696
  ),
2697
+ // Deprecated
2365
2698
  "anthropic.claude-3-opus": withDefaultModel(
2366
2699
  anthropicChatV1,
2367
- "claude-3-opus-latest"
2700
+ "claude-3-opus-20240229"
2701
+ ),
2702
+ "anthropic.claude-3-haiku": withDefaultModel(
2703
+ anthropicChatV1,
2704
+ "claude-3-haiku-20240307"
2368
2705
  )
2369
2706
  };
2370
2707
 
2371
2708
  // src/llm/config/x/index.ts
2372
- var xaiChatV1 = {
2709
+ var xaiChatV1 = createOpenAiCompatibleConfiguration({
2373
2710
  key: "xai.chat.v1",
2374
2711
  provider: "xai.chat",
2375
2712
  endpoint: `https://api.x.ai/v1/chat/completions`,
2376
- options: {
2377
- prompt: {},
2378
- topP: {},
2379
- useJson: {},
2380
- xAiApiKey: {
2381
- default: getEnvironmentVariable("XAI_API_KEY")
2382
- }
2383
- },
2384
- method: "POST",
2385
- headers: `{"Authorization":"Bearer {{xAiApiKey}}", "Content-Type": "application/json" }`,
2386
- mapBody: {
2387
- prompt: {
2388
- key: "messages",
2389
- sanitize: (v) => {
2390
- if (typeof v === "string") {
2391
- return [{ role: "user", content: v }];
2392
- }
2393
- return v;
2394
- }
2395
- },
2396
- model: {
2397
- key: "model"
2398
- },
2399
- topP: {
2400
- key: "top_p"
2401
- },
2402
- useJson: {
2403
- key: "response_format.type",
2404
- sanitize: (v) => v ? "json_object" : "text"
2405
- }
2406
- }
2407
- };
2713
+ apiKeyMapping: ["xAiApiKey", "XAI_API_KEY"]
2714
+ });
2408
2715
  var xai = {
2409
2716
  "xai.chat.v1": xaiChatV1,
2410
- "xai.grok-2": withDefaultModel(xaiChatV1, "grok-2-latest")
2717
+ "xai.grok-2": withDefaultModel(xaiChatV1, "grok-2-latest"),
2718
+ "xai.grok-3": withDefaultModel(xaiChatV1, "grok-3"),
2719
+ "xai.grok-4": withDefaultModel(xaiChatV1, "grok-4")
2411
2720
  };
2412
2721
 
2722
+ // src/llm/output/_utils/combineJsonl.ts
2723
+ function combineJsonl(jsonl) {
2724
+ const lines = jsonl.trim().split("\n").map((line) => line.trim()).filter((line) => line.length > 0).map((line) => {
2725
+ try {
2726
+ return JSON.parse(line);
2727
+ } catch (e) {
2728
+ throw new Error(`Invalid JSON: ${line}`);
2729
+ }
2730
+ });
2731
+ if (lines.length === 0) {
2732
+ throw new Error("No JSON lines provided.");
2733
+ }
2734
+ lines.sort(
2735
+ (a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime()
2736
+ );
2737
+ let combinedContent = lines.map((line) => line?.message?.content ?? "").join("");
2738
+ combinedContent = combinedContent.replace(/\\u003c/g, "<").replace(/\\u003e/g, ">");
2739
+ const finalLine = lines.find((line) => line.done === true);
2740
+ if (!finalLine) {
2741
+ throw new Error("No line found where done = true.");
2742
+ }
2743
+ const result = {
2744
+ model: finalLine.model,
2745
+ created_at: finalLine.created_at,
2746
+ message: {
2747
+ role: finalLine?.message?.role || "assistant",
2748
+ content: combinedContent
2749
+ },
2750
+ done_reason: finalLine.done_reason,
2751
+ done: finalLine.done,
2752
+ total_duration: finalLine.total_duration,
2753
+ load_duration: finalLine.load_duration,
2754
+ prompt_eval_count: finalLine.prompt_eval_count,
2755
+ prompt_eval_duration: finalLine.prompt_eval_duration,
2756
+ eval_count: finalLine.eval_count,
2757
+ eval_duration: finalLine.eval_duration
2758
+ };
2759
+ const content = {
2760
+ type: "text",
2761
+ text: combinedContent
2762
+ };
2763
+ return {
2764
+ lines,
2765
+ result,
2766
+ content
2767
+ };
2768
+ }
2769
+
2770
+ // src/llm/output/ollama.ts
2771
+ function OutputOllamaChat(result, _config) {
2772
+ const combined = combineJsonl(result);
2773
+ const id = `${combined.result.model}.${combined.result.created_at}`;
2774
+ const name = combined.result.model || _config?.options.model?.default || "ollama.unknown";
2775
+ const created = (/* @__PURE__ */ new Date(`${combined.result.created_at}`)).getTime();
2776
+ const stopReason = `${combined?.result?.done_reason || "stop"}`;
2777
+ const content = [combined.content];
2778
+ const usage = {
2779
+ output_tokens: 0,
2780
+ input_tokens: 0,
2781
+ total_tokens: 0
2782
+ };
2783
+ return {
2784
+ id,
2785
+ name,
2786
+ created,
2787
+ usage,
2788
+ stopReason,
2789
+ content,
2790
+ options: []
2791
+ };
2792
+ }
2793
+
2413
2794
  // src/llm/config/ollama/index.ts
2414
2795
  var ollamaChatV1 = {
2415
2796
  key: "ollama.chat.v1",
@@ -2423,7 +2804,7 @@ var ollamaChatV1 = {
2423
2804
  mapBody: {
2424
2805
  prompt: {
2425
2806
  key: "messages",
2426
- sanitize: (v) => {
2807
+ transform: (v) => {
2427
2808
  if (typeof v === "string") {
2428
2809
  return [{ role: "user", content: v }];
2429
2810
  }
@@ -2433,7 +2814,8 @@ var ollamaChatV1 = {
2433
2814
  model: {
2434
2815
  key: "model"
2435
2816
  }
2436
- }
2817
+ },
2818
+ transformResponse: OutputOllamaChat
2437
2819
  };
2438
2820
  var ollama = {
2439
2821
  "ollama.chat.v1": ollamaChatV1,
@@ -2463,507 +2845,72 @@ function googleGeminiPromptMessageCallback(_message) {
2463
2845
  parts.push({
2464
2846
  functionResponse: {
2465
2847
  name: message.name,
2466
- response: {
2467
- result: message.content
2468
- }
2469
- }
2470
- });
2471
- delete message.id;
2472
- }
2473
- if (message?.function_call) {
2474
- const { function_call } = message;
2475
- const toolsArr = Array.isArray(function_call) ? function_call : [function_call];
2476
- role = "model";
2477
- parts.push(
2478
- ...toolsArr.map((call) => {
2479
- const { name, arguments: input } = call;
2480
- return {
2481
- functionCall: {
2482
- name,
2483
- args: maybeParseJSON(input)
2484
- }
2485
- };
2486
- })
2487
- );
2488
- delete message.function_call;
2489
- }
2490
- return {
2491
- role,
2492
- parts
2493
- };
2494
- }
2495
-
2496
- // src/llm/config/google/promptSanitize.ts
2497
- function googleGeminiPromptSanitize(_messages, _inputBodyObj, _outputObj) {
2498
- if (typeof _messages === "string") {
2499
- return [{ role: "user", parts: [{ text: _messages }] }];
2500
- }
2501
- if (Array.isArray(_messages)) {
2502
- if (_messages.length === 0) {
2503
- throw new Error("Empty messages array");
2504
- }
2505
- if (_messages.length === 1 && _messages[0].role === "system") {
2506
- return [{ role: "user", parts: [{ text: _messages[0].content }] }];
2507
- }
2508
- const hasSystemInstruction = _messages.some(
2509
- (message) => message.role === "system"
2510
- );
2511
- if (hasSystemInstruction) {
2512
- const theSystemInstructions = _messages.filter(
2513
- (message) => message.role === "system"
2514
- );
2515
- const withoutSystemInstructions = _messages.filter(
2516
- (message) => message.role !== "system"
2517
- );
2518
- _outputObj.system_instruction = {
2519
- parts: theSystemInstructions.map((message) => ({
2520
- text: message.content
2521
- }))
2522
- };
2523
- return withoutSystemInstructions.map(googleGeminiPromptMessageCallback);
2524
- }
2525
- return _messages.map(googleGeminiPromptMessageCallback);
2526
- }
2527
- throw new Error("Invalid messages format");
2528
- }
2529
-
2530
- // src/llm/config/google/index.ts
2531
- var googleGeminiChatV1 = {
2532
- key: "google.chat.v1",
2533
- provider: "google.chat",
2534
- endpoint: `https://generativelanguage.googleapis.com/v1beta/models/{{model}}:generateContent?key={{geminiApiKey}}`,
2535
- options: {
2536
- prompt: {},
2537
- // topP: {},
2538
- geminiApiKey: {
2539
- default: getEnvironmentVariable("GEMINI_API_KEY")
2540
- }
2541
- },
2542
- method: "POST",
2543
- headers: `{"Content-Type": "application/json" }`,
2544
- mapBody: {
2545
- prompt: {
2546
- key: "contents",
2547
- sanitize: googleGeminiPromptSanitize
2548
- }
2549
- // topP: {
2550
- // key: "top_p",
2551
- // }
2552
- }
2553
- };
2554
- var google = {
2555
- "google.chat.v1": googleGeminiChatV1,
2556
- "google.gemini-2.0-flash": withDefaultModel(
2557
- googleGeminiChatV1,
2558
- "gemini-2.0-flash"
2559
- ),
2560
- "google.gemini-2.0-flash-lite": withDefaultModel(
2561
- googleGeminiChatV1,
2562
- "gemini-2.0-flash-lite"
2563
- ),
2564
- "google.gemini-1.5-pro": withDefaultModel(
2565
- googleGeminiChatV1,
2566
- "gemini-1.5-pro"
2567
- )
2568
- };
2569
-
2570
- // src/llm/config/deepseek/index.ts
2571
- var deepseekChatV1 = {
2572
- key: "deepseek.chat.v1",
2573
- provider: "deepseek.chat",
2574
- endpoint: `https://api.deepseek.com/v1/chat/completions`,
2575
- options: {
2576
- prompt: {},
2577
- topP: {},
2578
- useJson: {},
2579
- deepseekApiKey: {
2580
- default: getEnvironmentVariable("DEEPSEEK_API_KEY")
2581
- }
2582
- },
2583
- method: "POST",
2584
- headers: `{"Authorization":"Bearer {{deepseekApiKey}}", "Content-Type": "application/json" }`,
2585
- mapBody: {
2586
- prompt: {
2587
- key: "messages",
2588
- sanitize: (v) => {
2589
- if (typeof v === "string") {
2590
- return [{ role: "user", content: v }];
2591
- }
2592
- return v;
2593
- }
2594
- },
2595
- model: {
2596
- key: "model"
2597
- },
2598
- topP: {
2599
- key: "top_p"
2600
- },
2601
- useJson: {
2602
- key: "response_format.type",
2603
- sanitize: (v) => v ? "json_object" : "text"
2604
- }
2605
- }
2606
- };
2607
- var deepseek = {
2608
- "deepseek.chat.v1": deepseekChatV1,
2609
- "deepseek.chat": withDefaultModel(deepseekChatV1, "deepseek-chat")
2610
- };
2611
-
2612
- // src/llm/config.ts
2613
- var configs = {
2614
- ...openai,
2615
- ...anthropic,
2616
- ...bedrock,
2617
- ...xai,
2618
- ...ollama,
2619
- ...google,
2620
- ...deepseek
2621
- };
2622
- function getLlmConfig(provider) {
2623
- if (!provider) {
2624
- throw new LlmExeError(`Missing provider`, "unknown", {
2625
- error: "Missing provider",
2626
- resolution: "Provide a valid provider"
2627
- });
2628
- }
2629
- const pick2 = configs[provider];
2630
- if (pick2) {
2631
- return pick2;
2632
- }
2633
- throw new LlmExeError(`Invalid provider: ${provider}`, "unknown", {
2634
- provider,
2635
- error: `Invalid provider: ${provider}`,
2636
- resolution: "Provide a valid provider"
2637
- });
2638
- }
2639
-
2640
- // src/llm/output/_utils/getResultContent.ts
2641
- function getResultContent(result, index) {
2642
- if (typeof index === "number" && index > 0) {
2643
- const arr = result?.options || [];
2644
- const val = arr[index];
2645
- return val ? val : [];
2646
- }
2647
- return [...result.content];
2648
- }
2649
-
2650
- // src/llm/output/_utils/getResultText.ts
2651
- function getResultText(result, index) {
2652
- if (typeof index === "number" && index > 0) {
2653
- const arr = result?.options || [];
2654
- const val = arr[index];
2655
- return isOutputResultContentText(val?.[0]) ? val[0]?.text : "";
2656
- }
2657
- return isOutputResultContentText(result?.content?.[0]) ? result.content[0]?.text : "";
2658
- }
2659
-
2660
- // src/llm/output/base.ts
2661
- function BaseLlmOutput2(result) {
2662
- const __result = Object.freeze({
2663
- id: result.id || uuidv4(),
2664
- name: result.name,
2665
- usage: result.usage,
2666
- stopReason: result.stopReason,
2667
- options: [...result?.options || []],
2668
- content: [...result.content],
2669
- created: result?.created || (/* @__PURE__ */ new Date()).getTime()
2670
- });
2671
- function getResult() {
2672
- return {
2673
- id: __result.id,
2674
- name: __result.name,
2675
- created: __result.created,
2676
- usage: __result.usage,
2677
- options: __result.options,
2678
- content: __result.content,
2679
- stopReason: __result.stopReason
2680
- };
2681
- }
2682
- return {
2683
- getResultContent: (index) => getResultContent(__result, index),
2684
- getResultText: (index) => getResultText(__result, index),
2685
- getResult
2686
- };
2687
- }
2688
-
2689
- // src/llm/output/_util.ts
2690
- function normalizeFunctionCall(input, provider) {
2691
- if (input === "any") {
2692
- if (provider === "openai") {
2693
- return "required";
2694
- }
2695
- }
2696
- return input;
2697
- }
2698
- function formatOptions(response, handler) {
2699
- const out = [];
2700
- for (const item of response) {
2701
- const result = handler(item);
2702
- if (result) {
2703
- out.push([result]);
2704
- }
2705
- }
2706
- return out;
2707
- }
2708
- function formatContent(response, handler) {
2709
- const out = [];
2710
- const result = handler(response);
2711
- if (result) {
2712
- out.push(result);
2713
- }
2714
- return out;
2715
- }
2716
-
2717
- // src/llm/output/openai.ts
2718
- function formatResult(result) {
2719
- const out = [];
2720
- if (typeof result?.message?.content === "string") {
2721
- out.push({
2722
- type: "text",
2723
- text: result.message.content
2724
- });
2725
- }
2726
- if (result?.message?.tool_calls) {
2727
- for (const call of result.message.tool_calls) {
2728
- out.push({
2729
- functionId: call.id,
2730
- type: "function_use",
2731
- name: call.function.name,
2732
- input: maybeParseJSON(call.function.arguments)
2733
- });
2734
- }
2735
- }
2736
- return out;
2737
- }
2738
- function OutputOpenAIChat(result, _config) {
2739
- const id = result.id;
2740
- const name = result.model || _config?.model || "openai.unknown";
2741
- const created = result.created;
2742
- const [_content, ..._options] = result?.choices || [];
2743
- const stopReason = _content?.finish_reason;
2744
- const content = formatResult(_content);
2745
- const options = formatOptions(_options, formatResult);
2746
- const usage = {
2747
- output_tokens: result?.usage?.completion_tokens,
2748
- input_tokens: result?.usage?.prompt_tokens,
2749
- total_tokens: result?.usage?.total_tokens
2750
- };
2751
- return BaseLlmOutput2({
2752
- id,
2753
- name,
2754
- created,
2755
- usage,
2756
- stopReason,
2757
- content,
2758
- options
2759
- });
2760
- }
2761
-
2762
- // src/llm/output/claude.ts
2763
- function formatResult2(response) {
2764
- const content = response?.content || [];
2765
- const out = [];
2766
- for (let i = 0; i < content.length; i++) {
2767
- const result = content[i];
2768
- if (result.type === "text") {
2769
- out.push({
2770
- type: "text",
2771
- text: result.text
2772
- });
2773
- } else if (result.type === "tool_use") {
2774
- out.push({
2775
- functionId: result.id,
2776
- type: "function_use",
2777
- name: result.name,
2778
- input: result.input
2779
- });
2780
- }
2781
- }
2782
- return out;
2783
- }
2784
- function OutputAnthropicClaude3Chat(result, _config) {
2785
- const id = result.id;
2786
- const name = result.model || _config?.model || "anthropic.unknown";
2787
- const stopReason = result.stop_reason;
2788
- const content = formatResult2(result);
2789
- const usage = {
2790
- input_tokens: result?.usage?.input_tokens,
2791
- output_tokens: result?.usage?.output_tokens,
2792
- total_tokens: result?.usage?.input_tokens + result?.usage?.input_tokens
2793
- };
2794
- return BaseLlmOutput2({
2795
- id,
2796
- name,
2797
- usage,
2798
- stopReason,
2799
- content
2800
- });
2801
- }
2802
-
2803
- // src/llm/output/llama.ts
2804
- function OutputMetaLlama3Chat(result, _config) {
2805
- const name = _config?.model || "meta";
2806
- const stopReason = result.stop_reason;
2807
- const content = [
2808
- { type: "text", text: result.generation }
2809
- ];
2810
- const usage = {
2811
- output_tokens: result?.generation_token_count,
2812
- input_tokens: result?.prompt_token_count,
2813
- total_tokens: result?.generation_token_count + result?.prompt_token_count
2814
- };
2815
- return BaseLlmOutput2({
2816
- name,
2817
- usage,
2818
- stopReason,
2819
- content
2820
- });
2821
- }
2822
-
2823
- // src/llm/output/default.ts
2824
- function OutputDefault(result, _config) {
2825
- const name = _config.model || "unknown";
2826
- const stopReason = result?.stopReason || "stop";
2827
- const content = [];
2828
- if (result?.text) {
2829
- content.push({ type: "text", text: result.text });
2830
- }
2831
- const usage = {
2832
- output_tokens: result?.output_tokens || 0,
2833
- input_tokens: result?.input_tokens || 0,
2834
- total_tokens: (result?.input_tokens || 0) + (result?.output_tokens || 0)
2835
- };
2836
- return BaseLlmOutput2({
2837
- name,
2838
- usage,
2839
- stopReason,
2840
- content
2841
- });
2842
- }
2843
-
2844
- // src/llm/output/xai.ts
2845
- function formatResult3(result) {
2846
- if (typeof result?.message?.content === "string") {
2847
- return {
2848
- type: "text",
2849
- text: result.message.content
2850
- };
2851
- } else if (result?.message && "tool_calls" in result.message) {
2852
- const tool_calls = result.message.tool_calls;
2853
- if (tool_calls) {
2854
- for (const call of tool_calls) {
2855
- return {
2856
- functionId: call.id,
2857
- type: "function_use",
2858
- name: call.function.name,
2859
- input: JSON.parse(call.function.arguments)
2860
- };
2861
- }
2862
- }
2863
- }
2864
- return {
2865
- type: "text",
2866
- text: ""
2867
- };
2868
- }
2869
- function OutputXAIChat(result, _config) {
2870
- const id = result.id;
2871
- const name = result?.model;
2872
- const created = result.created;
2873
- const [_content, ..._options] = result?.choices || [];
2874
- const stopReason = _content?.finish_reason;
2875
- const content = formatContent(_content, formatResult3);
2876
- const options = formatOptions(_options, formatResult3);
2877
- const usage = {
2878
- output_tokens: result?.usage?.completion_tokens,
2879
- input_tokens: result?.usage?.prompt_tokens,
2880
- total_tokens: result?.usage?.total_tokens
2881
- };
2882
- return BaseLlmOutput2({
2883
- id,
2884
- name,
2885
- created,
2886
- usage,
2887
- stopReason,
2888
- content,
2889
- options
2890
- });
2891
- }
2892
-
2893
- // src/llm/output/_utils/combineJsonl.ts
2894
- function combineJsonl(jsonl) {
2895
- const lines = jsonl.trim().split("\n").map((line) => line.trim()).filter((line) => line.length > 0).map((line) => {
2896
- try {
2897
- return JSON.parse(line);
2898
- } catch (e) {
2899
- throw new Error(`Invalid JSON: ${line}`);
2900
- }
2901
- });
2902
- if (lines.length === 0) {
2903
- throw new Error("No JSON lines provided.");
2848
+ response: {
2849
+ result: message.content
2850
+ }
2851
+ }
2852
+ });
2853
+ delete message.id;
2904
2854
  }
2905
- lines.sort(
2906
- (a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime()
2907
- );
2908
- let combinedContent = lines.map((line) => line?.message?.content ?? "").join("");
2909
- combinedContent = combinedContent.replace(/\\u003c/g, "<").replace(/\\u003e/g, ">");
2910
- const finalLine = lines.find((line) => line.done === true);
2911
- if (!finalLine) {
2912
- throw new Error("No line found where done = true.");
2855
+ if (message?.function_call) {
2856
+ const { function_call } = message;
2857
+ const toolsArr = Array.isArray(function_call) ? function_call : [function_call];
2858
+ role = "model";
2859
+ parts.push(
2860
+ ...toolsArr.map((call) => {
2861
+ const { name, arguments: input } = call;
2862
+ return {
2863
+ functionCall: {
2864
+ name,
2865
+ args: maybeParseJSON(input)
2866
+ }
2867
+ };
2868
+ })
2869
+ );
2870
+ delete message.function_call;
2913
2871
  }
2914
- const result = {
2915
- model: finalLine.model,
2916
- created_at: finalLine.created_at,
2917
- message: {
2918
- role: finalLine?.message?.role || "assistant",
2919
- content: combinedContent
2920
- },
2921
- done_reason: finalLine.done_reason,
2922
- done: finalLine.done,
2923
- total_duration: finalLine.total_duration,
2924
- load_duration: finalLine.load_duration,
2925
- prompt_eval_count: finalLine.prompt_eval_count,
2926
- prompt_eval_duration: finalLine.prompt_eval_duration,
2927
- eval_count: finalLine.eval_count,
2928
- eval_duration: finalLine.eval_duration
2929
- };
2930
- const content = {
2931
- type: "text",
2932
- text: combinedContent
2933
- };
2934
2872
  return {
2935
- lines,
2936
- result,
2937
- content
2873
+ role,
2874
+ parts
2938
2875
  };
2939
2876
  }
2940
2877
 
2941
- // src/llm/output/ollama.ts
2942
- function OutputOllamaChat(result, _config) {
2943
- const combined = combineJsonl(result);
2944
- const id = `${combined.result.model}.${combined.result.created_at}`;
2945
- const name = combined.result.model || _config?.model || "ollama.unknown";
2946
- const created = (/* @__PURE__ */ new Date(`${combined.result.created_at}`)).getTime();
2947
- const stopReason = `${combined?.result?.done_reason || "stop"}`;
2948
- const content = [combined.content];
2949
- const usage = {
2950
- output_tokens: 0,
2951
- input_tokens: 0,
2952
- total_tokens: 0
2953
- };
2954
- return BaseLlmOutput2({
2955
- id,
2956
- name,
2957
- created,
2958
- usage,
2959
- stopReason,
2960
- content,
2961
- options: []
2962
- });
2878
+ // src/llm/config/google/promptSanitize.ts
2879
+ function googleGeminiPromptSanitize(_messages, _inputBodyObj, _outputObj) {
2880
+ if (typeof _messages === "string") {
2881
+ return [{ role: "user", parts: [{ text: _messages }] }];
2882
+ }
2883
+ if (Array.isArray(_messages)) {
2884
+ if (_messages.length === 0) {
2885
+ throw new Error("Empty messages array");
2886
+ }
2887
+ if (_messages.length === 1 && _messages[0].role === "system") {
2888
+ return [{ role: "user", parts: [{ text: _messages[0].content }] }];
2889
+ }
2890
+ const hasSystemInstruction = _messages.some(
2891
+ (message) => message.role === "system"
2892
+ );
2893
+ if (hasSystemInstruction) {
2894
+ const theSystemInstructions = _messages.filter(
2895
+ (message) => message.role === "system"
2896
+ );
2897
+ const withoutSystemInstructions = _messages.filter(
2898
+ (message) => message.role !== "system"
2899
+ );
2900
+ _outputObj.system_instruction = {
2901
+ parts: theSystemInstructions.map((message) => ({
2902
+ text: message.content
2903
+ }))
2904
+ };
2905
+ return withoutSystemInstructions.map(googleGeminiPromptMessageCallback);
2906
+ }
2907
+ return _messages.map(googleGeminiPromptMessageCallback);
2908
+ }
2909
+ throw new Error("Invalid messages format");
2963
2910
  }
2964
2911
 
2965
2912
  // src/llm/output/google.gemini/formatResult.ts
2966
- function formatResult4(result, id) {
2913
+ function formatResult3(result, id) {
2967
2914
  const { parts = [] } = result?.content || {};
2968
2915
  const out = [];
2969
2916
  for (let i = 0; i < parts.length; i++) {
@@ -2988,18 +2935,18 @@ function formatResult4(result, id) {
2988
2935
  // src/llm/output/google.gemini/index.ts
2989
2936
  function OutputGoogleGeminiChat(result, _config) {
2990
2937
  const id = result.responseId;
2991
- const name = result.modelVersion || _config?.model || "gemini";
2938
+ const name = result.modelVersion || _config?.options.model?.default || "gemini";
2992
2939
  const created = (/* @__PURE__ */ new Date()).getTime();
2993
2940
  const [_content, ..._options] = result?.candidates || [];
2994
2941
  const stopReason = _content?.finishReason?.toLowerCase();
2995
- const content = formatResult4(_content, id);
2996
- const options = formatOptions(_options, formatResult4);
2942
+ const content = formatResult3(_content, id);
2943
+ const options = formatOptions(_options, formatResult3);
2997
2944
  const usage = {
2998
2945
  output_tokens: result?.usageMetadata?.candidatesTokenCount,
2999
2946
  input_tokens: result?.usageMetadata?.promptTokenCount,
3000
2947
  total_tokens: result?.usageMetadata?.totalTokenCount
3001
2948
  };
3002
- return BaseLlmOutput2({
2949
+ return {
3003
2950
  id,
3004
2951
  name,
3005
2952
  created,
@@ -3007,38 +2954,152 @@ function OutputGoogleGeminiChat(result, _config) {
3007
2954
  stopReason,
3008
2955
  content,
3009
2956
  options
3010
- });
2957
+ };
3011
2958
  }
3012
2959
 
3013
- // src/llm/output/index.ts
3014
- function normalizeLlmOutputToInternalFormat(config, response) {
3015
- switch (config?.key) {
3016
- case "openai.chat.v1":
3017
- case "openai.chat-mock.v1":
3018
- return OutputOpenAIChat(response, config);
3019
- case "anthropic.chat.v1":
3020
- case "amazon:anthropic.chat.v1":
3021
- return OutputAnthropicClaude3Chat(response, config);
3022
- case "amazon:meta.chat.v1":
3023
- return OutputMetaLlama3Chat(response, config);
3024
- // case "amazon:nova.chat.v1":
3025
- // return OutputDefault(response, config);
3026
- case "xai.chat.v1":
3027
- return OutputXAIChat(response, config);
3028
- case "ollama.chat.v1":
3029
- return OutputOllamaChat(response, config);
3030
- case "google.chat.v1":
3031
- return OutputGoogleGeminiChat(response, config);
3032
- case "deepseek.chat.v1":
3033
- return OutputOpenAIChat(response, config);
3034
- // use oai for now
3035
- default: {
3036
- if (config?.key?.startsWith("custom:")) {
3037
- return OutputDefault(response, config);
2960
+ // src/llm/config/google/index.ts
2961
+ var googleGeminiChatV1 = {
2962
+ key: "google.chat.v1",
2963
+ provider: "google.chat",
2964
+ endpoint: `https://generativelanguage.googleapis.com/v1beta/models/{{model}}:generateContent?key={{geminiApiKey}}`,
2965
+ options: {
2966
+ effort: {},
2967
+ prompt: {},
2968
+ // topP: {},
2969
+ geminiApiKey: {
2970
+ default: getEnvironmentVariable("GEMINI_API_KEY")
2971
+ }
2972
+ },
2973
+ method: "POST",
2974
+ headers: `{"Content-Type": "application/json" }`,
2975
+ mapBody: {
2976
+ prompt: {
2977
+ key: "contents",
2978
+ transform: googleGeminiPromptSanitize
2979
+ },
2980
+ effort: {
2981
+ key: "config.thinkingConfig.thinkingBudget",
2982
+ transform: (v, _s) => {
2983
+ if (
2984
+ // only supported reasoning models
2985
+ ["gemini-2.5-pro", "gemini-2.5-flash", "gemini-2.5-light"].includes(
2986
+ _s.model
2987
+ ) && typeof v === "string" && ["minimal", "low", "medium", "high"].includes(v)
2988
+ ) {
2989
+ if (v === "low" || v === "minimal") {
2990
+ return 1024;
2991
+ } else if (v === "medium") {
2992
+ return 8192;
2993
+ } else if (v === "high") {
2994
+ return 24576;
2995
+ }
2996
+ }
2997
+ return void 0;
3038
2998
  }
3039
- throw new Error("Unsupported provider");
3040
2999
  }
3000
+ },
3001
+ mapOptions: {
3002
+ functionCall: (call) => ({
3003
+ toolConfig: {
3004
+ functionCallingConfig: {
3005
+ mode: call === "any" ? "any" : call === "none" ? "none" : "auto"
3006
+ }
3007
+ }
3008
+ }),
3009
+ functions: (functions) => ({
3010
+ tools: [
3011
+ {
3012
+ functionDeclarations: functions.map((f) => ({
3013
+ name: f.name,
3014
+ description: f.description,
3015
+ parameters: cleanJsonSchemaFor(f.parameters, "google.chat")
3016
+ }))
3017
+ }
3018
+ ]
3019
+ })
3020
+ },
3021
+ transformResponse: OutputGoogleGeminiChat
3022
+ };
3023
+ var google = {
3024
+ "google.chat.v1": googleGeminiChatV1,
3025
+ "google.gemini-2.0-flash": withDefaultModel(
3026
+ googleGeminiChatV1,
3027
+ "gemini-2.0-flash"
3028
+ ),
3029
+ "google.gemini-2.0-flash-lite": withDefaultModel(
3030
+ googleGeminiChatV1,
3031
+ "gemini-2.0-flash-lite"
3032
+ ),
3033
+ "google.gemini-2.5-flash": withDefaultModel(
3034
+ googleGeminiChatV1,
3035
+ "gemini-2.5-flash"
3036
+ ),
3037
+ "google.gemini-2.5-flash-lite": withDefaultModel(
3038
+ googleGeminiChatV1,
3039
+ "gemini-2.5-flash-lite"
3040
+ ),
3041
+ "google.gemini-1.5-pro": withDefaultModel(
3042
+ googleGeminiChatV1,
3043
+ "gemini-1.5-pro"
3044
+ ),
3045
+ "google.gemini-2.5-pro": withDefaultModel(
3046
+ googleGeminiChatV1,
3047
+ "gemini-2.5-pro"
3048
+ )
3049
+ };
3050
+
3051
+ // src/llm/config/deepseek/index.ts
3052
+ var deepseekChatV1 = createOpenAiCompatibleConfiguration({
3053
+ key: "deepseek.chat.v1",
3054
+ provider: "deepseek.chat",
3055
+ endpoint: `https://api.deepseek.com/v1/chat/completions`,
3056
+ apiKeyMapping: ["deepseekApiKey", "DEEPSEEK_API_KEY"]
3057
+ });
3058
+ var deepseek = {
3059
+ "deepseek.chat.v1": deepseekChatV1,
3060
+ "deepseek.chat": withDefaultModel(deepseekChatV1, "deepseek-chat")
3061
+ };
3062
+
3063
+ // src/llm/config.ts
3064
+ var configs = {
3065
+ ...openai,
3066
+ ...anthropic,
3067
+ ...bedrock,
3068
+ ...xai,
3069
+ ...ollama,
3070
+ ...google,
3071
+ ...deepseek
3072
+ };
3073
+ function getLlmConfig(provider) {
3074
+ if (!provider) {
3075
+ throw new LlmExeError(`Missing provider`, "unknown", {
3076
+ error: "Missing provider",
3077
+ resolution: "Provide a valid provider"
3078
+ });
3079
+ }
3080
+ const pick2 = configs[provider];
3081
+ if (pick2) {
3082
+ return pick2;
3041
3083
  }
3084
+ throw new LlmExeError(`Invalid provider: ${provider}`, "unknown", {
3085
+ provider,
3086
+ error: `Invalid provider: ${provider}`,
3087
+ resolution: "Provide a valid provider"
3088
+ });
3089
+ }
3090
+
3091
+ // src/utils/modules/maskApiKeysInDebug.ts
3092
+ function maskApiKeys(log) {
3093
+ return log.replace(
3094
+ /\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,
3095
+ (match) => {
3096
+ if (match.length <= 8) return match;
3097
+ const prefix = match.substring(0, 4);
3098
+ const suffix = match.substring(match.length - 4);
3099
+ const maskLength = match.length - 8;
3100
+ return `${prefix}${"*".repeat(maskLength)}${suffix}`;
3101
+ }
3102
+ );
3042
3103
  }
3043
3104
 
3044
3105
  // src/utils/modules/debug.ts
@@ -3064,7 +3125,15 @@ function debug(...args) {
3064
3125
  logs.push(arg.toString());
3065
3126
  } else {
3066
3127
  try {
3067
- logs.push(JSON.stringify(arg, null, 2));
3128
+ let shouldMask = false;
3129
+ if (arg.headers && arg.headers.Authorization) {
3130
+ shouldMask = true;
3131
+ }
3132
+ let str = JSON.stringify(arg, null, 2);
3133
+ if (shouldMask) {
3134
+ str = maskApiKeys(str);
3135
+ }
3136
+ logs.push(str);
3068
3137
  } catch (error) {
3069
3138
  console.error("Error parsing object:", error);
3070
3139
  }
@@ -3112,7 +3181,8 @@ async function apiRequest(url, options) {
3112
3181
  }
3113
3182
  throw new Error(message);
3114
3183
  }
3115
- if (response.headers.get("content-type")?.includes("application/json")) {
3184
+ const contentType = response.headers.get("content-type");
3185
+ if (contentType?.includes("application/json")) {
3116
3186
  const responseData = await response.json();
3117
3187
  return responseData;
3118
3188
  } else {
@@ -3129,20 +3199,26 @@ async function apiRequest(url, options) {
3129
3199
  function convertDotNotation(obj) {
3130
3200
  const result = {};
3131
3201
  for (const key in obj) {
3132
- if (obj.hasOwnProperty(key)) {
3133
- if (key.includes(".")) {
3134
- const keys = key.split(".");
3135
- let currentLevel = result;
3136
- for (let i = 0; i < keys.length; i++) {
3137
- if (i === keys.length - 1) {
3138
- currentLevel[keys[i]] = obj[key];
3139
- } else {
3140
- currentLevel[keys[i]] = currentLevel[keys[i]] || {};
3141
- currentLevel = currentLevel[keys[i]];
3202
+ if (Object.prototype.hasOwnProperty.call(obj, key) && !key.includes(".")) {
3203
+ result[key] = obj[key];
3204
+ }
3205
+ }
3206
+ for (const key in obj) {
3207
+ if (Object.prototype.hasOwnProperty.call(obj, key) && key.includes(".")) {
3208
+ const keys = key.split(".");
3209
+ let currentLevel = result;
3210
+ for (let i = 0; i < keys.length; i++) {
3211
+ const currentKey = keys[i];
3212
+ if (i === keys.length - 1) {
3213
+ currentLevel[currentKey] = obj[key];
3214
+ } else {
3215
+ if (!(currentKey in currentLevel)) {
3216
+ currentLevel[currentKey] = {};
3217
+ } else if (typeof currentLevel[currentKey] !== "object" || currentLevel[currentKey] === null || Array.isArray(currentLevel[currentKey])) {
3218
+ currentLevel[currentKey] = {};
3142
3219
  }
3220
+ currentLevel = currentLevel[currentKey];
3143
3221
  }
3144
- } else {
3145
- result[key] = obj[key];
3146
3222
  }
3147
3223
  }
3148
3224
  }
@@ -3159,8 +3235,8 @@ function mapBody(template, body) {
3159
3235
  const { key: providerSpecificKey, default: defaultValue } = providerSpecificSettings;
3160
3236
  if (providerSpecificKey) {
3161
3237
  let valueForThisKey = body[genericInputKey];
3162
- if (providerSpecificSettings.sanitize && typeof providerSpecificSettings.sanitize === "function") {
3163
- valueForThisKey = providerSpecificSettings.sanitize(
3238
+ if (providerSpecificSettings.transform && typeof providerSpecificSettings.transform === "function") {
3239
+ valueForThisKey = providerSpecificSettings.transform(
3164
3240
  valueForThisKey,
3165
3241
  Object.freeze({ ...body }),
3166
3242
  output
@@ -3184,28 +3260,70 @@ import { Sha256 } from "@aws-crypto/sha256-js";
3184
3260
 
3185
3261
  // src/utils/modules/runWithTemporaryEnv.ts
3186
3262
  async function runWithTemporaryEnv(env, handler) {
3187
- const previousEnv = { ...process.env };
3263
+ const modifiedKeys = [];
3264
+ const originalValues = {};
3265
+ const envBefore = { ...process.env };
3188
3266
  try {
3189
- env();
3267
+ try {
3268
+ env();
3269
+ } catch (envError) {
3270
+ const envAfter2 = process.env;
3271
+ for (const key in envAfter2) {
3272
+ if (envBefore[key] !== envAfter2[key]) {
3273
+ modifiedKeys.push(key);
3274
+ originalValues[key] = envBefore[key];
3275
+ }
3276
+ }
3277
+ for (const key in envBefore) {
3278
+ if (!(key in envAfter2) && !modifiedKeys.includes(key)) {
3279
+ modifiedKeys.push(key);
3280
+ originalValues[key] = envBefore[key];
3281
+ }
3282
+ }
3283
+ throw envError;
3284
+ }
3285
+ const envAfter = process.env;
3286
+ for (const key in envAfter) {
3287
+ if (envBefore[key] !== envAfter[key]) {
3288
+ modifiedKeys.push(key);
3289
+ originalValues[key] = envBefore[key];
3290
+ }
3291
+ }
3292
+ for (const key in envBefore) {
3293
+ if (!(key in envAfter) && !modifiedKeys.includes(key)) {
3294
+ modifiedKeys.push(key);
3295
+ originalValues[key] = envBefore[key];
3296
+ }
3297
+ }
3190
3298
  const value = await handler();
3191
3299
  return value;
3192
3300
  } finally {
3193
- process.env = previousEnv;
3301
+ for (const key of modifiedKeys) {
3302
+ const originalValue = originalValues[key];
3303
+ if (originalValue === void 0) {
3304
+ delete process.env[key];
3305
+ } else {
3306
+ process.env[key] = originalValue;
3307
+ }
3308
+ }
3194
3309
  }
3195
3310
  }
3196
3311
 
3197
3312
  // src/utils/modules/getAwsAuthorizationHeaders.ts
3198
3313
  async function getAwsAuthorizationHeaders(req, props) {
3314
+ if (!props.url || !props.regionName) {
3315
+ throw new Error("URL and region name are required for AWS authorization");
3316
+ }
3199
3317
  const providerChain = fromNodeProviderChain();
3200
3318
  const credentials = await runWithTemporaryEnv(
3201
3319
  () => {
3202
- if (props.awsAccessKey) {
3320
+ if (props.awsAccessKey && typeof props.awsAccessKey === "string") {
3203
3321
  process.env["AWS_ACCESS_KEY_ID"] = props.awsAccessKey;
3204
3322
  }
3205
- if (props.awsSecretKey) {
3323
+ if (props.awsSecretKey && typeof props.awsSecretKey === "string") {
3206
3324
  process.env["AWS_SECRET_ACCESS_KEY"] = props.awsSecretKey;
3207
3325
  }
3208
- if (props.awsSessionToken) {
3326
+ if (props.awsSessionToken && typeof props.awsSessionToken === "string") {
3209
3327
  process.env["AWS_SESSION_TOKEN"] = props.awsSessionToken;
3210
3328
  }
3211
3329
  },
@@ -3235,8 +3353,21 @@ async function getAwsAuthorizationHeaders(req, props) {
3235
3353
  // src/llm/_utils.parseHeaders.ts
3236
3354
  async function parseHeaders(config, replacements, payload) {
3237
3355
  const replace = replaceTemplateStringSimple(config.headers, replacements);
3238
- const parse = replace ? JSON.parse(replace) : {};
3239
- const headers = Object.assign({}, payload.headers, parse);
3356
+ let parsedHeaders = {};
3357
+ if (replace) {
3358
+ try {
3359
+ parsedHeaders = JSON.parse(replace);
3360
+ if (typeof parsedHeaders !== "object" || parsedHeaders === null || Array.isArray(parsedHeaders)) {
3361
+ throw new Error("Headers must be a JSON object");
3362
+ }
3363
+ } catch (error) {
3364
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
3365
+ throw new Error(
3366
+ `Failed to parse headers configuration: ${errorMessage}. Headers template: "${config.headers}". After replacement: "${replace}"`
3367
+ );
3368
+ }
3369
+ }
3370
+ const headers = Object.assign({}, payload.headers, parsedHeaders);
3240
3371
  if (config.provider.startsWith("amazon:") || config.provider.startsWith("amazon.")) {
3241
3372
  const url = payload.url;
3242
3373
  return getAwsAuthorizationHeaders(
@@ -3257,122 +3388,129 @@ async function parseHeaders(config, replacements, payload) {
3257
3388
  }
3258
3389
  }
3259
3390
 
3260
- // src/llm/output/_utils/cleanJsonSchemaFor.ts
3261
- var providerFieldExclusions = {
3262
- "openai.chat": ["default"],
3263
- // fields to exclude for openai.chat
3264
- "anthropic.chat": []
3265
- // fields to exclude for openai.chat
3266
- };
3267
- function cleanJsonSchemaFor(schema = {}, provider) {
3268
- const clone = deepClone(schema);
3269
- if (Object.keys(clone).length === 0) {
3391
+ // src/llm/output/default.ts
3392
+ function OutputDefault(result, _config) {
3393
+ const name = _config?.options.model?.default || "unknown";
3394
+ const stopReason = result?.stopReason || "stop";
3395
+ const content = [];
3396
+ if (result?.text) {
3397
+ content.push({ type: "text", text: result.text });
3398
+ }
3399
+ const usage = {
3400
+ output_tokens: result?.output_tokens || 0,
3401
+ input_tokens: result?.input_tokens || 0,
3402
+ total_tokens: (result?.input_tokens || 0) + (result?.output_tokens || 0)
3403
+ };
3404
+ return {
3405
+ name,
3406
+ usage,
3407
+ stopReason,
3408
+ content
3409
+ };
3410
+ }
3411
+
3412
+ // src/llm/output/_utils/getResultContent.ts
3413
+ function getResultContent(result, index) {
3414
+ if (typeof index === "number" && index > 0) {
3415
+ const arr = result?.options || [];
3416
+ const val = arr[index];
3417
+ return val ? val : [];
3418
+ }
3419
+ return [...result.content];
3420
+ }
3421
+
3422
+ // src/llm/output/_utils/getResultText.ts
3423
+ function getResultText(result, index) {
3424
+ if (typeof index === "number" && index > 0) {
3425
+ const arr = result?.options || [];
3426
+ const val = arr[index];
3427
+ return isOutputResultContentText(val?.[0]) ? val[0]?.text : "";
3428
+ }
3429
+ return isOutputResultContentText(result?.content?.[0]) ? result.content[0]?.text : "";
3430
+ }
3431
+
3432
+ // src/llm/output/base.ts
3433
+ function BaseLlmOutput(result) {
3434
+ const __result = Object.freeze({
3435
+ id: result.id || uuidv4(),
3436
+ name: result.name,
3437
+ usage: result.usage,
3438
+ stopReason: result.stopReason,
3439
+ options: [...result?.options || []],
3440
+ content: [...result.content],
3441
+ created: result?.created || (/* @__PURE__ */ new Date()).getTime()
3442
+ });
3443
+ function getResult() {
3270
3444
  return {
3271
- type: "object",
3272
- properties: {},
3273
- required: []
3445
+ id: __result.id,
3446
+ name: __result.name,
3447
+ created: __result.created,
3448
+ usage: __result.usage,
3449
+ options: __result.options,
3450
+ content: __result.content,
3451
+ stopReason: __result.stopReason
3274
3452
  };
3275
3453
  }
3276
- const exclusions = providerFieldExclusions[provider] || [];
3277
- function removeDisallowedFields(obj) {
3278
- if (Array.isArray(obj)) {
3279
- return obj.map(removeDisallowedFields);
3280
- } else if (typeof obj === "object" && obj !== null) {
3281
- return Object.keys(obj).reduce((acc, key) => {
3282
- if (!exclusions.includes(key)) {
3283
- acc[key] = removeDisallowedFields(obj[key]);
3284
- }
3285
- return acc;
3286
- }, {});
3454
+ return {
3455
+ getResultContent: (index) => getResultContent(__result, index),
3456
+ getResultText: (index) => getResultText(__result, index),
3457
+ getResult
3458
+ };
3459
+ }
3460
+
3461
+ // src/llm/_utils.mapOptions.ts
3462
+ function mapOptions(input, options, config) {
3463
+ if (!config?.mapOptions || !options) {
3464
+ return input;
3465
+ }
3466
+ let result = { ...input };
3467
+ let processedOptions = options;
3468
+ if (options.functionCall && config.mapOptions.functionCall) {
3469
+ const mapping = config.mapOptions.functionCall(
3470
+ options.functionCall,
3471
+ options,
3472
+ result,
3473
+ config
3474
+ );
3475
+ if (mapping._clearFunctions) {
3476
+ processedOptions = { ...options, functions: [] };
3477
+ const { _clearFunctions, ...rest } = mapping;
3478
+ result = { ...result, ...rest };
3479
+ } else {
3480
+ result = { ...result, ...mapping };
3287
3481
  }
3288
- return obj;
3289
3482
  }
3290
- return removeDisallowedFields(clone);
3483
+ if (processedOptions.functions?.length && config.mapOptions.functions) {
3484
+ result = {
3485
+ ...result,
3486
+ ...config.mapOptions.functions(
3487
+ processedOptions.functions,
3488
+ processedOptions,
3489
+ result,
3490
+ config
3491
+ )
3492
+ };
3493
+ }
3494
+ if (options.jsonSchema && config.mapOptions.jsonSchema) {
3495
+ result = {
3496
+ ...result,
3497
+ ...config.mapOptions.jsonSchema(options.jsonSchema, options, result, config)
3498
+ };
3499
+ }
3500
+ return result;
3291
3501
  }
3292
3502
 
3293
3503
  // src/llm/llm.call.ts
3294
3504
  async function useLlm_call(state, messages, _options) {
3295
3505
  const config = getLlmConfig(state.key);
3296
- const { functionCallStrictInput = false } = _options || {};
3297
- const input = mapBody(
3506
+ const transformBody = mapBody(
3298
3507
  config.mapBody,
3299
3508
  Object.assign({}, state, {
3300
3509
  prompt: messages
3301
3510
  })
3302
3511
  );
3303
- if (_options && _options?.jsonSchema) {
3304
- if (state.provider.startsWith("openai")) {
3305
- const curr = input["response_format"] || {};
3306
- input["response_format"] = Object.assign(curr, {
3307
- type: "json_schema",
3308
- json_schema: {
3309
- name: "output",
3310
- strict: !!functionCallStrictInput,
3311
- schema: cleanJsonSchemaFor(_options?.jsonSchema, "openai.chat")
3312
- }
3313
- });
3314
- }
3315
- }
3316
- if (_options && _options?.functionCall) {
3317
- if (state.provider.startsWith("anthropic")) {
3318
- if (_options?.functionCall === "none") {
3319
- _options.functions = [];
3320
- } else if (_options?.functionCall === "auto" || _options?.functionCall === "any") {
3321
- input["tool_choice"] = { type: _options?.functionCall };
3322
- } else {
3323
- input["tool_choice"] = _options?.functionCall;
3324
- }
3325
- } else if (state.provider.startsWith("openai")) {
3326
- input["tool_choice"] = normalizeFunctionCall(
3327
- _options?.functionCall,
3328
- "openai"
3329
- );
3330
- } else if (state.provider.startsWith("google")) {
3331
- input["toolConfig"] = {
3332
- functionCallingConfig: {
3333
- mode: normalizeFunctionCall(_options?.functionCall, "google")
3334
- }
3335
- };
3336
- }
3337
- }
3338
- if (_options && _options?.functions?.length) {
3339
- if (state.provider.startsWith("anthropic")) {
3340
- input["tools"] = _options.functions.map((f) => ({
3341
- name: f.name,
3342
- description: f.description,
3343
- input_schema: cleanJsonSchemaFor(f.parameters, "anthropic.chat")
3344
- }));
3345
- } else if (state.provider.startsWith("openai")) {
3346
- input["tools"] = _options.functions.map((f) => {
3347
- const props = {
3348
- name: f?.name,
3349
- description: f?.description,
3350
- parameters: f?.parameters
3351
- };
3352
- return {
3353
- type: "function",
3354
- function: Object.assign(
3355
- props,
3356
- {
3357
- parameters: cleanJsonSchemaFor(props.parameters, "openai.chat")
3358
- },
3359
- { strict: functionCallStrictInput }
3360
- )
3361
- };
3362
- });
3363
- } else if (state.provider.startsWith("google")) {
3364
- input["tools"] = [
3365
- {
3366
- functionDeclarations: _options.functions.map((f) => ({
3367
- name: f.name,
3368
- description: f.description,
3369
- parameters: cleanJsonSchemaFor(f.parameters, "google.chat")
3370
- }))
3371
- }
3372
- ];
3373
- }
3374
- }
3375
- const body = JSON.stringify(input);
3512
+ const applyOptions = mapOptions(transformBody, _options, config);
3513
+ const body = JSON.stringify(applyOptions);
3376
3514
  const url = replaceTemplateStringSimple(config.endpoint, state);
3377
3515
  const headers = await parseHeaders(config, state, {
3378
3516
  url,
@@ -3399,7 +3537,9 @@ async function useLlm_call(state, messages, _options) {
3399
3537
  body,
3400
3538
  headers
3401
3539
  });
3402
- return normalizeLlmOutputToInternalFormat(state, response);
3540
+ const { transformResponse = OutputDefault } = config;
3541
+ const normalized = transformResponse(response, config);
3542
+ return BaseLlmOutput(normalized);
3403
3543
  }
3404
3544
 
3405
3545
  // src/llm/_utils.stateFromOptions.ts
@@ -3542,6 +3682,80 @@ function useLlm(provider, options = {}) {
3542
3682
  const config = getLlmConfig(provider);
3543
3683
  return apiRequestWrapper(config, options, useLlm_call);
3544
3684
  }
3685
+ function useLlmConfiguration(config) {
3686
+ return (options = {}) => apiRequestWrapper(config, options, useLlm_call);
3687
+ }
3688
+
3689
+ // src/embedding/output/BaseEmbeddingOutput.ts
3690
+ function BaseEmbeddingOutput(result) {
3691
+ const __result = Object.freeze({
3692
+ id: result.id || uuidv4(),
3693
+ model: result.model,
3694
+ usage: result.usage,
3695
+ embedding: [...result?.embedding || []],
3696
+ created: result?.created || (/* @__PURE__ */ new Date()).getTime()
3697
+ });
3698
+ function getResult() {
3699
+ return {
3700
+ id: __result.id,
3701
+ model: __result.model,
3702
+ created: __result.created,
3703
+ usage: __result.usage,
3704
+ embedding: __result.embedding
3705
+ };
3706
+ }
3707
+ function getEmbedding(index) {
3708
+ if (index && index > 0) {
3709
+ const arr = __result?.embedding;
3710
+ const val = arr[index];
3711
+ return val ? val : [];
3712
+ }
3713
+ return __result.embedding[0];
3714
+ }
3715
+ return {
3716
+ getEmbedding,
3717
+ getResult
3718
+ };
3719
+ }
3720
+
3721
+ // src/embedding/output/OpenAiEmbedding.ts
3722
+ function OpenAiEmbedding(result, config) {
3723
+ const __result = deepClone(result);
3724
+ const model = __result.model || config.model || "openai.unknown";
3725
+ const created = (/* @__PURE__ */ new Date()).getTime();
3726
+ const results = result?.data || [];
3727
+ const embedding = results.map((a) => a.embedding);
3728
+ const usage = {
3729
+ output_tokens: 0,
3730
+ input_tokens: result?.usage?.prompt_tokens,
3731
+ total_tokens: result?.usage?.total_tokens
3732
+ };
3733
+ return BaseEmbeddingOutput({
3734
+ model,
3735
+ created,
3736
+ usage,
3737
+ embedding
3738
+ });
3739
+ }
3740
+
3741
+ // src/embedding/output/AmazonTitan.ts
3742
+ function AmazonTitanEmbedding(result, config) {
3743
+ const __result = deepClone(result);
3744
+ const model = config.model || "amazon.unknown";
3745
+ const created = (/* @__PURE__ */ new Date()).getTime();
3746
+ const embedding = [__result.embedding];
3747
+ const usage = {
3748
+ output_tokens: 0,
3749
+ input_tokens: __result.inputTextTokenCount,
3750
+ total_tokens: __result.inputTextTokenCount
3751
+ };
3752
+ return BaseEmbeddingOutput({
3753
+ model,
3754
+ created,
3755
+ usage,
3756
+ embedding
3757
+ });
3758
+ }
3545
3759
 
3546
3760
  // src/embedding/config.ts
3547
3761
  var embeddingConfigs = {
@@ -3574,7 +3788,8 @@ var embeddingConfigs = {
3574
3788
  encodingFormat: {
3575
3789
  key: "encoding_format"
3576
3790
  }
3577
- }
3791
+ },
3792
+ transformResponse: OpenAiEmbedding
3578
3793
  },
3579
3794
  "amazon.embedding.v1": {
3580
3795
  key: "amazon.embedding.v1",
@@ -3601,7 +3816,8 @@ var embeddingConfigs = {
3601
3816
  dimensions: {
3602
3817
  key: "dimensions"
3603
3818
  }
3604
- }
3819
+ },
3820
+ transformResponse: AmazonTitanEmbedding
3605
3821
  }
3606
3822
  };
3607
3823
  function getEmbeddingConfig(provider) {
@@ -3615,77 +3831,6 @@ function getEmbeddingConfig(provider) {
3615
3831
  throw new Error(`Invalid provider: ${provider}`);
3616
3832
  }
3617
3833
 
3618
- // src/embedding/output/BaseEmbeddingOutput.ts
3619
- function BaseEmbeddingOutput(result) {
3620
- const __result = Object.freeze({
3621
- id: result.id || uuidv4(),
3622
- model: result.model,
3623
- usage: result.usage,
3624
- embedding: [...result?.embedding || []],
3625
- created: result?.created || (/* @__PURE__ */ new Date()).getTime()
3626
- });
3627
- function getResult() {
3628
- return {
3629
- id: __result.id,
3630
- model: __result.model,
3631
- created: __result.created,
3632
- usage: __result.usage,
3633
- embedding: __result.embedding
3634
- };
3635
- }
3636
- function getEmbedding(index) {
3637
- if (index && index > 0) {
3638
- const arr = __result?.embedding;
3639
- const val = arr[index];
3640
- return val ? val : [];
3641
- }
3642
- return __result.embedding[0];
3643
- }
3644
- return {
3645
- getEmbedding,
3646
- getResult
3647
- };
3648
- }
3649
-
3650
- // src/embedding/output/AmazonTitan.ts
3651
- function AmazonTitanEmbedding(result, config) {
3652
- const __result = deepClone(result);
3653
- const model = config.model || "amazon.unknown";
3654
- const created = (/* @__PURE__ */ new Date()).getTime();
3655
- const embedding = [__result.embedding];
3656
- const usage = {
3657
- output_tokens: 0,
3658
- input_tokens: __result.inputTextTokenCount,
3659
- total_tokens: __result.inputTextTokenCount
3660
- };
3661
- return BaseEmbeddingOutput({
3662
- model,
3663
- created,
3664
- usage,
3665
- embedding
3666
- });
3667
- }
3668
-
3669
- // src/embedding/output/OpenAiEmbedding.ts
3670
- function OpenAiEmbedding(result, config) {
3671
- const __result = deepClone(result);
3672
- const model = __result.model || config.model || "openai.unknown";
3673
- const created = (/* @__PURE__ */ new Date()).getTime();
3674
- const results = result?.data || [];
3675
- const embedding = results.map((a) => a.embedding);
3676
- const usage = {
3677
- output_tokens: 0,
3678
- input_tokens: result?.usage?.prompt_tokens,
3679
- total_tokens: result?.usage?.total_tokens
3680
- };
3681
- return BaseEmbeddingOutput({
3682
- model,
3683
- created,
3684
- usage,
3685
- embedding
3686
- });
3687
- }
3688
-
3689
3834
  // src/embedding/output/getEmbeddingOutputParser.ts
3690
3835
  function getEmbeddingOutputParser(config, response) {
3691
3836
  switch (config.key) {
@@ -4703,6 +4848,9 @@ var Dialogue = class extends BaseStateItem {
4703
4848
  * @returns this for chaining
4704
4849
  */
4705
4850
  addFromOutput(output) {
4851
+ if (!output || typeof output !== "object") {
4852
+ return this;
4853
+ }
4706
4854
  const result = "getResult" in output ? output.getResult() : output;
4707
4855
  if (!result || typeof result !== "object") {
4708
4856
  return this;
@@ -4838,6 +4986,7 @@ export {
4838
4986
  createEmbedding,
4839
4987
  createLlmExecutor,
4840
4988
  createLlmFunctionExecutor,
4989
+ createOpenAiCompatibleConfiguration,
4841
4990
  createParser,
4842
4991
  createPrompt,
4843
4992
  createState,
@@ -4848,5 +4997,6 @@ export {
4848
4997
  registerPartials,
4849
4998
  useExecutors,
4850
4999
  useLlm,
5000
+ useLlmConfiguration,
4851
5001
  utils_exports as utils
4852
5002
  };