@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.
@@ -1,4 +1,4 @@
1
- import { b as AdapterFactory, e as AuthKind, A as AuthSpec, L as LlmAdapter, d as ApiKeyAuth, h as ClientOptions, P as PromptRequest, m as LlmEvent, M as Message, p as ToolCallEvent, o as ModelInfo, c as AdapterManifest } from '../types-DbqWrdT6.cjs';
1
+ import { b as AdapterFactory, e as AuthKind, A as AuthSpec, L as LlmAdapter, d as ApiKeyAuth, h as ClientOptions, P as PromptRequest, m as LlmEvent, M as Message, p as ToolCallEvent, o as ModelInfo, c as AdapterManifest } from '../types-BWsmVtXv.cjs';
2
2
 
3
3
  /**
4
4
  * Named scenarios the harness must be able to stage. Each scenario configures
@@ -1,4 +1,4 @@
1
- import { b as AdapterFactory, e as AuthKind, A as AuthSpec, L as LlmAdapter, d as ApiKeyAuth, h as ClientOptions, P as PromptRequest, m as LlmEvent, M as Message, p as ToolCallEvent, o as ModelInfo, c as AdapterManifest } from '../types-DbqWrdT6.js';
1
+ import { b as AdapterFactory, e as AuthKind, A as AuthSpec, L as LlmAdapter, d as ApiKeyAuth, h as ClientOptions, P as PromptRequest, m as LlmEvent, M as Message, p as ToolCallEvent, o as ModelInfo, c as AdapterManifest } from '../types-BWsmVtXv.js';
2
2
 
3
3
  /**
4
4
  * Named scenarios the harness must be able to stage. Each scenario configures
@@ -79,8 +79,17 @@ async function* streamFromOpenAI(client, req, options) {
79
79
  body[param] = effectiveMaxTokens;
80
80
  }
81
81
  let stream;
82
+ let responseHeaders;
82
83
  try {
83
- stream = await client.chat.completions.create(body, { signal: req.signal });
84
+ const apiPromise = client.chat.completions.create(body, { signal: req.signal });
85
+ const maybeWithResponse = apiPromise.withResponse;
86
+ if (typeof maybeWithResponse === "function") {
87
+ const result = await maybeWithResponse.call(apiPromise);
88
+ stream = result.data;
89
+ responseHeaders = result.response?.headers;
90
+ } else {
91
+ stream = await apiPromise;
92
+ }
84
93
  } catch (err) {
85
94
  if (isAbortError(err)) {
86
95
  yield { type: "end", finishReason: "aborted" };
@@ -175,6 +184,12 @@ async function* streamFromOpenAI(client, req, options) {
175
184
  ...usage ? { usage } : {},
176
185
  ...finalRawReason ? { rawReason: finalRawReason } : {}
177
186
  };
187
+ if (options.vendorMetadataExtractor && responseHeaders) {
188
+ const metadata = options.vendorMetadataExtractor(responseHeaders);
189
+ if (metadata && Object.keys(metadata).length > 0) {
190
+ endEvent.vendorMetadata = metadata;
191
+ }
192
+ }
178
193
  yield endEvent;
179
194
  }
180
195
  function appendOpenAIAssistantToolCall(history, toolCalls) {
@@ -302,6 +317,40 @@ function isAbortError(err) {
302
317
  return e.name === "APIUserAbortError" || e.name === "AbortError" || e.code === "ABORT_ERR" || typeof e.message === "string" && /aborted/i.test(e.message);
303
318
  }
304
319
 
320
+ // src/adapters/_metadata.ts
321
+ function makeMetadataExtractor(fields) {
322
+ return (headers) => {
323
+ const out = {};
324
+ for (const f of fields) {
325
+ const raw = headers.get(f.header);
326
+ if (raw === null || raw === void 0 || raw === "") continue;
327
+ if (f.numeric) {
328
+ const n = Number(raw);
329
+ if (Number.isFinite(n)) out[f.key] = n;
330
+ } else {
331
+ out[f.key] = raw;
332
+ }
333
+ }
334
+ return out;
335
+ };
336
+ }
337
+ function extractMetadata(fields, headers) {
338
+ const headersInstance = headers instanceof Headers ? headers : recordToHeaders(headers);
339
+ return makeMetadataExtractor(fields)(headersInstance);
340
+ }
341
+ function recordToHeaders(record) {
342
+ const h = new Headers();
343
+ for (const [name, value] of Object.entries(record)) {
344
+ if (value === void 0) continue;
345
+ if (Array.isArray(value)) {
346
+ for (const v of value) h.append(name, v);
347
+ } else {
348
+ h.set(name, value);
349
+ }
350
+ }
351
+ return h;
352
+ }
353
+
305
354
  // src/adapters/openai/manifest.ts
306
355
  var OPENAI_KNOWN_MODELS = [
307
356
  {
@@ -403,6 +452,12 @@ var openAIManifest = {
403
452
  };
404
453
 
405
454
  // src/adapters/openai/adapter.ts
455
+ var OPENAI_METADATA_EXTRACTOR = makeMetadataExtractor([
456
+ { header: "x-request-id", key: "request_id" },
457
+ { header: "openai-processing-ms", key: "processing_ms", numeric: true },
458
+ { header: "x-ratelimit-remaining-requests", key: "requests_remaining", numeric: true },
459
+ { header: "x-ratelimit-remaining-tokens", key: "tokens_remaining", numeric: true }
460
+ ]);
406
461
  var OpenAIAdapter = class {
407
462
  vendor = openAIManifest.vendor;
408
463
  acceptedAuth = ["apiKey"];
@@ -420,7 +475,8 @@ var OpenAIAdapter = class {
420
475
  }
421
476
  stream(req) {
422
477
  return streamFromOpenAI(this.ensureClient(), req, {
423
- knownModels: openAIManifest.knownModels
478
+ knownModels: openAIManifest.knownModels,
479
+ vendorMetadataExtractor: OPENAI_METADATA_EXTRACTOR
424
480
  });
425
481
  }
426
482
  appendAssistantToolCall(history, toolCalls) {
@@ -652,6 +708,12 @@ var anthropicManifest = {
652
708
  };
653
709
 
654
710
  // src/adapters/anthropic/adapter.ts
711
+ var ANTHROPIC_METADATA_EXTRACTOR = makeMetadataExtractor([
712
+ { header: "request-id", key: "request_id" },
713
+ { header: "anthropic-ratelimit-requests-remaining", key: "requests_remaining", numeric: true },
714
+ { header: "anthropic-ratelimit-input-tokens-remaining", key: "input_tokens_remaining", numeric: true },
715
+ { header: "anthropic-ratelimit-output-tokens-remaining", key: "output_tokens_remaining", numeric: true }
716
+ ]);
655
717
  var AnthropicAdapter = class {
656
718
  vendor = anthropicManifest.vendor;
657
719
  acceptedAuth = ["apiKey"];
@@ -686,11 +748,20 @@ var AnthropicAdapter = class {
686
748
  if (tools) body.tools = tools;
687
749
  if (req.temperature !== void 0) body.temperature = req.temperature;
688
750
  let stream;
751
+ let responseHeaders;
689
752
  try {
690
- stream = await client.messages.create(
753
+ const apiPromise = client.messages.create(
691
754
  body,
692
755
  { signal: req.signal }
693
756
  );
757
+ const maybeWithResponse = apiPromise.withResponse;
758
+ if (typeof maybeWithResponse === "function") {
759
+ const result = await maybeWithResponse.call(apiPromise);
760
+ stream = result.data;
761
+ responseHeaders = result.response?.headers;
762
+ } else {
763
+ stream = await apiPromise;
764
+ }
694
765
  } catch (err) {
695
766
  if (isAbortError2(err)) {
696
767
  yield { type: "end", finishReason: "aborted" };
@@ -801,6 +872,12 @@ var AnthropicAdapter = class {
801
872
  ...usage ? { usage } : {},
802
873
  ...stopReason ? { rawReason: stopReason } : {}
803
874
  };
875
+ if (responseHeaders) {
876
+ const metadata = ANTHROPIC_METADATA_EXTRACTOR(responseHeaders);
877
+ if (Object.keys(metadata).length > 0) {
878
+ endEvent.vendorMetadata = metadata;
879
+ }
880
+ }
804
881
  yield endEvent;
805
882
  }
806
883
  appendAssistantToolCall(history, toolCalls) {
@@ -1593,6 +1670,9 @@ var vertexOpenAIManifest = {
1593
1670
  };
1594
1671
 
1595
1672
  // src/adapters/vertex-openai/adapter.ts
1673
+ var VERTEX_OPENAI_METADATA_EXTRACTOR = makeMetadataExtractor([
1674
+ { header: "x-request-id", key: "request_id" }
1675
+ ]);
1596
1676
  var VertexOpenAIAdapter = class {
1597
1677
  vendor = vertexOpenAIManifest.vendor;
1598
1678
  acceptedAuth = ["vertexServiceAccount"];
@@ -1645,7 +1725,8 @@ var VertexOpenAIAdapter = class {
1645
1725
  // endpoint predates `max_completion_tokens` and may not recognize it.
1646
1726
  // The model-id heuristic wouldn't catch a partner model named in the
1647
1727
  // OpenAI style (unlikely today, but defensive).
1648
- tokensParam: "max_tokens"
1728
+ tokensParam: "max_tokens",
1729
+ vendorMetadataExtractor: VERTEX_OPENAI_METADATA_EXTRACTOR
1649
1730
  });
1650
1731
  }
1651
1732
  appendAssistantToolCall(history, toolCalls) {
@@ -2109,6 +2190,21 @@ var BedrockAdapter = class {
2109
2190
  ...usage ? { usage } : {},
2110
2191
  ...stopReason ? { rawReason: stopReason } : {}
2111
2192
  };
2193
+ const httpHeaders = response.$metadata?.httpHeaders;
2194
+ if (httpHeaders) {
2195
+ const metadata = extractMetadata(
2196
+ [
2197
+ { header: "x-amzn-bedrock-invocation-latency", key: "invocation_latency_ms", numeric: true },
2198
+ { header: "x-amzn-bedrock-cache-read-input-token-count", key: "cache_read_input_tokens", numeric: true },
2199
+ { header: "x-amzn-bedrock-cache-write-input-token-count", key: "cache_write_input_tokens", numeric: true },
2200
+ { header: "x-amzn-bedrock-trace-id", key: "trace_id" }
2201
+ ],
2202
+ httpHeaders
2203
+ );
2204
+ if (Object.keys(metadata).length > 0) {
2205
+ endEvent.vendorMetadata = metadata;
2206
+ }
2207
+ }
2112
2208
  yield endEvent;
2113
2209
  }
2114
2210
  appendAssistantToolCall(history, toolCalls) {
@@ -2360,6 +2456,14 @@ var azureOpenAIManifest = {
2360
2456
  };
2361
2457
 
2362
2458
  // src/adapters/azure-openai/adapter.ts
2459
+ var AZURE_OPENAI_METADATA_EXTRACTOR = makeMetadataExtractor([
2460
+ { header: "x-ms-region", key: "region" },
2461
+ { header: "x-ms-deployment-name", key: "deployment" },
2462
+ { header: "apim-request-id", key: "request_id" },
2463
+ { header: "azureml-model-session", key: "model_session" },
2464
+ { header: "x-ratelimit-remaining-requests", key: "requests_remaining", numeric: true },
2465
+ { header: "x-ratelimit-remaining-tokens", key: "tokens_remaining", numeric: true }
2466
+ ]);
2363
2467
  var AzureOpenAIAdapter = class {
2364
2468
  vendor = azureOpenAIManifest.vendor;
2365
2469
  acceptedAuth = ["azureOpenAIApiKey"];
@@ -2394,7 +2498,8 @@ var AzureOpenAIAdapter = class {
2394
2498
  stream(req) {
2395
2499
  return streamFromOpenAI(this.ensureClient(), req, {
2396
2500
  knownModels: azureOpenAIManifest.knownModels,
2397
- tokensParam: "max_completion_tokens"
2501
+ tokensParam: "max_completion_tokens",
2502
+ vendorMetadataExtractor: AZURE_OPENAI_METADATA_EXTRACTOR
2398
2503
  });
2399
2504
  }
2400
2505
  appendAssistantToolCall(history, toolCalls) {
@@ -2519,6 +2624,12 @@ var groqManifest = {
2519
2624
  };
2520
2625
 
2521
2626
  // src/adapters/groq/adapter.ts
2627
+ var GROQ_METADATA_EXTRACTOR = makeMetadataExtractor([
2628
+ { header: "x-request-id", key: "request_id" },
2629
+ { header: "x-groq-region", key: "region" },
2630
+ { header: "x-ratelimit-remaining-requests", key: "requests_remaining", numeric: true },
2631
+ { header: "x-ratelimit-remaining-tokens", key: "tokens_remaining", numeric: true }
2632
+ ]);
2522
2633
  var GroqAdapter = class extends OpenAIAdapter {
2523
2634
  vendor = groqManifest.vendor;
2524
2635
  init(auth, client) {
@@ -2530,6 +2641,12 @@ var GroqAdapter = class extends OpenAIAdapter {
2530
2641
  client
2531
2642
  );
2532
2643
  }
2644
+ stream(req) {
2645
+ return streamFromOpenAI(this.ensureClient(), req, {
2646
+ knownModels: groqManifest.knownModels,
2647
+ vendorMetadataExtractor: GROQ_METADATA_EXTRACTOR
2648
+ });
2649
+ }
2533
2650
  };
2534
2651
 
2535
2652
  // src/adapters/groq/factory.ts
@@ -2630,6 +2747,10 @@ var huggingfaceManifest = {
2630
2747
  };
2631
2748
 
2632
2749
  // src/adapters/huggingface/adapter.ts
2750
+ var HUGGINGFACE_METADATA_EXTRACTOR = makeMetadataExtractor([
2751
+ { header: "x-inference-provider", key: "provider" },
2752
+ { header: "x-request-id", key: "request_id" }
2753
+ ]);
2633
2754
  var HuggingfaceAdapter = class extends OpenAIAdapter {
2634
2755
  vendor = huggingfaceManifest.vendor;
2635
2756
  init(auth, client) {
@@ -2641,6 +2762,12 @@ var HuggingfaceAdapter = class extends OpenAIAdapter {
2641
2762
  client
2642
2763
  );
2643
2764
  }
2765
+ stream(req) {
2766
+ return streamFromOpenAI(this.ensureClient(), req, {
2767
+ knownModels: huggingfaceManifest.knownModels,
2768
+ vendorMetadataExtractor: HUGGINGFACE_METADATA_EXTRACTOR
2769
+ });
2770
+ }
2644
2771
  };
2645
2772
 
2646
2773
  // src/adapters/huggingface/factory.ts