@jambonz/llm 0.6.5 → 0.6.7
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 +186 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +186 -3
- package/dist/index.js.map +1 -1
- package/dist/test-kit/index.cjs +185 -3
- package/dist/test-kit/index.cjs.map +1 -1
- package/dist/test-kit/index.js +185 -3
- package/dist/test-kit/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -187,12 +187,20 @@ async function* streamFromOpenAI(client, req, options) {
|
|
|
187
187
|
throw new Error(`OpenAI-compatible stream returned an error: ${message}`);
|
|
188
188
|
}
|
|
189
189
|
if (chunk.usage) {
|
|
190
|
-
const
|
|
190
|
+
const details = chunk.usage.prompt_tokens_details;
|
|
191
|
+
const cachedTokens = details?.cached_tokens;
|
|
192
|
+
const cacheWriteTokens = details?.cache_write_tokens;
|
|
191
193
|
usage = {
|
|
192
|
-
...chunk.usage.prompt_tokens !== void 0 ? {
|
|
194
|
+
...chunk.usage.prompt_tokens !== void 0 ? {
|
|
195
|
+
inputTokens: Math.max(
|
|
196
|
+
0,
|
|
197
|
+
chunk.usage.prompt_tokens - (cachedTokens ?? 0) - (cacheWriteTokens ?? 0)
|
|
198
|
+
)
|
|
199
|
+
} : {},
|
|
193
200
|
...chunk.usage.completion_tokens !== void 0 ? { outputTokens: chunk.usage.completion_tokens } : {},
|
|
194
201
|
...chunk.usage.total_tokens !== void 0 ? { totalTokens: chunk.usage.total_tokens } : {},
|
|
195
|
-
...cachedTokens !== void 0 ? { cacheReadTokens: cachedTokens } : {}
|
|
202
|
+
...cachedTokens !== void 0 ? { cacheReadTokens: cachedTokens } : {},
|
|
203
|
+
...cacheWriteTokens !== void 0 ? { cacheWriteTokens } : {}
|
|
196
204
|
};
|
|
197
205
|
}
|
|
198
206
|
const choice = chunk.choices?.[0];
|
|
@@ -3583,6 +3591,179 @@ var huggingfaceFactory = {
|
|
|
3583
3591
|
create: () => new HuggingfaceAdapter()
|
|
3584
3592
|
};
|
|
3585
3593
|
|
|
3594
|
+
// src/adapters/openrouter/manifest.ts
|
|
3595
|
+
var OPENROUTER_KNOWN_MODELS = [
|
|
3596
|
+
{
|
|
3597
|
+
id: "anthropic/claude-haiku-5.5",
|
|
3598
|
+
displayName: "Claude Haiku 5.5 (OpenRouter)",
|
|
3599
|
+
capabilities: {
|
|
3600
|
+
streaming: true,
|
|
3601
|
+
tools: true,
|
|
3602
|
+
vision: true,
|
|
3603
|
+
systemPrompt: true,
|
|
3604
|
+
maxContextTokens: 1e6
|
|
3605
|
+
}
|
|
3606
|
+
},
|
|
3607
|
+
{
|
|
3608
|
+
id: "anthropic/claude-sonnet-5.5",
|
|
3609
|
+
displayName: "Claude Sonnet 5.5 (OpenRouter)",
|
|
3610
|
+
capabilities: {
|
|
3611
|
+
streaming: true,
|
|
3612
|
+
tools: true,
|
|
3613
|
+
vision: true,
|
|
3614
|
+
systemPrompt: true,
|
|
3615
|
+
maxContextTokens: 1e6
|
|
3616
|
+
}
|
|
3617
|
+
},
|
|
3618
|
+
{
|
|
3619
|
+
id: "openai/gpt-5.4-mini",
|
|
3620
|
+
displayName: "GPT-5.4 Mini (OpenRouter)",
|
|
3621
|
+
capabilities: {
|
|
3622
|
+
streaming: true,
|
|
3623
|
+
tools: true,
|
|
3624
|
+
vision: true,
|
|
3625
|
+
systemPrompt: true,
|
|
3626
|
+
maxContextTokens: 4e5
|
|
3627
|
+
}
|
|
3628
|
+
},
|
|
3629
|
+
{
|
|
3630
|
+
id: "openai/gpt-4.1-mini",
|
|
3631
|
+
displayName: "GPT-4.1 Mini (OpenRouter)",
|
|
3632
|
+
capabilities: {
|
|
3633
|
+
streaming: true,
|
|
3634
|
+
tools: true,
|
|
3635
|
+
vision: true,
|
|
3636
|
+
systemPrompt: true,
|
|
3637
|
+
maxContextTokens: 1047576
|
|
3638
|
+
}
|
|
3639
|
+
},
|
|
3640
|
+
{
|
|
3641
|
+
id: "google/gemini-3.5-flash",
|
|
3642
|
+
displayName: "Gemini 3.5 Flash (OpenRouter)",
|
|
3643
|
+
capabilities: {
|
|
3644
|
+
streaming: true,
|
|
3645
|
+
tools: true,
|
|
3646
|
+
vision: true,
|
|
3647
|
+
systemPrompt: true,
|
|
3648
|
+
maxContextTokens: 1048576
|
|
3649
|
+
}
|
|
3650
|
+
},
|
|
3651
|
+
{
|
|
3652
|
+
id: "meta-llama/llama-3.3-70b-instruct",
|
|
3653
|
+
displayName: "Llama 3.3 70B Instruct (OpenRouter)",
|
|
3654
|
+
capabilities: {
|
|
3655
|
+
streaming: true,
|
|
3656
|
+
tools: true,
|
|
3657
|
+
vision: false,
|
|
3658
|
+
systemPrompt: true,
|
|
3659
|
+
maxContextTokens: 131072
|
|
3660
|
+
}
|
|
3661
|
+
}
|
|
3662
|
+
];
|
|
3663
|
+
var openRouterManifest = {
|
|
3664
|
+
vendor: "openrouter",
|
|
3665
|
+
displayName: "OpenRouter",
|
|
3666
|
+
authKinds: [
|
|
3667
|
+
{
|
|
3668
|
+
kind: "apiKey",
|
|
3669
|
+
displayName: "API Key",
|
|
3670
|
+
fields: [
|
|
3671
|
+
{
|
|
3672
|
+
name: "apiKey",
|
|
3673
|
+
label: "API Key",
|
|
3674
|
+
type: "password",
|
|
3675
|
+
required: true,
|
|
3676
|
+
help: "Get an API key from https://openrouter.ai/settings/keys"
|
|
3677
|
+
},
|
|
3678
|
+
{
|
|
3679
|
+
name: "baseURL",
|
|
3680
|
+
label: "Base URL",
|
|
3681
|
+
type: "url",
|
|
3682
|
+
required: false,
|
|
3683
|
+
default: "https://openrouter.ai/api/v1",
|
|
3684
|
+
help: "Override only for proxies. Default points at OpenRouter's production endpoint."
|
|
3685
|
+
}
|
|
3686
|
+
]
|
|
3687
|
+
}
|
|
3688
|
+
],
|
|
3689
|
+
knownModels: OPENROUTER_KNOWN_MODELS,
|
|
3690
|
+
// /models is public; the adapter enriches it with OpenRouter's own capability metadata.
|
|
3691
|
+
supportsModelListing: true,
|
|
3692
|
+
docsUrl: "https://openrouter.ai/docs/api_reference/overview"
|
|
3693
|
+
};
|
|
3694
|
+
|
|
3695
|
+
// src/adapters/openrouter/adapter.ts
|
|
3696
|
+
var OPENROUTER_METADATA_EXTRACTOR = makeMetadataExtractor([
|
|
3697
|
+
{ header: "x-generation-id", key: "request_id" }
|
|
3698
|
+
]);
|
|
3699
|
+
var OPENROUTER_ATTRIBUTION_HEADERS = {
|
|
3700
|
+
"HTTP-Referer": "https://jambonz.org",
|
|
3701
|
+
"X-OpenRouter-Title": "jambonz"
|
|
3702
|
+
};
|
|
3703
|
+
var OpenRouterAdapter = class extends OpenAIAdapter {
|
|
3704
|
+
vendor = openRouterManifest.vendor;
|
|
3705
|
+
init(auth, client) {
|
|
3706
|
+
super.init(
|
|
3707
|
+
{
|
|
3708
|
+
...auth,
|
|
3709
|
+
baseURL: auth.baseURL ?? "https://openrouter.ai/api/v1"
|
|
3710
|
+
},
|
|
3711
|
+
client
|
|
3712
|
+
);
|
|
3713
|
+
this.client = this.ensureClient().withOptions({
|
|
3714
|
+
defaultHeaders: OPENROUTER_ATTRIBUTION_HEADERS
|
|
3715
|
+
});
|
|
3716
|
+
}
|
|
3717
|
+
stream(req) {
|
|
3718
|
+
return streamFromOpenAI(this.ensureClient(), req, {
|
|
3719
|
+
knownModels: this.knownModels(),
|
|
3720
|
+
vendorMetadataExtractor: OPENROUTER_METADATA_EXTRACTOR,
|
|
3721
|
+
// Verified accepted by OpenRouter (forwarded to OpenAI-family upstreams).
|
|
3722
|
+
includeCacheKey: true,
|
|
3723
|
+
openRouterAutoCache: this.isOpenRouter
|
|
3724
|
+
});
|
|
3725
|
+
}
|
|
3726
|
+
async listAvailableModels() {
|
|
3727
|
+
const result = await this.ensureClient().models.list();
|
|
3728
|
+
const out = [];
|
|
3729
|
+
for (const m of result.data) {
|
|
3730
|
+
if (m.id.endsWith(":batch")) continue;
|
|
3731
|
+
const outputs = m.architecture?.output_modalities;
|
|
3732
|
+
if (outputs && !outputs.includes("text")) continue;
|
|
3733
|
+
const known = this.knownModels().find((k) => k.id === m.id);
|
|
3734
|
+
if (known) {
|
|
3735
|
+
out.push(known);
|
|
3736
|
+
continue;
|
|
3737
|
+
}
|
|
3738
|
+
out.push({
|
|
3739
|
+
id: m.id,
|
|
3740
|
+
...m.name ? { displayName: m.name } : {},
|
|
3741
|
+
capabilities: {
|
|
3742
|
+
streaming: true,
|
|
3743
|
+
tools: m.supported_parameters?.includes("tools") ?? true,
|
|
3744
|
+
vision: m.architecture?.input_modalities?.includes("image") ?? false,
|
|
3745
|
+
systemPrompt: true,
|
|
3746
|
+
...m.context_length ? { maxContextTokens: m.context_length } : {}
|
|
3747
|
+
}
|
|
3748
|
+
});
|
|
3749
|
+
}
|
|
3750
|
+
return out;
|
|
3751
|
+
}
|
|
3752
|
+
async testCredential() {
|
|
3753
|
+
await this.ensureClient().get("/key");
|
|
3754
|
+
}
|
|
3755
|
+
knownModels() {
|
|
3756
|
+
return openRouterManifest.knownModels;
|
|
3757
|
+
}
|
|
3758
|
+
};
|
|
3759
|
+
|
|
3760
|
+
// src/adapters/openrouter/factory.ts
|
|
3761
|
+
var openRouterFactory = {
|
|
3762
|
+
vendor: openRouterManifest.vendor,
|
|
3763
|
+
manifest: openRouterManifest,
|
|
3764
|
+
create: () => new OpenRouterAdapter()
|
|
3765
|
+
};
|
|
3766
|
+
|
|
3586
3767
|
// src/adapters/index.ts
|
|
3587
3768
|
registerAdapter(openAIFactory);
|
|
3588
3769
|
registerAdapter(deepseekFactory);
|
|
@@ -3599,6 +3780,7 @@ registerAdapter(bedrockFactory);
|
|
|
3599
3780
|
registerAdapter(azureOpenAIFactory);
|
|
3600
3781
|
registerAdapter(groqFactory);
|
|
3601
3782
|
registerAdapter(huggingfaceFactory);
|
|
3783
|
+
registerAdapter(openRouterFactory);
|
|
3602
3784
|
|
|
3603
3785
|
// src/normalize-auth.ts
|
|
3604
3786
|
function normalizeAuth(vendor, raw) {
|
|
@@ -3607,6 +3789,7 @@ function normalizeAuth(vendor, raw) {
|
|
|
3607
3789
|
case "anthropic":
|
|
3608
3790
|
case "groq":
|
|
3609
3791
|
case "huggingface":
|
|
3792
|
+
case "openrouter":
|
|
3610
3793
|
case "moonshot":
|
|
3611
3794
|
case "zai":
|
|
3612
3795
|
case "xai":
|