@jambonz/llm 0.4.6 → 0.5.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.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as ServiceAccountJson, A as AuthSpec, a as AuthKindSchema, P as PromptRequest, b as AdapterFactory, c as AdapterManifest, C as CreateLlmArgs, L as LlmAdapter } from './types-DbqWrdT6.cjs';
2
- export { d as ApiKeyAuth, e as AuthKind, f as AzureOpenAIApiKeyAuth, B as BedrockApiKeyAuth, g as BedrockIamAuth, h as ClientOptions, i as ContentBlock, F as FinishReason, j as FormField, k as FormFieldType, G as GoogleApiKeyAuth, l as GoogleServiceAccountAuth, J as JsonSchema, m as LlmEvent, M as Message, n as ModelCapabilities, o as ModelInfo, R as Role, T as Tool, p as ToolCallEvent, U as Usage, V as VertexServiceAccountAuth } from './types-DbqWrdT6.cjs';
1
+ import { S as ServiceAccountJson, A as AuthSpec, a as AuthKindSchema, P as PromptRequest, b as AdapterFactory, c as AdapterManifest, C as CreateLlmArgs, L as LlmAdapter } from './types-BWsmVtXv.cjs';
2
+ export { d as ApiKeyAuth, e as AuthKind, f as AzureOpenAIApiKeyAuth, B as BedrockApiKeyAuth, g as BedrockIamAuth, h as ClientOptions, i as ContentBlock, F as FinishReason, j as FormField, k as FormFieldType, G as GoogleApiKeyAuth, l as GoogleServiceAccountAuth, J as JsonSchema, m as LlmEvent, M as Message, n as ModelCapabilities, o as ModelInfo, R as Role, T as Tool, p as ToolCallEvent, U as Usage, V as VertexServiceAccountAuth } from './types-BWsmVtXv.cjs';
3
3
 
4
4
  /**
5
5
  * The loose "DB-shape" input accepted by `normalizeAuth`.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { S as ServiceAccountJson, A as AuthSpec, a as AuthKindSchema, P as PromptRequest, b as AdapterFactory, c as AdapterManifest, C as CreateLlmArgs, L as LlmAdapter } from './types-DbqWrdT6.js';
2
- export { d as ApiKeyAuth, e as AuthKind, f as AzureOpenAIApiKeyAuth, B as BedrockApiKeyAuth, g as BedrockIamAuth, h as ClientOptions, i as ContentBlock, F as FinishReason, j as FormField, k as FormFieldType, G as GoogleApiKeyAuth, l as GoogleServiceAccountAuth, J as JsonSchema, m as LlmEvent, M as Message, n as ModelCapabilities, o as ModelInfo, R as Role, T as Tool, p as ToolCallEvent, U as Usage, V as VertexServiceAccountAuth } from './types-DbqWrdT6.js';
1
+ import { S as ServiceAccountJson, A as AuthSpec, a as AuthKindSchema, P as PromptRequest, b as AdapterFactory, c as AdapterManifest, C as CreateLlmArgs, L as LlmAdapter } from './types-BWsmVtXv.js';
2
+ export { d as ApiKeyAuth, e as AuthKind, f as AzureOpenAIApiKeyAuth, B as BedrockApiKeyAuth, g as BedrockIamAuth, h as ClientOptions, i as ContentBlock, F as FinishReason, j as FormField, k as FormFieldType, G as GoogleApiKeyAuth, l as GoogleServiceAccountAuth, J as JsonSchema, m as LlmEvent, M as Message, n as ModelCapabilities, o as ModelInfo, R as Role, T as Tool, p as ToolCallEvent, U as Usage, V as VertexServiceAccountAuth } from './types-BWsmVtXv.js';
3
3
 
4
4
  /**
5
5
  * The loose "DB-shape" input accepted by `normalizeAuth`.
package/dist/index.js CHANGED
@@ -86,8 +86,17 @@ async function* streamFromOpenAI(client, req, options) {
86
86
  body[param] = effectiveMaxTokens;
87
87
  }
88
88
  let stream;
89
+ let responseHeaders;
89
90
  try {
90
- stream = await client.chat.completions.create(body, { signal: req.signal });
91
+ const apiPromise = client.chat.completions.create(body, { signal: req.signal });
92
+ const maybeWithResponse = apiPromise.withResponse;
93
+ if (typeof maybeWithResponse === "function") {
94
+ const result = await maybeWithResponse.call(apiPromise);
95
+ stream = result.data;
96
+ responseHeaders = result.response?.headers;
97
+ } else {
98
+ stream = await apiPromise;
99
+ }
91
100
  } catch (err) {
92
101
  if (isAbortError(err)) {
93
102
  yield { type: "end", finishReason: "aborted" };
@@ -182,6 +191,12 @@ async function* streamFromOpenAI(client, req, options) {
182
191
  ...usage ? { usage } : {},
183
192
  ...finalRawReason ? { rawReason: finalRawReason } : {}
184
193
  };
194
+ if (options.vendorMetadataExtractor && responseHeaders) {
195
+ const metadata = options.vendorMetadataExtractor(responseHeaders);
196
+ if (metadata && Object.keys(metadata).length > 0) {
197
+ endEvent.vendorMetadata = metadata;
198
+ }
199
+ }
185
200
  yield endEvent;
186
201
  }
187
202
  function appendOpenAIAssistantToolCall(history, toolCalls) {
@@ -309,6 +324,40 @@ function isAbortError(err) {
309
324
  return e.name === "APIUserAbortError" || e.name === "AbortError" || e.code === "ABORT_ERR" || typeof e.message === "string" && /aborted/i.test(e.message);
310
325
  }
311
326
 
327
+ // src/adapters/_metadata.ts
328
+ function makeMetadataExtractor(fields) {
329
+ return (headers) => {
330
+ const out = {};
331
+ for (const f of fields) {
332
+ const raw = headers.get(f.header);
333
+ if (raw === null || raw === void 0 || raw === "") continue;
334
+ if (f.numeric) {
335
+ const n = Number(raw);
336
+ if (Number.isFinite(n)) out[f.key] = n;
337
+ } else {
338
+ out[f.key] = raw;
339
+ }
340
+ }
341
+ return out;
342
+ };
343
+ }
344
+ function extractMetadata(fields, headers) {
345
+ const headersInstance = headers instanceof Headers ? headers : recordToHeaders(headers);
346
+ return makeMetadataExtractor(fields)(headersInstance);
347
+ }
348
+ function recordToHeaders(record) {
349
+ const h = new Headers();
350
+ for (const [name, value] of Object.entries(record)) {
351
+ if (value === void 0) continue;
352
+ if (Array.isArray(value)) {
353
+ for (const v of value) h.append(name, v);
354
+ } else {
355
+ h.set(name, value);
356
+ }
357
+ }
358
+ return h;
359
+ }
360
+
312
361
  // src/adapters/openai/manifest.ts
313
362
  var OPENAI_KNOWN_MODELS = [
314
363
  {
@@ -410,6 +459,12 @@ var openAIManifest = {
410
459
  };
411
460
 
412
461
  // src/adapters/openai/adapter.ts
462
+ var OPENAI_METADATA_EXTRACTOR = makeMetadataExtractor([
463
+ { header: "x-request-id", key: "request_id" },
464
+ { header: "openai-processing-ms", key: "processing_ms", numeric: true },
465
+ { header: "x-ratelimit-remaining-requests", key: "requests_remaining", numeric: true },
466
+ { header: "x-ratelimit-remaining-tokens", key: "tokens_remaining", numeric: true }
467
+ ]);
413
468
  var OpenAIAdapter = class {
414
469
  vendor = openAIManifest.vendor;
415
470
  acceptedAuth = ["apiKey"];
@@ -427,7 +482,8 @@ var OpenAIAdapter = class {
427
482
  }
428
483
  stream(req) {
429
484
  return streamFromOpenAI(this.ensureClient(), req, {
430
- knownModels: openAIManifest.knownModels
485
+ knownModels: openAIManifest.knownModels,
486
+ vendorMetadataExtractor: OPENAI_METADATA_EXTRACTOR
431
487
  });
432
488
  }
433
489
  appendAssistantToolCall(history, toolCalls) {
@@ -659,6 +715,12 @@ var anthropicManifest = {
659
715
  };
660
716
 
661
717
  // src/adapters/anthropic/adapter.ts
718
+ var ANTHROPIC_METADATA_EXTRACTOR = makeMetadataExtractor([
719
+ { header: "request-id", key: "request_id" },
720
+ { header: "anthropic-ratelimit-requests-remaining", key: "requests_remaining", numeric: true },
721
+ { header: "anthropic-ratelimit-input-tokens-remaining", key: "input_tokens_remaining", numeric: true },
722
+ { header: "anthropic-ratelimit-output-tokens-remaining", key: "output_tokens_remaining", numeric: true }
723
+ ]);
662
724
  var AnthropicAdapter = class {
663
725
  vendor = anthropicManifest.vendor;
664
726
  acceptedAuth = ["apiKey"];
@@ -693,11 +755,20 @@ var AnthropicAdapter = class {
693
755
  if (tools) body.tools = tools;
694
756
  if (req.temperature !== void 0) body.temperature = req.temperature;
695
757
  let stream;
758
+ let responseHeaders;
696
759
  try {
697
- stream = await client.messages.create(
760
+ const apiPromise = client.messages.create(
698
761
  body,
699
762
  { signal: req.signal }
700
763
  );
764
+ const maybeWithResponse = apiPromise.withResponse;
765
+ if (typeof maybeWithResponse === "function") {
766
+ const result = await maybeWithResponse.call(apiPromise);
767
+ stream = result.data;
768
+ responseHeaders = result.response?.headers;
769
+ } else {
770
+ stream = await apiPromise;
771
+ }
701
772
  } catch (err) {
702
773
  if (isAbortError2(err)) {
703
774
  yield { type: "end", finishReason: "aborted" };
@@ -808,6 +879,12 @@ var AnthropicAdapter = class {
808
879
  ...usage ? { usage } : {},
809
880
  ...stopReason ? { rawReason: stopReason } : {}
810
881
  };
882
+ if (responseHeaders) {
883
+ const metadata = ANTHROPIC_METADATA_EXTRACTOR(responseHeaders);
884
+ if (Object.keys(metadata).length > 0) {
885
+ endEvent.vendorMetadata = metadata;
886
+ }
887
+ }
811
888
  yield endEvent;
812
889
  }
813
890
  appendAssistantToolCall(history, toolCalls) {
@@ -1600,6 +1677,9 @@ var vertexOpenAIManifest = {
1600
1677
  };
1601
1678
 
1602
1679
  // src/adapters/vertex-openai/adapter.ts
1680
+ var VERTEX_OPENAI_METADATA_EXTRACTOR = makeMetadataExtractor([
1681
+ { header: "x-request-id", key: "request_id" }
1682
+ ]);
1603
1683
  var VertexOpenAIAdapter = class {
1604
1684
  vendor = vertexOpenAIManifest.vendor;
1605
1685
  acceptedAuth = ["vertexServiceAccount"];
@@ -1652,7 +1732,8 @@ var VertexOpenAIAdapter = class {
1652
1732
  // endpoint predates `max_completion_tokens` and may not recognize it.
1653
1733
  // The model-id heuristic wouldn't catch a partner model named in the
1654
1734
  // OpenAI style (unlikely today, but defensive).
1655
- tokensParam: "max_tokens"
1735
+ tokensParam: "max_tokens",
1736
+ vendorMetadataExtractor: VERTEX_OPENAI_METADATA_EXTRACTOR
1656
1737
  });
1657
1738
  }
1658
1739
  appendAssistantToolCall(history, toolCalls) {
@@ -2116,6 +2197,21 @@ var BedrockAdapter = class {
2116
2197
  ...usage ? { usage } : {},
2117
2198
  ...stopReason ? { rawReason: stopReason } : {}
2118
2199
  };
2200
+ const httpHeaders = response.$metadata?.httpHeaders;
2201
+ if (httpHeaders) {
2202
+ const metadata = extractMetadata(
2203
+ [
2204
+ { header: "x-amzn-bedrock-invocation-latency", key: "invocation_latency_ms", numeric: true },
2205
+ { header: "x-amzn-bedrock-cache-read-input-token-count", key: "cache_read_input_tokens", numeric: true },
2206
+ { header: "x-amzn-bedrock-cache-write-input-token-count", key: "cache_write_input_tokens", numeric: true },
2207
+ { header: "x-amzn-bedrock-trace-id", key: "trace_id" }
2208
+ ],
2209
+ httpHeaders
2210
+ );
2211
+ if (Object.keys(metadata).length > 0) {
2212
+ endEvent.vendorMetadata = metadata;
2213
+ }
2214
+ }
2119
2215
  yield endEvent;
2120
2216
  }
2121
2217
  appendAssistantToolCall(history, toolCalls) {
@@ -2367,6 +2463,14 @@ var azureOpenAIManifest = {
2367
2463
  };
2368
2464
 
2369
2465
  // src/adapters/azure-openai/adapter.ts
2466
+ var AZURE_OPENAI_METADATA_EXTRACTOR = makeMetadataExtractor([
2467
+ { header: "x-ms-region", key: "region" },
2468
+ { header: "x-ms-deployment-name", key: "deployment" },
2469
+ { header: "apim-request-id", key: "request_id" },
2470
+ { header: "azureml-model-session", key: "model_session" },
2471
+ { header: "x-ratelimit-remaining-requests", key: "requests_remaining", numeric: true },
2472
+ { header: "x-ratelimit-remaining-tokens", key: "tokens_remaining", numeric: true }
2473
+ ]);
2370
2474
  var AzureOpenAIAdapter = class {
2371
2475
  vendor = azureOpenAIManifest.vendor;
2372
2476
  acceptedAuth = ["azureOpenAIApiKey"];
@@ -2401,7 +2505,8 @@ var AzureOpenAIAdapter = class {
2401
2505
  stream(req) {
2402
2506
  return streamFromOpenAI(this.ensureClient(), req, {
2403
2507
  knownModels: azureOpenAIManifest.knownModels,
2404
- tokensParam: "max_completion_tokens"
2508
+ tokensParam: "max_completion_tokens",
2509
+ vendorMetadataExtractor: AZURE_OPENAI_METADATA_EXTRACTOR
2405
2510
  });
2406
2511
  }
2407
2512
  appendAssistantToolCall(history, toolCalls) {
@@ -2526,6 +2631,12 @@ var groqManifest = {
2526
2631
  };
2527
2632
 
2528
2633
  // src/adapters/groq/adapter.ts
2634
+ var GROQ_METADATA_EXTRACTOR = makeMetadataExtractor([
2635
+ { header: "x-request-id", key: "request_id" },
2636
+ { header: "x-groq-region", key: "region" },
2637
+ { header: "x-ratelimit-remaining-requests", key: "requests_remaining", numeric: true },
2638
+ { header: "x-ratelimit-remaining-tokens", key: "tokens_remaining", numeric: true }
2639
+ ]);
2529
2640
  var GroqAdapter = class extends OpenAIAdapter {
2530
2641
  vendor = groqManifest.vendor;
2531
2642
  init(auth, client) {
@@ -2537,6 +2648,12 @@ var GroqAdapter = class extends OpenAIAdapter {
2537
2648
  client
2538
2649
  );
2539
2650
  }
2651
+ stream(req) {
2652
+ return streamFromOpenAI(this.ensureClient(), req, {
2653
+ knownModels: groqManifest.knownModels,
2654
+ vendorMetadataExtractor: GROQ_METADATA_EXTRACTOR
2655
+ });
2656
+ }
2540
2657
  };
2541
2658
 
2542
2659
  // src/adapters/groq/factory.ts
@@ -2637,6 +2754,10 @@ var huggingfaceManifest = {
2637
2754
  };
2638
2755
 
2639
2756
  // src/adapters/huggingface/adapter.ts
2757
+ var HUGGINGFACE_METADATA_EXTRACTOR = makeMetadataExtractor([
2758
+ { header: "x-inference-provider", key: "provider" },
2759
+ { header: "x-request-id", key: "request_id" }
2760
+ ]);
2640
2761
  var HuggingfaceAdapter = class extends OpenAIAdapter {
2641
2762
  vendor = huggingfaceManifest.vendor;
2642
2763
  init(auth, client) {
@@ -2648,6 +2769,12 @@ var HuggingfaceAdapter = class extends OpenAIAdapter {
2648
2769
  client
2649
2770
  );
2650
2771
  }
2772
+ stream(req) {
2773
+ return streamFromOpenAI(this.ensureClient(), req, {
2774
+ knownModels: huggingfaceManifest.knownModels,
2775
+ vendorMetadataExtractor: HUGGINGFACE_METADATA_EXTRACTOR
2776
+ });
2777
+ }
2651
2778
  };
2652
2779
 
2653
2780
  // src/adapters/huggingface/factory.ts