@jambonz/llm 0.4.5 → 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.cjs +245 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +245 -5
- package/dist/index.js.map +1 -1
- package/dist/test-kit/index.cjs +244 -5
- package/dist/test-kit/index.cjs.map +1 -1
- package/dist/test-kit/index.d.cts +1 -1
- package/dist/test-kit/index.d.ts +1 -1
- package/dist/test-kit/index.js +244 -5
- package/dist/test-kit/index.js.map +1 -1
- package/dist/{types-DbqWrdT6.d.cts → types-BWsmVtXv.d.cts} +13 -0
- package/dist/{types-DbqWrdT6.d.ts → types-BWsmVtXv.d.ts} +13 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -131,8 +131,17 @@ async function* streamFromOpenAI(client, req, options) {
|
|
|
131
131
|
body[param] = effectiveMaxTokens;
|
|
132
132
|
}
|
|
133
133
|
let stream;
|
|
134
|
+
let responseHeaders;
|
|
134
135
|
try {
|
|
135
|
-
|
|
136
|
+
const apiPromise = client.chat.completions.create(body, { signal: req.signal });
|
|
137
|
+
const maybeWithResponse = apiPromise.withResponse;
|
|
138
|
+
if (typeof maybeWithResponse === "function") {
|
|
139
|
+
const result = await maybeWithResponse.call(apiPromise);
|
|
140
|
+
stream = result.data;
|
|
141
|
+
responseHeaders = result.response?.headers;
|
|
142
|
+
} else {
|
|
143
|
+
stream = await apiPromise;
|
|
144
|
+
}
|
|
136
145
|
} catch (err) {
|
|
137
146
|
if (isAbortError(err)) {
|
|
138
147
|
yield { type: "end", finishReason: "aborted" };
|
|
@@ -227,6 +236,12 @@ async function* streamFromOpenAI(client, req, options) {
|
|
|
227
236
|
...usage ? { usage } : {},
|
|
228
237
|
...finalRawReason ? { rawReason: finalRawReason } : {}
|
|
229
238
|
};
|
|
239
|
+
if (options.vendorMetadataExtractor && responseHeaders) {
|
|
240
|
+
const metadata = options.vendorMetadataExtractor(responseHeaders);
|
|
241
|
+
if (metadata && Object.keys(metadata).length > 0) {
|
|
242
|
+
endEvent.vendorMetadata = metadata;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
230
245
|
yield endEvent;
|
|
231
246
|
}
|
|
232
247
|
function appendOpenAIAssistantToolCall(history, toolCalls) {
|
|
@@ -354,6 +369,40 @@ function isAbortError(err) {
|
|
|
354
369
|
return e.name === "APIUserAbortError" || e.name === "AbortError" || e.code === "ABORT_ERR" || typeof e.message === "string" && /aborted/i.test(e.message);
|
|
355
370
|
}
|
|
356
371
|
|
|
372
|
+
// src/adapters/_metadata.ts
|
|
373
|
+
function makeMetadataExtractor(fields) {
|
|
374
|
+
return (headers) => {
|
|
375
|
+
const out = {};
|
|
376
|
+
for (const f of fields) {
|
|
377
|
+
const raw = headers.get(f.header);
|
|
378
|
+
if (raw === null || raw === void 0 || raw === "") continue;
|
|
379
|
+
if (f.numeric) {
|
|
380
|
+
const n = Number(raw);
|
|
381
|
+
if (Number.isFinite(n)) out[f.key] = n;
|
|
382
|
+
} else {
|
|
383
|
+
out[f.key] = raw;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
return out;
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
function extractMetadata(fields, headers) {
|
|
390
|
+
const headersInstance = headers instanceof Headers ? headers : recordToHeaders(headers);
|
|
391
|
+
return makeMetadataExtractor(fields)(headersInstance);
|
|
392
|
+
}
|
|
393
|
+
function recordToHeaders(record) {
|
|
394
|
+
const h = new Headers();
|
|
395
|
+
for (const [name, value] of Object.entries(record)) {
|
|
396
|
+
if (value === void 0) continue;
|
|
397
|
+
if (Array.isArray(value)) {
|
|
398
|
+
for (const v of value) h.append(name, v);
|
|
399
|
+
} else {
|
|
400
|
+
h.set(name, value);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
return h;
|
|
404
|
+
}
|
|
405
|
+
|
|
357
406
|
// src/adapters/openai/manifest.ts
|
|
358
407
|
var OPENAI_KNOWN_MODELS = [
|
|
359
408
|
{
|
|
@@ -455,6 +504,12 @@ var openAIManifest = {
|
|
|
455
504
|
};
|
|
456
505
|
|
|
457
506
|
// src/adapters/openai/adapter.ts
|
|
507
|
+
var OPENAI_METADATA_EXTRACTOR = makeMetadataExtractor([
|
|
508
|
+
{ header: "x-request-id", key: "request_id" },
|
|
509
|
+
{ header: "openai-processing-ms", key: "processing_ms", numeric: true },
|
|
510
|
+
{ header: "x-ratelimit-remaining-requests", key: "requests_remaining", numeric: true },
|
|
511
|
+
{ header: "x-ratelimit-remaining-tokens", key: "tokens_remaining", numeric: true }
|
|
512
|
+
]);
|
|
458
513
|
var OpenAIAdapter = class {
|
|
459
514
|
vendor = openAIManifest.vendor;
|
|
460
515
|
acceptedAuth = ["apiKey"];
|
|
@@ -472,7 +527,8 @@ var OpenAIAdapter = class {
|
|
|
472
527
|
}
|
|
473
528
|
stream(req) {
|
|
474
529
|
return streamFromOpenAI(this.ensureClient(), req, {
|
|
475
|
-
knownModels: openAIManifest.knownModels
|
|
530
|
+
knownModels: openAIManifest.knownModels,
|
|
531
|
+
vendorMetadataExtractor: OPENAI_METADATA_EXTRACTOR
|
|
476
532
|
});
|
|
477
533
|
}
|
|
478
534
|
appendAssistantToolCall(history, toolCalls) {
|
|
@@ -704,6 +760,12 @@ var anthropicManifest = {
|
|
|
704
760
|
};
|
|
705
761
|
|
|
706
762
|
// src/adapters/anthropic/adapter.ts
|
|
763
|
+
var ANTHROPIC_METADATA_EXTRACTOR = makeMetadataExtractor([
|
|
764
|
+
{ header: "request-id", key: "request_id" },
|
|
765
|
+
{ header: "anthropic-ratelimit-requests-remaining", key: "requests_remaining", numeric: true },
|
|
766
|
+
{ header: "anthropic-ratelimit-input-tokens-remaining", key: "input_tokens_remaining", numeric: true },
|
|
767
|
+
{ header: "anthropic-ratelimit-output-tokens-remaining", key: "output_tokens_remaining", numeric: true }
|
|
768
|
+
]);
|
|
707
769
|
var AnthropicAdapter = class {
|
|
708
770
|
vendor = anthropicManifest.vendor;
|
|
709
771
|
acceptedAuth = ["apiKey"];
|
|
@@ -738,11 +800,20 @@ var AnthropicAdapter = class {
|
|
|
738
800
|
if (tools) body.tools = tools;
|
|
739
801
|
if (req.temperature !== void 0) body.temperature = req.temperature;
|
|
740
802
|
let stream;
|
|
803
|
+
let responseHeaders;
|
|
741
804
|
try {
|
|
742
|
-
|
|
805
|
+
const apiPromise = client.messages.create(
|
|
743
806
|
body,
|
|
744
807
|
{ signal: req.signal }
|
|
745
808
|
);
|
|
809
|
+
const maybeWithResponse = apiPromise.withResponse;
|
|
810
|
+
if (typeof maybeWithResponse === "function") {
|
|
811
|
+
const result = await maybeWithResponse.call(apiPromise);
|
|
812
|
+
stream = result.data;
|
|
813
|
+
responseHeaders = result.response?.headers;
|
|
814
|
+
} else {
|
|
815
|
+
stream = await apiPromise;
|
|
816
|
+
}
|
|
746
817
|
} catch (err) {
|
|
747
818
|
if (isAbortError2(err)) {
|
|
748
819
|
yield { type: "end", finishReason: "aborted" };
|
|
@@ -853,6 +924,12 @@ var AnthropicAdapter = class {
|
|
|
853
924
|
...usage ? { usage } : {},
|
|
854
925
|
...stopReason ? { rawReason: stopReason } : {}
|
|
855
926
|
};
|
|
927
|
+
if (responseHeaders) {
|
|
928
|
+
const metadata = ANTHROPIC_METADATA_EXTRACTOR(responseHeaders);
|
|
929
|
+
if (Object.keys(metadata).length > 0) {
|
|
930
|
+
endEvent.vendorMetadata = metadata;
|
|
931
|
+
}
|
|
932
|
+
}
|
|
856
933
|
yield endEvent;
|
|
857
934
|
}
|
|
858
935
|
appendAssistantToolCall(history, toolCalls) {
|
|
@@ -1645,6 +1722,9 @@ var vertexOpenAIManifest = {
|
|
|
1645
1722
|
};
|
|
1646
1723
|
|
|
1647
1724
|
// src/adapters/vertex-openai/adapter.ts
|
|
1725
|
+
var VERTEX_OPENAI_METADATA_EXTRACTOR = makeMetadataExtractor([
|
|
1726
|
+
{ header: "x-request-id", key: "request_id" }
|
|
1727
|
+
]);
|
|
1648
1728
|
var VertexOpenAIAdapter = class {
|
|
1649
1729
|
vendor = vertexOpenAIManifest.vendor;
|
|
1650
1730
|
acceptedAuth = ["vertexServiceAccount"];
|
|
@@ -1697,7 +1777,8 @@ var VertexOpenAIAdapter = class {
|
|
|
1697
1777
|
// endpoint predates `max_completion_tokens` and may not recognize it.
|
|
1698
1778
|
// The model-id heuristic wouldn't catch a partner model named in the
|
|
1699
1779
|
// OpenAI style (unlikely today, but defensive).
|
|
1700
|
-
tokensParam: "max_tokens"
|
|
1780
|
+
tokensParam: "max_tokens",
|
|
1781
|
+
vendorMetadataExtractor: VERTEX_OPENAI_METADATA_EXTRACTOR
|
|
1701
1782
|
});
|
|
1702
1783
|
}
|
|
1703
1784
|
appendAssistantToolCall(history, toolCalls) {
|
|
@@ -2155,6 +2236,21 @@ var BedrockAdapter = class {
|
|
|
2155
2236
|
...usage ? { usage } : {},
|
|
2156
2237
|
...stopReason ? { rawReason: stopReason } : {}
|
|
2157
2238
|
};
|
|
2239
|
+
const httpHeaders = response.$metadata?.httpHeaders;
|
|
2240
|
+
if (httpHeaders) {
|
|
2241
|
+
const metadata = extractMetadata(
|
|
2242
|
+
[
|
|
2243
|
+
{ header: "x-amzn-bedrock-invocation-latency", key: "invocation_latency_ms", numeric: true },
|
|
2244
|
+
{ header: "x-amzn-bedrock-cache-read-input-token-count", key: "cache_read_input_tokens", numeric: true },
|
|
2245
|
+
{ header: "x-amzn-bedrock-cache-write-input-token-count", key: "cache_write_input_tokens", numeric: true },
|
|
2246
|
+
{ header: "x-amzn-bedrock-trace-id", key: "trace_id" }
|
|
2247
|
+
],
|
|
2248
|
+
httpHeaders
|
|
2249
|
+
);
|
|
2250
|
+
if (Object.keys(metadata).length > 0) {
|
|
2251
|
+
endEvent.vendorMetadata = metadata;
|
|
2252
|
+
}
|
|
2253
|
+
}
|
|
2158
2254
|
yield endEvent;
|
|
2159
2255
|
}
|
|
2160
2256
|
appendAssistantToolCall(history, toolCalls) {
|
|
@@ -2406,6 +2502,14 @@ var azureOpenAIManifest = {
|
|
|
2406
2502
|
};
|
|
2407
2503
|
|
|
2408
2504
|
// src/adapters/azure-openai/adapter.ts
|
|
2505
|
+
var AZURE_OPENAI_METADATA_EXTRACTOR = makeMetadataExtractor([
|
|
2506
|
+
{ header: "x-ms-region", key: "region" },
|
|
2507
|
+
{ header: "x-ms-deployment-name", key: "deployment" },
|
|
2508
|
+
{ header: "apim-request-id", key: "request_id" },
|
|
2509
|
+
{ header: "azureml-model-session", key: "model_session" },
|
|
2510
|
+
{ header: "x-ratelimit-remaining-requests", key: "requests_remaining", numeric: true },
|
|
2511
|
+
{ header: "x-ratelimit-remaining-tokens", key: "tokens_remaining", numeric: true }
|
|
2512
|
+
]);
|
|
2409
2513
|
var AzureOpenAIAdapter = class {
|
|
2410
2514
|
vendor = azureOpenAIManifest.vendor;
|
|
2411
2515
|
acceptedAuth = ["azureOpenAIApiKey"];
|
|
@@ -2440,7 +2544,8 @@ var AzureOpenAIAdapter = class {
|
|
|
2440
2544
|
stream(req) {
|
|
2441
2545
|
return streamFromOpenAI(this.ensureClient(), req, {
|
|
2442
2546
|
knownModels: azureOpenAIManifest.knownModels,
|
|
2443
|
-
tokensParam: "max_completion_tokens"
|
|
2547
|
+
tokensParam: "max_completion_tokens",
|
|
2548
|
+
vendorMetadataExtractor: AZURE_OPENAI_METADATA_EXTRACTOR
|
|
2444
2549
|
});
|
|
2445
2550
|
}
|
|
2446
2551
|
appendAssistantToolCall(history, toolCalls) {
|
|
@@ -2565,6 +2670,12 @@ var groqManifest = {
|
|
|
2565
2670
|
};
|
|
2566
2671
|
|
|
2567
2672
|
// src/adapters/groq/adapter.ts
|
|
2673
|
+
var GROQ_METADATA_EXTRACTOR = makeMetadataExtractor([
|
|
2674
|
+
{ header: "x-request-id", key: "request_id" },
|
|
2675
|
+
{ header: "x-groq-region", key: "region" },
|
|
2676
|
+
{ header: "x-ratelimit-remaining-requests", key: "requests_remaining", numeric: true },
|
|
2677
|
+
{ header: "x-ratelimit-remaining-tokens", key: "tokens_remaining", numeric: true }
|
|
2678
|
+
]);
|
|
2568
2679
|
var GroqAdapter = class extends OpenAIAdapter {
|
|
2569
2680
|
vendor = groqManifest.vendor;
|
|
2570
2681
|
init(auth, client) {
|
|
@@ -2576,6 +2687,12 @@ var GroqAdapter = class extends OpenAIAdapter {
|
|
|
2576
2687
|
client
|
|
2577
2688
|
);
|
|
2578
2689
|
}
|
|
2690
|
+
stream(req) {
|
|
2691
|
+
return streamFromOpenAI(this.ensureClient(), req, {
|
|
2692
|
+
knownModels: groqManifest.knownModels,
|
|
2693
|
+
vendorMetadataExtractor: GROQ_METADATA_EXTRACTOR
|
|
2694
|
+
});
|
|
2695
|
+
}
|
|
2579
2696
|
};
|
|
2580
2697
|
|
|
2581
2698
|
// src/adapters/groq/factory.ts
|
|
@@ -2585,6 +2702,127 @@ var groqFactory = {
|
|
|
2585
2702
|
create: () => new GroqAdapter()
|
|
2586
2703
|
};
|
|
2587
2704
|
|
|
2705
|
+
// src/adapters/huggingface/manifest.ts
|
|
2706
|
+
var HF_KNOWN_MODELS = [
|
|
2707
|
+
{
|
|
2708
|
+
id: "meta-llama/Llama-3.3-70B-Instruct",
|
|
2709
|
+
displayName: "Llama 3.3 70B Instruct (HF Providers)",
|
|
2710
|
+
capabilities: {
|
|
2711
|
+
streaming: true,
|
|
2712
|
+
tools: true,
|
|
2713
|
+
vision: false,
|
|
2714
|
+
systemPrompt: true,
|
|
2715
|
+
maxContextTokens: 128e3
|
|
2716
|
+
}
|
|
2717
|
+
},
|
|
2718
|
+
{
|
|
2719
|
+
id: "meta-llama/Llama-3.1-8B-Instruct",
|
|
2720
|
+
displayName: "Llama 3.1 8B Instruct (HF Providers)",
|
|
2721
|
+
capabilities: {
|
|
2722
|
+
streaming: true,
|
|
2723
|
+
tools: true,
|
|
2724
|
+
vision: false,
|
|
2725
|
+
systemPrompt: true,
|
|
2726
|
+
maxContextTokens: 128e3
|
|
2727
|
+
}
|
|
2728
|
+
},
|
|
2729
|
+
{
|
|
2730
|
+
id: "Qwen/Qwen2.5-72B-Instruct",
|
|
2731
|
+
displayName: "Qwen 2.5 72B Instruct (HF Providers)",
|
|
2732
|
+
capabilities: {
|
|
2733
|
+
streaming: true,
|
|
2734
|
+
tools: true,
|
|
2735
|
+
vision: false,
|
|
2736
|
+
systemPrompt: true,
|
|
2737
|
+
maxContextTokens: 128e3
|
|
2738
|
+
}
|
|
2739
|
+
},
|
|
2740
|
+
{
|
|
2741
|
+
id: "mistralai/Mistral-7B-Instruct-v0.3",
|
|
2742
|
+
displayName: "Mistral 7B Instruct v0.3 (HF Providers)",
|
|
2743
|
+
capabilities: {
|
|
2744
|
+
streaming: true,
|
|
2745
|
+
tools: true,
|
|
2746
|
+
vision: false,
|
|
2747
|
+
systemPrompt: true,
|
|
2748
|
+
maxContextTokens: 32e3
|
|
2749
|
+
}
|
|
2750
|
+
},
|
|
2751
|
+
{
|
|
2752
|
+
id: "deepseek-ai/DeepSeek-V3",
|
|
2753
|
+
displayName: "DeepSeek V3 (HF Providers)",
|
|
2754
|
+
capabilities: {
|
|
2755
|
+
streaming: true,
|
|
2756
|
+
tools: true,
|
|
2757
|
+
vision: false,
|
|
2758
|
+
systemPrompt: true,
|
|
2759
|
+
maxContextTokens: 64e3
|
|
2760
|
+
}
|
|
2761
|
+
}
|
|
2762
|
+
];
|
|
2763
|
+
var huggingfaceManifest = {
|
|
2764
|
+
vendor: "huggingface",
|
|
2765
|
+
displayName: "HuggingFace Inference Providers",
|
|
2766
|
+
authKinds: [
|
|
2767
|
+
{
|
|
2768
|
+
kind: "apiKey",
|
|
2769
|
+
displayName: "API Key",
|
|
2770
|
+
fields: [
|
|
2771
|
+
{
|
|
2772
|
+
name: "apiKey",
|
|
2773
|
+
label: "HuggingFace Token",
|
|
2774
|
+
type: "password",
|
|
2775
|
+
required: true,
|
|
2776
|
+
help: "Get a token from https://huggingface.co/settings/tokens (Read scope is sufficient). Inference Providers requires a credit balance \u2014 claim the free monthly tier or attach a payment method at https://huggingface.co/billing."
|
|
2777
|
+
},
|
|
2778
|
+
{
|
|
2779
|
+
name: "baseURL",
|
|
2780
|
+
label: "Base URL",
|
|
2781
|
+
type: "url",
|
|
2782
|
+
required: false,
|
|
2783
|
+
default: "https://router.huggingface.co/v1",
|
|
2784
|
+
help: "Override only for proxies. Default is the HF Providers router endpoint."
|
|
2785
|
+
}
|
|
2786
|
+
]
|
|
2787
|
+
}
|
|
2788
|
+
],
|
|
2789
|
+
knownModels: HF_KNOWN_MODELS,
|
|
2790
|
+
// The HF router exposes /v1/models with the same Bearer auth.
|
|
2791
|
+
supportsModelListing: true,
|
|
2792
|
+
docsUrl: "https://huggingface.co/docs/inference-providers"
|
|
2793
|
+
};
|
|
2794
|
+
|
|
2795
|
+
// src/adapters/huggingface/adapter.ts
|
|
2796
|
+
var HUGGINGFACE_METADATA_EXTRACTOR = makeMetadataExtractor([
|
|
2797
|
+
{ header: "x-inference-provider", key: "provider" },
|
|
2798
|
+
{ header: "x-request-id", key: "request_id" }
|
|
2799
|
+
]);
|
|
2800
|
+
var HuggingfaceAdapter = class extends OpenAIAdapter {
|
|
2801
|
+
vendor = huggingfaceManifest.vendor;
|
|
2802
|
+
init(auth, client) {
|
|
2803
|
+
super.init(
|
|
2804
|
+
{
|
|
2805
|
+
...auth,
|
|
2806
|
+
baseURL: auth.baseURL ?? "https://router.huggingface.co/v1"
|
|
2807
|
+
},
|
|
2808
|
+
client
|
|
2809
|
+
);
|
|
2810
|
+
}
|
|
2811
|
+
stream(req) {
|
|
2812
|
+
return streamFromOpenAI(this.ensureClient(), req, {
|
|
2813
|
+
knownModels: huggingfaceManifest.knownModels,
|
|
2814
|
+
vendorMetadataExtractor: HUGGINGFACE_METADATA_EXTRACTOR
|
|
2815
|
+
});
|
|
2816
|
+
}
|
|
2817
|
+
};
|
|
2818
|
+
|
|
2819
|
+
// src/adapters/huggingface/factory.ts
|
|
2820
|
+
var huggingfaceFactory = {
|
|
2821
|
+
vendor: huggingfaceManifest.vendor,
|
|
2822
|
+
manifest: huggingfaceManifest,
|
|
2823
|
+
create: () => new HuggingfaceAdapter()
|
|
2824
|
+
};
|
|
2825
|
+
|
|
2588
2826
|
// src/adapters/index.ts
|
|
2589
2827
|
registerAdapter(openAIFactory);
|
|
2590
2828
|
registerAdapter(deepseekFactory);
|
|
@@ -2595,6 +2833,7 @@ registerAdapter(vertexOpenAIFactory);
|
|
|
2595
2833
|
registerAdapter(bedrockFactory);
|
|
2596
2834
|
registerAdapter(azureOpenAIFactory);
|
|
2597
2835
|
registerAdapter(groqFactory);
|
|
2836
|
+
registerAdapter(huggingfaceFactory);
|
|
2598
2837
|
|
|
2599
2838
|
// src/normalize-auth.ts
|
|
2600
2839
|
function normalizeAuth(vendor, raw) {
|
|
@@ -2602,6 +2841,7 @@ function normalizeAuth(vendor, raw) {
|
|
|
2602
2841
|
case "openai":
|
|
2603
2842
|
case "anthropic":
|
|
2604
2843
|
case "groq":
|
|
2844
|
+
case "huggingface":
|
|
2605
2845
|
return requireApiKey(vendor, raw);
|
|
2606
2846
|
case "deepseek":
|
|
2607
2847
|
return {
|