llm-exe 3.0.0-beta.2 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1142,6 +1142,7 @@ interface GenericEmbeddingOptions extends BaseLlmOptions {
1142
1142
  interface OpenAiEmbeddingOptions extends GenericEmbeddingOptions {
1143
1143
  model?: string;
1144
1144
  openAiApiKey?: string;
1145
+ baseUrl?: string;
1145
1146
  }
1146
1147
  interface AmazonEmbeddingOptions extends GenericEmbeddingOptions {
1147
1148
  model: string;
@@ -1283,6 +1284,9 @@ type AllUseLlmOptions = AllLlm & {
1283
1284
  "openai.o4-mini": {
1284
1285
  input: Omit<OpenAiRequest, "model">;
1285
1286
  };
1287
+ "anthropic.claude-opus-4-8": {
1288
+ input: Omit<AnthropicRequest, "model">;
1289
+ };
1286
1290
  "anthropic.claude-opus-4-7": {
1287
1291
  input: Omit<AnthropicRequest, "model">;
1288
1292
  };
@@ -1549,7 +1553,7 @@ interface Config<Pk = LlmProviderKey> {
1549
1553
  * Embedding configs do not use this — their flow dispatches via
1550
1554
  * `getEmbeddingOutputParser` instead.
1551
1555
  */
1552
- transformResponse?: (result: any, _config?: Config<any>) => OutputResult;
1556
+ transformResponse?: (result: any, _config?: Config<any>, headers?: Record<string, string>) => OutputResult;
1553
1557
  /**
1554
1558
  * Marks this config as deprecated. When set, useLlm() will emit a one-time
1555
1559
  * deprecation warning to inform users about upcoming model shutdowns.
@@ -2018,6 +2022,7 @@ declare const configs: {
2018
2022
  "anthropic.claude-opus-4-1": Config<any>;
2019
2023
  "anthropic.claude-opus-4-6": Config<any>;
2020
2024
  "anthropic.chat.v1": Config<keyof AllLlm>;
2025
+ "anthropic.claude-opus-4-8": Config<keyof AllLlm>;
2021
2026
  "anthropic.claude-opus-4-7": Config<keyof AllLlm>;
2022
2027
  "anthropic.claude-sonnet-4-6": Config<keyof AllLlm>;
2023
2028
  "anthropic.claude-opus-4-5": Config<keyof AllLlm>;
package/dist/index.d.ts CHANGED
@@ -1142,6 +1142,7 @@ interface GenericEmbeddingOptions extends BaseLlmOptions {
1142
1142
  interface OpenAiEmbeddingOptions extends GenericEmbeddingOptions {
1143
1143
  model?: string;
1144
1144
  openAiApiKey?: string;
1145
+ baseUrl?: string;
1145
1146
  }
1146
1147
  interface AmazonEmbeddingOptions extends GenericEmbeddingOptions {
1147
1148
  model: string;
@@ -1283,6 +1284,9 @@ type AllUseLlmOptions = AllLlm & {
1283
1284
  "openai.o4-mini": {
1284
1285
  input: Omit<OpenAiRequest, "model">;
1285
1286
  };
1287
+ "anthropic.claude-opus-4-8": {
1288
+ input: Omit<AnthropicRequest, "model">;
1289
+ };
1286
1290
  "anthropic.claude-opus-4-7": {
1287
1291
  input: Omit<AnthropicRequest, "model">;
1288
1292
  };
@@ -1549,7 +1553,7 @@ interface Config<Pk = LlmProviderKey> {
1549
1553
  * Embedding configs do not use this — their flow dispatches via
1550
1554
  * `getEmbeddingOutputParser` instead.
1551
1555
  */
1552
- transformResponse?: (result: any, _config?: Config<any>) => OutputResult;
1556
+ transformResponse?: (result: any, _config?: Config<any>, headers?: Record<string, string>) => OutputResult;
1553
1557
  /**
1554
1558
  * Marks this config as deprecated. When set, useLlm() will emit a one-time
1555
1559
  * deprecation warning to inform users about upcoming model shutdowns.
@@ -2018,6 +2022,7 @@ declare const configs: {
2018
2022
  "anthropic.claude-opus-4-1": Config<any>;
2019
2023
  "anthropic.claude-opus-4-6": Config<any>;
2020
2024
  "anthropic.chat.v1": Config<keyof AllLlm>;
2025
+ "anthropic.claude-opus-4-8": Config<keyof AllLlm>;
2021
2026
  "anthropic.claude-opus-4-7": Config<keyof AllLlm>;
2022
2027
  "anthropic.claude-sonnet-4-6": Config<keyof AllLlm>;
2023
2028
  "anthropic.claude-opus-4-5": Config<keyof AllLlm>;
package/dist/index.js CHANGED
@@ -4352,6 +4352,20 @@ function anthropicPromptSanitize(_messages, _inputBodyObj, _outputObj) {
4352
4352
  return mergeConsecutiveSameRole(result);
4353
4353
  }
4354
4354
 
4355
+ // src/llm/output/_utils/getBedrockTokenCounts.ts
4356
+ function getBedrockTokenCounts(headers) {
4357
+ if (!headers) return void 0;
4358
+ const input = parseInt(headers["x-amzn-bedrock-input-token-count"], 10);
4359
+ const output = parseInt(headers["x-amzn-bedrock-output-token-count"], 10);
4360
+ if (!Number.isFinite(input) && !Number.isFinite(output)) {
4361
+ return void 0;
4362
+ }
4363
+ return {
4364
+ input_tokens: Number.isFinite(input) ? input : 0,
4365
+ output_tokens: Number.isFinite(output) ? output : 0
4366
+ };
4367
+ }
4368
+
4355
4369
  // src/llm/output/claude.ts
4356
4370
  function formatResult2(response) {
4357
4371
  const content = response?.content || [];
@@ -4374,15 +4388,18 @@ function formatResult2(response) {
4374
4388
  }
4375
4389
  return out;
4376
4390
  }
4377
- function OutputAnthropicClaude3Chat(result, _config) {
4391
+ function OutputAnthropicClaude3Chat(result, _config, headers) {
4378
4392
  const id = result.id;
4379
4393
  const name = result.model || _config?.options.model?.default || "anthropic.unknown";
4380
4394
  const stopReason = result.stop_reason;
4381
4395
  const content = formatResult2(result);
4396
+ const headerUsage = getBedrockTokenCounts(headers);
4397
+ const input_tokens = result?.usage?.input_tokens ?? headerUsage?.input_tokens ?? 0;
4398
+ const output_tokens = result?.usage?.output_tokens ?? headerUsage?.output_tokens ?? 0;
4382
4399
  const usage = {
4383
- input_tokens: result?.usage?.input_tokens,
4384
- output_tokens: result?.usage?.output_tokens,
4385
- total_tokens: result?.usage?.input_tokens + result?.usage?.output_tokens
4400
+ input_tokens,
4401
+ output_tokens,
4402
+ total_tokens: input_tokens + output_tokens
4386
4403
  };
4387
4404
  return {
4388
4405
  id,
@@ -4395,7 +4412,7 @@ function OutputAnthropicClaude3Chat(result, _config) {
4395
4412
  }
4396
4413
 
4397
4414
  // src/llm/output/llama.ts
4398
- function OutputMetaLlama3Chat(result, _config) {
4415
+ function OutputMetaLlama3Chat(result, _config, headers) {
4399
4416
  const id = (0, import_uuid.v4)();
4400
4417
  const name = _config?.options?.model?.default || "meta";
4401
4418
  const created = (/* @__PURE__ */ new Date()).getTime();
@@ -4403,10 +4420,13 @@ function OutputMetaLlama3Chat(result, _config) {
4403
4420
  const content = [
4404
4421
  { type: "text", text: result.generation }
4405
4422
  ];
4423
+ const headerUsage = getBedrockTokenCounts(headers);
4424
+ const output_tokens = result?.generation_token_count ?? headerUsage?.output_tokens ?? 0;
4425
+ const input_tokens = result?.prompt_token_count ?? headerUsage?.input_tokens ?? 0;
4406
4426
  const usage = {
4407
- output_tokens: result?.generation_token_count,
4408
- input_tokens: result?.prompt_token_count,
4409
- total_tokens: result?.generation_token_count + result?.prompt_token_count
4427
+ output_tokens,
4428
+ input_tokens,
4429
+ total_tokens: output_tokens + input_tokens
4410
4430
  };
4411
4431
  return {
4412
4432
  id,
@@ -4524,7 +4544,7 @@ var bedrock = {
4524
4544
 
4525
4545
  // src/llm/config/anthropic/index.ts
4526
4546
  var ANTHROPIC_VERSION = "2023-06-01";
4527
- var MODELS_REJECTING_SAMPLING_PARAMS = ["claude-opus-4-7"];
4547
+ var MODELS_REJECTING_SAMPLING_PARAMS = ["claude-opus-4-7", "claude-opus-4-8"];
4528
4548
  var isClaude4x = (model) => /^claude-(opus|sonnet|haiku)-4-/.test(model);
4529
4549
  var dropIfModelRejectsSamplingParams = (v, body) => MODELS_REJECTING_SAMPLING_PARAMS.includes(body.model) ? void 0 : v;
4530
4550
  var topPTransform = (v, body) => {
@@ -4609,6 +4629,11 @@ var anthropicChatV1 = {
4609
4629
  };
4610
4630
  var anthropic = {
4611
4631
  "anthropic.chat.v1": anthropicChatV1,
4632
+ // Claude 4.8 models
4633
+ "anthropic.claude-opus-4-8": withDefaultModel(
4634
+ anthropicChatV1,
4635
+ "claude-opus-4-8"
4636
+ ),
4612
4637
  // Claude 4.7 models
4613
4638
  "anthropic.claude-opus-4-7": withDefaultModel(
4614
4639
  anthropicChatV1,
@@ -4792,7 +4817,11 @@ var ollamaChatV1 = {
4792
4817
  provider: "ollama.chat",
4793
4818
  endpoint: `${getEnvironmentVariable("OLLAMA_ENDPOINT") || `http://localhost:11434`}/api/chat`,
4794
4819
  options: {
4795
- prompt: {}
4820
+ prompt: {},
4821
+ temperature: {},
4822
+ topP: {},
4823
+ maxTokens: {},
4824
+ stopSequences: {}
4796
4825
  },
4797
4826
  method: "POST",
4798
4827
  headers: `{"Content-Type": "application/json" }`,
@@ -4808,6 +4837,18 @@ var ollamaChatV1 = {
4808
4837
  },
4809
4838
  model: {
4810
4839
  key: "model"
4840
+ },
4841
+ temperature: {
4842
+ key: "options.temperature"
4843
+ },
4844
+ topP: {
4845
+ key: "options.top_p"
4846
+ },
4847
+ maxTokens: {
4848
+ key: "options.num_predict"
4849
+ },
4850
+ stopSequences: {
4851
+ key: "options.stop"
4811
4852
  }
4812
4853
  },
4813
4854
  transformResponse: OutputOllamaChat
@@ -5003,7 +5044,10 @@ var googleGeminiChatV1 = {
5003
5044
  options: {
5004
5045
  effort: {},
5005
5046
  prompt: {},
5006
- // topP: {},
5047
+ temperature: {},
5048
+ topP: {},
5049
+ maxTokens: {},
5050
+ stopSequences: {},
5007
5051
  geminiApiKey: {
5008
5052
  default: getEnvironmentVariable("GEMINI_API_KEY")
5009
5053
  }
@@ -5015,6 +5059,18 @@ var googleGeminiChatV1 = {
5015
5059
  key: "contents",
5016
5060
  transform: googleGeminiPromptSanitize
5017
5061
  },
5062
+ temperature: {
5063
+ key: "generationConfig.temperature"
5064
+ },
5065
+ topP: {
5066
+ key: "generationConfig.topP"
5067
+ },
5068
+ maxTokens: {
5069
+ key: "generationConfig.maxOutputTokens"
5070
+ },
5071
+ stopSequences: {
5072
+ key: "generationConfig.stopSequences"
5073
+ },
5018
5074
  effort: {
5019
5075
  key: "config.thinkingConfig.thinkingBudget",
5020
5076
  transform: (v, _s) => {
@@ -5156,6 +5212,13 @@ function isValidUrl(input) {
5156
5212
  }
5157
5213
 
5158
5214
  // src/utils/modules/request.ts
5215
+ function headersToRecord(headers) {
5216
+ const record = {};
5217
+ headers.forEach((value, key) => {
5218
+ record[key.toLowerCase()] = value;
5219
+ });
5220
+ return record;
5221
+ }
5159
5222
  async function apiRequest(url, options) {
5160
5223
  const finalOptions = {
5161
5224
  ...options
@@ -5241,13 +5304,16 @@ async function apiRequest(url, options) {
5241
5304
  });
5242
5305
  }
5243
5306
  const contentType = response.headers.get("content-type");
5307
+ const headers = headersToRecord(response.headers);
5244
5308
  if (contentType?.includes("application/json")) {
5245
- const responseData = await response.json();
5246
- return responseData;
5247
- } else {
5248
- const responseData = await response.text();
5249
- return responseData;
5309
+ const responseData2 = await response.json();
5310
+ return { data: responseData2, headers };
5250
5311
  }
5312
+ const responseData = await response.text();
5313
+ return {
5314
+ data: responseData,
5315
+ headers
5316
+ };
5251
5317
  }
5252
5318
 
5253
5319
  // src/utils/modules/convertDotNotation.ts
@@ -5619,7 +5685,7 @@ async function useLlm_call(state, messages, _options) {
5619
5685
  }
5620
5686
  ]
5621
5687
  };
5622
- return BaseLlmOutput(transformResponse(mockResponse, config));
5688
+ return BaseLlmOutput(transformResponse(mockResponse, config, {}));
5623
5689
  }
5624
5690
  try {
5625
5691
  const response = await apiRequest(url, {
@@ -5627,7 +5693,9 @@ async function useLlm_call(state, messages, _options) {
5627
5693
  body,
5628
5694
  headers
5629
5695
  });
5630
- return BaseLlmOutput(transformResponse(response, config));
5696
+ return BaseLlmOutput(
5697
+ transformResponse(response.data, config, response.headers)
5698
+ );
5631
5699
  } catch (e) {
5632
5700
  if (!isLlmExeError(e, "request.http_error")) throw e;
5633
5701
  const ctx = e.context ?? {};
@@ -5808,7 +5876,9 @@ var embeddingConfigs = {
5808
5876
  "openai.embedding.v1": {
5809
5877
  key: "openai.embedding.v1",
5810
5878
  provider: "openai.embedding",
5811
- endpoint: `https://api.openai.com/v1/embeddings`,
5879
+ // Templated host: `baseUrl` defaults to OpenAI. Override to point at any
5880
+ // OpenAI-compatible embeddings server (Baseten, vLLM, TEI, Together, etc.).
5881
+ endpoint: `{{baseUrl}}/embeddings`,
5812
5882
  method: "POST",
5813
5883
  headers: `{"Authorization":"Bearer {{openAiApiKey}}", "Content-Type": "application/json" }`,
5814
5884
  options: {
@@ -5819,6 +5889,9 @@ var embeddingConfigs = {
5819
5889
  encodingFormat: {},
5820
5890
  openAiApiKey: {
5821
5891
  default: getEnvironmentVariable("OPENAI_API_KEY")
5892
+ },
5893
+ baseUrl: {
5894
+ default: "https://api.openai.com/v1"
5822
5895
  }
5823
5896
  },
5824
5897
  mapBody: {
@@ -6005,15 +6078,34 @@ function AmazonTitanEmbedding(result, config) {
6005
6078
  }
6006
6079
 
6007
6080
  // src/embedding/output/CohereBedrockEmbedding.ts
6008
- function CohereBedrockEmbedding(result, config) {
6081
+ function resolveEmbeddings(embeddings, model) {
6082
+ if (Array.isArray(embeddings)) {
6083
+ return embeddings;
6084
+ }
6085
+ if (embeddings && typeof embeddings === "object") {
6086
+ if (Array.isArray(embeddings.float)) {
6087
+ return embeddings.float;
6088
+ }
6089
+ throw new Error(
6090
+ `Unexpected embeddings in Cohere Bedrock response (model: "${model}"). Expected float embeddings, received object with keys: [${Object.keys(embeddings).join(", ")}]`
6091
+ );
6092
+ }
6093
+ throw new Error(
6094
+ `Unexpected embeddings shape in Cohere Bedrock response (model: "${model}"). Expected an array (Embed v3) or an object with float embeddings (Embed v4), received: ${embeddings === null ? "null" : typeof embeddings}`
6095
+ );
6096
+ }
6097
+ function CohereBedrockEmbedding(result, config, headers) {
6098
+ const headerUsage = getBedrockTokenCounts(headers);
6009
6099
  const __result = deepClone(result);
6010
6100
  const model = config.model || "cohere.unknown";
6011
6101
  const created = (/* @__PURE__ */ new Date()).getTime();
6012
- const embedding = Array.isArray(__result.embeddings) ? __result.embeddings : [];
6102
+ const embedding = resolveEmbeddings(__result.embeddings, model);
6103
+ const input_tokens = headerUsage?.input_tokens ?? 0;
6104
+ const output_tokens = headerUsage?.output_tokens ?? 0;
6013
6105
  const usage = {
6014
- output_tokens: 0,
6015
- input_tokens: 0,
6016
- total_tokens: 0
6106
+ output_tokens,
6107
+ input_tokens,
6108
+ total_tokens: input_tokens + output_tokens
6017
6109
  };
6018
6110
  return BaseEmbeddingOutput({
6019
6111
  id: __result.id,
@@ -6045,14 +6137,14 @@ function OpenAiEmbedding(result, config) {
6045
6137
  }
6046
6138
 
6047
6139
  // src/embedding/output/getEmbeddingOutputParser.ts
6048
- function getEmbeddingOutputParser(config, response) {
6140
+ function getEmbeddingOutputParser(config, response, headers) {
6049
6141
  switch (config.key) {
6050
6142
  case "openai.embedding.v1":
6051
6143
  return OpenAiEmbedding(response, config);
6052
6144
  case "amazon.embedding.v1":
6053
6145
  return AmazonTitanEmbedding(response, config);
6054
6146
  case "amazon:cohere.embedding.v1":
6055
- return CohereBedrockEmbedding(response, config);
6147
+ return CohereBedrockEmbedding(response, config, headers);
6056
6148
  default:
6057
6149
  throw new LlmExeError("Unsupported provider", {
6058
6150
  code: "embedding.invalid_response_shape",
@@ -6089,7 +6181,7 @@ async function createEmbedding_call(state, _input, _options) {
6089
6181
  body,
6090
6182
  headers
6091
6183
  });
6092
- return getEmbeddingOutputParser(state, request);
6184
+ return getEmbeddingOutputParser(state, request.data, request.headers);
6093
6185
  } catch (e) {
6094
6186
  if (!isLlmExeError(e, "request.http_error")) throw e;
6095
6187
  const ctx = e.context ?? {};
package/dist/index.mjs CHANGED
@@ -4286,6 +4286,20 @@ function anthropicPromptSanitize(_messages, _inputBodyObj, _outputObj) {
4286
4286
  return mergeConsecutiveSameRole(result);
4287
4287
  }
4288
4288
 
4289
+ // src/llm/output/_utils/getBedrockTokenCounts.ts
4290
+ function getBedrockTokenCounts(headers) {
4291
+ if (!headers) return void 0;
4292
+ const input = parseInt(headers["x-amzn-bedrock-input-token-count"], 10);
4293
+ const output = parseInt(headers["x-amzn-bedrock-output-token-count"], 10);
4294
+ if (!Number.isFinite(input) && !Number.isFinite(output)) {
4295
+ return void 0;
4296
+ }
4297
+ return {
4298
+ input_tokens: Number.isFinite(input) ? input : 0,
4299
+ output_tokens: Number.isFinite(output) ? output : 0
4300
+ };
4301
+ }
4302
+
4289
4303
  // src/llm/output/claude.ts
4290
4304
  function formatResult2(response) {
4291
4305
  const content = response?.content || [];
@@ -4308,15 +4322,18 @@ function formatResult2(response) {
4308
4322
  }
4309
4323
  return out;
4310
4324
  }
4311
- function OutputAnthropicClaude3Chat(result, _config) {
4325
+ function OutputAnthropicClaude3Chat(result, _config, headers) {
4312
4326
  const id = result.id;
4313
4327
  const name = result.model || _config?.options.model?.default || "anthropic.unknown";
4314
4328
  const stopReason = result.stop_reason;
4315
4329
  const content = formatResult2(result);
4330
+ const headerUsage = getBedrockTokenCounts(headers);
4331
+ const input_tokens = result?.usage?.input_tokens ?? headerUsage?.input_tokens ?? 0;
4332
+ const output_tokens = result?.usage?.output_tokens ?? headerUsage?.output_tokens ?? 0;
4316
4333
  const usage = {
4317
- input_tokens: result?.usage?.input_tokens,
4318
- output_tokens: result?.usage?.output_tokens,
4319
- total_tokens: result?.usage?.input_tokens + result?.usage?.output_tokens
4334
+ input_tokens,
4335
+ output_tokens,
4336
+ total_tokens: input_tokens + output_tokens
4320
4337
  };
4321
4338
  return {
4322
4339
  id,
@@ -4329,7 +4346,7 @@ function OutputAnthropicClaude3Chat(result, _config) {
4329
4346
  }
4330
4347
 
4331
4348
  // src/llm/output/llama.ts
4332
- function OutputMetaLlama3Chat(result, _config) {
4349
+ function OutputMetaLlama3Chat(result, _config, headers) {
4333
4350
  const id = uuidv4();
4334
4351
  const name = _config?.options?.model?.default || "meta";
4335
4352
  const created = (/* @__PURE__ */ new Date()).getTime();
@@ -4337,10 +4354,13 @@ function OutputMetaLlama3Chat(result, _config) {
4337
4354
  const content = [
4338
4355
  { type: "text", text: result.generation }
4339
4356
  ];
4357
+ const headerUsage = getBedrockTokenCounts(headers);
4358
+ const output_tokens = result?.generation_token_count ?? headerUsage?.output_tokens ?? 0;
4359
+ const input_tokens = result?.prompt_token_count ?? headerUsage?.input_tokens ?? 0;
4340
4360
  const usage = {
4341
- output_tokens: result?.generation_token_count,
4342
- input_tokens: result?.prompt_token_count,
4343
- total_tokens: result?.generation_token_count + result?.prompt_token_count
4361
+ output_tokens,
4362
+ input_tokens,
4363
+ total_tokens: output_tokens + input_tokens
4344
4364
  };
4345
4365
  return {
4346
4366
  id,
@@ -4458,7 +4478,7 @@ var bedrock = {
4458
4478
 
4459
4479
  // src/llm/config/anthropic/index.ts
4460
4480
  var ANTHROPIC_VERSION = "2023-06-01";
4461
- var MODELS_REJECTING_SAMPLING_PARAMS = ["claude-opus-4-7"];
4481
+ var MODELS_REJECTING_SAMPLING_PARAMS = ["claude-opus-4-7", "claude-opus-4-8"];
4462
4482
  var isClaude4x = (model) => /^claude-(opus|sonnet|haiku)-4-/.test(model);
4463
4483
  var dropIfModelRejectsSamplingParams = (v, body) => MODELS_REJECTING_SAMPLING_PARAMS.includes(body.model) ? void 0 : v;
4464
4484
  var topPTransform = (v, body) => {
@@ -4543,6 +4563,11 @@ var anthropicChatV1 = {
4543
4563
  };
4544
4564
  var anthropic = {
4545
4565
  "anthropic.chat.v1": anthropicChatV1,
4566
+ // Claude 4.8 models
4567
+ "anthropic.claude-opus-4-8": withDefaultModel(
4568
+ anthropicChatV1,
4569
+ "claude-opus-4-8"
4570
+ ),
4546
4571
  // Claude 4.7 models
4547
4572
  "anthropic.claude-opus-4-7": withDefaultModel(
4548
4573
  anthropicChatV1,
@@ -4726,7 +4751,11 @@ var ollamaChatV1 = {
4726
4751
  provider: "ollama.chat",
4727
4752
  endpoint: `${getEnvironmentVariable("OLLAMA_ENDPOINT") || `http://localhost:11434`}/api/chat`,
4728
4753
  options: {
4729
- prompt: {}
4754
+ prompt: {},
4755
+ temperature: {},
4756
+ topP: {},
4757
+ maxTokens: {},
4758
+ stopSequences: {}
4730
4759
  },
4731
4760
  method: "POST",
4732
4761
  headers: `{"Content-Type": "application/json" }`,
@@ -4742,6 +4771,18 @@ var ollamaChatV1 = {
4742
4771
  },
4743
4772
  model: {
4744
4773
  key: "model"
4774
+ },
4775
+ temperature: {
4776
+ key: "options.temperature"
4777
+ },
4778
+ topP: {
4779
+ key: "options.top_p"
4780
+ },
4781
+ maxTokens: {
4782
+ key: "options.num_predict"
4783
+ },
4784
+ stopSequences: {
4785
+ key: "options.stop"
4745
4786
  }
4746
4787
  },
4747
4788
  transformResponse: OutputOllamaChat
@@ -4937,7 +4978,10 @@ var googleGeminiChatV1 = {
4937
4978
  options: {
4938
4979
  effort: {},
4939
4980
  prompt: {},
4940
- // topP: {},
4981
+ temperature: {},
4982
+ topP: {},
4983
+ maxTokens: {},
4984
+ stopSequences: {},
4941
4985
  geminiApiKey: {
4942
4986
  default: getEnvironmentVariable("GEMINI_API_KEY")
4943
4987
  }
@@ -4949,6 +4993,18 @@ var googleGeminiChatV1 = {
4949
4993
  key: "contents",
4950
4994
  transform: googleGeminiPromptSanitize
4951
4995
  },
4996
+ temperature: {
4997
+ key: "generationConfig.temperature"
4998
+ },
4999
+ topP: {
5000
+ key: "generationConfig.topP"
5001
+ },
5002
+ maxTokens: {
5003
+ key: "generationConfig.maxOutputTokens"
5004
+ },
5005
+ stopSequences: {
5006
+ key: "generationConfig.stopSequences"
5007
+ },
4952
5008
  effort: {
4953
5009
  key: "config.thinkingConfig.thinkingBudget",
4954
5010
  transform: (v, _s) => {
@@ -5090,6 +5146,13 @@ function isValidUrl(input) {
5090
5146
  }
5091
5147
 
5092
5148
  // src/utils/modules/request.ts
5149
+ function headersToRecord(headers) {
5150
+ const record = {};
5151
+ headers.forEach((value, key) => {
5152
+ record[key.toLowerCase()] = value;
5153
+ });
5154
+ return record;
5155
+ }
5093
5156
  async function apiRequest(url, options) {
5094
5157
  const finalOptions = {
5095
5158
  ...options
@@ -5175,13 +5238,16 @@ async function apiRequest(url, options) {
5175
5238
  });
5176
5239
  }
5177
5240
  const contentType = response.headers.get("content-type");
5241
+ const headers = headersToRecord(response.headers);
5178
5242
  if (contentType?.includes("application/json")) {
5179
- const responseData = await response.json();
5180
- return responseData;
5181
- } else {
5182
- const responseData = await response.text();
5183
- return responseData;
5243
+ const responseData2 = await response.json();
5244
+ return { data: responseData2, headers };
5184
5245
  }
5246
+ const responseData = await response.text();
5247
+ return {
5248
+ data: responseData,
5249
+ headers
5250
+ };
5185
5251
  }
5186
5252
 
5187
5253
  // src/utils/modules/convertDotNotation.ts
@@ -5553,7 +5619,7 @@ async function useLlm_call(state, messages, _options) {
5553
5619
  }
5554
5620
  ]
5555
5621
  };
5556
- return BaseLlmOutput(transformResponse(mockResponse, config));
5622
+ return BaseLlmOutput(transformResponse(mockResponse, config, {}));
5557
5623
  }
5558
5624
  try {
5559
5625
  const response = await apiRequest(url, {
@@ -5561,7 +5627,9 @@ async function useLlm_call(state, messages, _options) {
5561
5627
  body,
5562
5628
  headers
5563
5629
  });
5564
- return BaseLlmOutput(transformResponse(response, config));
5630
+ return BaseLlmOutput(
5631
+ transformResponse(response.data, config, response.headers)
5632
+ );
5565
5633
  } catch (e) {
5566
5634
  if (!isLlmExeError(e, "request.http_error")) throw e;
5567
5635
  const ctx = e.context ?? {};
@@ -5742,7 +5810,9 @@ var embeddingConfigs = {
5742
5810
  "openai.embedding.v1": {
5743
5811
  key: "openai.embedding.v1",
5744
5812
  provider: "openai.embedding",
5745
- endpoint: `https://api.openai.com/v1/embeddings`,
5813
+ // Templated host: `baseUrl` defaults to OpenAI. Override to point at any
5814
+ // OpenAI-compatible embeddings server (Baseten, vLLM, TEI, Together, etc.).
5815
+ endpoint: `{{baseUrl}}/embeddings`,
5746
5816
  method: "POST",
5747
5817
  headers: `{"Authorization":"Bearer {{openAiApiKey}}", "Content-Type": "application/json" }`,
5748
5818
  options: {
@@ -5753,6 +5823,9 @@ var embeddingConfigs = {
5753
5823
  encodingFormat: {},
5754
5824
  openAiApiKey: {
5755
5825
  default: getEnvironmentVariable("OPENAI_API_KEY")
5826
+ },
5827
+ baseUrl: {
5828
+ default: "https://api.openai.com/v1"
5756
5829
  }
5757
5830
  },
5758
5831
  mapBody: {
@@ -5939,15 +6012,34 @@ function AmazonTitanEmbedding(result, config) {
5939
6012
  }
5940
6013
 
5941
6014
  // src/embedding/output/CohereBedrockEmbedding.ts
5942
- function CohereBedrockEmbedding(result, config) {
6015
+ function resolveEmbeddings(embeddings, model) {
6016
+ if (Array.isArray(embeddings)) {
6017
+ return embeddings;
6018
+ }
6019
+ if (embeddings && typeof embeddings === "object") {
6020
+ if (Array.isArray(embeddings.float)) {
6021
+ return embeddings.float;
6022
+ }
6023
+ throw new Error(
6024
+ `Unexpected embeddings in Cohere Bedrock response (model: "${model}"). Expected float embeddings, received object with keys: [${Object.keys(embeddings).join(", ")}]`
6025
+ );
6026
+ }
6027
+ throw new Error(
6028
+ `Unexpected embeddings shape in Cohere Bedrock response (model: "${model}"). Expected an array (Embed v3) or an object with float embeddings (Embed v4), received: ${embeddings === null ? "null" : typeof embeddings}`
6029
+ );
6030
+ }
6031
+ function CohereBedrockEmbedding(result, config, headers) {
6032
+ const headerUsage = getBedrockTokenCounts(headers);
5943
6033
  const __result = deepClone(result);
5944
6034
  const model = config.model || "cohere.unknown";
5945
6035
  const created = (/* @__PURE__ */ new Date()).getTime();
5946
- const embedding = Array.isArray(__result.embeddings) ? __result.embeddings : [];
6036
+ const embedding = resolveEmbeddings(__result.embeddings, model);
6037
+ const input_tokens = headerUsage?.input_tokens ?? 0;
6038
+ const output_tokens = headerUsage?.output_tokens ?? 0;
5947
6039
  const usage = {
5948
- output_tokens: 0,
5949
- input_tokens: 0,
5950
- total_tokens: 0
6040
+ output_tokens,
6041
+ input_tokens,
6042
+ total_tokens: input_tokens + output_tokens
5951
6043
  };
5952
6044
  return BaseEmbeddingOutput({
5953
6045
  id: __result.id,
@@ -5979,14 +6071,14 @@ function OpenAiEmbedding(result, config) {
5979
6071
  }
5980
6072
 
5981
6073
  // src/embedding/output/getEmbeddingOutputParser.ts
5982
- function getEmbeddingOutputParser(config, response) {
6074
+ function getEmbeddingOutputParser(config, response, headers) {
5983
6075
  switch (config.key) {
5984
6076
  case "openai.embedding.v1":
5985
6077
  return OpenAiEmbedding(response, config);
5986
6078
  case "amazon.embedding.v1":
5987
6079
  return AmazonTitanEmbedding(response, config);
5988
6080
  case "amazon:cohere.embedding.v1":
5989
- return CohereBedrockEmbedding(response, config);
6081
+ return CohereBedrockEmbedding(response, config, headers);
5990
6082
  default:
5991
6083
  throw new LlmExeError("Unsupported provider", {
5992
6084
  code: "embedding.invalid_response_shape",
@@ -6023,7 +6115,7 @@ async function createEmbedding_call(state, _input, _options) {
6023
6115
  body,
6024
6116
  headers
6025
6117
  });
6026
- return getEmbeddingOutputParser(state, request);
6118
+ return getEmbeddingOutputParser(state, request.data, request.headers);
6027
6119
  } catch (e) {
6028
6120
  if (!isLlmExeError(e, "request.http_error")) throw e;
6029
6121
  const ctx = e.context ?? {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "llm-exe",
3
- "version": "3.0.0-beta.2",
3
+ "version": "3.0.0",
4
4
  "description": "Simplify building LLM-powered apps with easy-to-use base components, supporting text and chat-based prompts with handlebars template engine, output parsers, and flexible function calling capabilities.",
5
5
  "keywords": [
6
6
  "ai",
package/readme.md CHANGED
@@ -9,7 +9,7 @@ A package that provides simplified base components to make building and maintain
9
9
  - Write functions powered by LLM's with easy to use building blocks.
10
10
  - Pure Javascript and Typescript. Allows you to pass and infer types.
11
11
  - Supercharge your prompts by using handlebars within prompt template.
12
- - Support for text-based (llama-3) and chat-based prompts. (gpt-4o, claude-3.5, grok-3, Gemini, Bedrock, Ollama, etc)
12
+ - Support for text-based and chat-based prompts. (ChatGPT, Claude, Grok, Gemini, Bedrock, Ollama, etc)
13
13
  - Call LLM's from different providers without changing your code. (OpenAi/Anthropic/xAI/Google/AWS Bedrock/Ollama/Deepseek)
14
14
  - Allow LLM's to call functions (or call other LLM executors).
15
15
  - Not very opinionated. You have control on how you use it.