@absolutejs/ai 0.0.51 → 0.0.52
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/README.md +66 -7
- package/dist/ai/index.js +229 -13
- package/dist/ai/index.js.map +4 -4
- package/dist/ai/providers/openrouter.js +230 -14
- package/dist/ai/providers/openrouter.js.map +4 -4
- package/dist/src/ai/index.d.ts +2 -2
- package/dist/src/ai/providers/openrouter.d.ts +12 -3
- package/dist/src/ai/providers/openrouterClient.d.ts +367 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -111,8 +111,29 @@ const provider = openrouter({
|
|
|
111
111
|
The adapter intentionally has no built-in geopolitical model list. Omitting
|
|
112
112
|
`allowedModels` exposes the full OpenRouter catalog; applications that need a
|
|
113
113
|
restricted catalog can define their own `allowedModels` and `allowedProviders`
|
|
114
|
-
policy.
|
|
115
|
-
|
|
114
|
+
policy. Auto Router is fully supported with `openrouter/auto` (or
|
|
115
|
+
`openrouter/auto-beta`), a sticky `sessionId`, and its typed plugin controls:
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
const provider = openrouter({
|
|
119
|
+
apiKey: process.env.OPENROUTER_API_KEY,
|
|
120
|
+
// Omit this for unrestricted access to every OpenRouter model.
|
|
121
|
+
allowedModels: ["openrouter/auto", "anthropic/*", "openai/*"],
|
|
122
|
+
requestOptions: {
|
|
123
|
+
sessionId: conversationId,
|
|
124
|
+
plugins: [
|
|
125
|
+
{
|
|
126
|
+
id: "auto-router",
|
|
127
|
+
cost_tier: "low",
|
|
128
|
+
allowed_models: ["anthropic/*", "openai/*"],
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Under a strict policy, Auto Router's `allowed_models` is checked locally along
|
|
136
|
+
with fallback, Fusion, advisor, subagent, and other indirectly selected models.
|
|
116
137
|
|
|
117
138
|
Provider usage callbacks include OpenRouter's reported `costCredits`,
|
|
118
139
|
`upstreamInferenceCostCredits`, cache-read/write token counts, and reasoning
|
|
@@ -161,8 +182,9 @@ metadata when reported.
|
|
|
161
182
|
|
|
162
183
|
`createOpenRouterClient()` covers model/provider discovery, embeddings,
|
|
163
184
|
reranking, streamed and non-streamed image generation, reusable files,
|
|
164
|
-
Responses, speech, transcription, video jobs and downloads, batches,
|
|
165
|
-
|
|
185
|
+
Responses, speech, typed transcription, video jobs and downloads, beta batches,
|
|
186
|
+
presets, workspaces and budgets, activity/analytics, task classifications,
|
|
187
|
+
credits, key metadata, and generation content. It also exports
|
|
166
188
|
`verifyOpenRouterWebhookSignature()` for video completion webhooks. Its typed
|
|
167
189
|
operations enforce the same model allowlist. `request()` and `requestRaw()` are
|
|
168
190
|
forward-compatible access to new or administrative OpenRouter endpoints.
|
|
@@ -190,6 +212,41 @@ const reranked = await openrouterClient.rerank({
|
|
|
190
212
|
query: "cost controls",
|
|
191
213
|
documents: ["response caching", "CSS layout"],
|
|
192
214
|
});
|
|
215
|
+
|
|
216
|
+
const batch = await openrouterClient.createBatch({
|
|
217
|
+
endpoint: "/v1/chat/completions",
|
|
218
|
+
model: "anthropic/claude-sonnet-4.6",
|
|
219
|
+
requests: [
|
|
220
|
+
{ custom_id: "one", body: { messages: [{ role: "user", content: "Hi" }] } },
|
|
221
|
+
],
|
|
222
|
+
});
|
|
223
|
+
const completed = await openrouterClient.waitForBatch(batch.id, {
|
|
224
|
+
signal: abortController.signal,
|
|
225
|
+
timeoutMs: 60_000,
|
|
226
|
+
});
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Batch traffic uses OpenRouter's separate `/api/beta/batches` API and returns
|
|
230
|
+
inline typed results. `estimateOpenRouterModelCost()` calculates prompt,
|
|
231
|
+
completion, request, image, web-search, reasoning, and cache costs directly from
|
|
232
|
+
model-discovery pricing fields.
|
|
233
|
+
|
|
234
|
+
OAuth helpers cover S256 PKCE, web and headless authorization URLs, code
|
|
235
|
+
exchange, authenticated code creation, and user key deep-links:
|
|
236
|
+
|
|
237
|
+
```ts
|
|
238
|
+
const pkce = await generateOpenRouterPKCE();
|
|
239
|
+
const authorizationUrl = createOpenRouterAuthorizationUrl({
|
|
240
|
+
callbackUrl: "https://example.com/openrouter/callback",
|
|
241
|
+
codeChallenge: pkce.codeChallenge,
|
|
242
|
+
codeChallengeMethod: pkce.codeChallengeMethod,
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
const { key } = await exchangeOpenRouterAuthCode({
|
|
246
|
+
code,
|
|
247
|
+
code_verifier: pkce.codeVerifier,
|
|
248
|
+
code_challenge_method: pkce.codeChallengeMethod,
|
|
249
|
+
});
|
|
193
250
|
```
|
|
194
251
|
|
|
195
252
|
For a strict model-origin policy, also assign an OpenRouter key/workspace
|
|
@@ -197,9 +254,11 @@ guardrail with the same model allowlist. Provider allowlists restrict where a
|
|
|
197
254
|
model runs; they do not identify who developed it. Presets and router aliases
|
|
198
255
|
must be explicitly allowed, because their resolved model is controlled outside
|
|
199
256
|
the request. The raw client is intentionally unopinionated and should be limited
|
|
200
|
-
to trusted server-side administration code. OpenRouter
|
|
201
|
-
|
|
202
|
-
|
|
257
|
+
to trusted server-side administration code. OpenRouter currently documents
|
|
258
|
+
reporting generation feedback through Chatroom and Logs, not through a public
|
|
259
|
+
feedback API, so AbsoluteJS exposes generation IDs/content without inventing an
|
|
260
|
+
unstable endpoint. OpenRouter's official SDK can be used alongside this package
|
|
261
|
+
for specialized organization, SSO, SCIM, and BYOK administration.
|
|
203
262
|
|
|
204
263
|
Use `openrouterResponses(config)` when an AbsoluteJS agent should stream through
|
|
205
264
|
OpenRouter's stateless Responses API, or `openrouterMessages(config)` for the
|
package/dist/ai/index.js
CHANGED
|
@@ -2584,7 +2584,46 @@ var ollama = (config2 = {}) => {
|
|
|
2584
2584
|
};
|
|
2585
2585
|
|
|
2586
2586
|
// src/ai/providers/openrouterClient.ts
|
|
2587
|
+
var OPENROUTER_PRICING_KEYS = [
|
|
2588
|
+
"prompt",
|
|
2589
|
+
"completion",
|
|
2590
|
+
"request",
|
|
2591
|
+
"image",
|
|
2592
|
+
"web_search",
|
|
2593
|
+
"internal_reasoning",
|
|
2594
|
+
"input_cache_read",
|
|
2595
|
+
"input_cache_write"
|
|
2596
|
+
];
|
|
2597
|
+
var estimateOpenRouterCost = (pricing, units) => {
|
|
2598
|
+
const components = {};
|
|
2599
|
+
let total = 0;
|
|
2600
|
+
for (const key of OPENROUTER_PRICING_KEYS) {
|
|
2601
|
+
const quantity = units[key];
|
|
2602
|
+
if (quantity === undefined)
|
|
2603
|
+
continue;
|
|
2604
|
+
if (!Number.isFinite(quantity) || quantity < 0)
|
|
2605
|
+
throw new Error(`OpenRouter ${key} units must be non-negative`);
|
|
2606
|
+
const rawPrice = pricing[key];
|
|
2607
|
+
if (rawPrice === undefined)
|
|
2608
|
+
continue;
|
|
2609
|
+
const price = Number(rawPrice);
|
|
2610
|
+
if (!Number.isFinite(price) || price < 0)
|
|
2611
|
+
throw new Error(`OpenRouter ${key} price must be non-negative`);
|
|
2612
|
+
components[key] = price * quantity;
|
|
2613
|
+
total += components[key];
|
|
2614
|
+
}
|
|
2615
|
+
return { components, total };
|
|
2616
|
+
};
|
|
2617
|
+
var estimateOpenRouterModelCost = (model, units) => estimateOpenRouterCost(model.pricing ?? {}, units);
|
|
2587
2618
|
var DEFAULT_BASE_URL6 = "https://openrouter.ai/api/v1";
|
|
2619
|
+
var DEFAULT_BATCH_BASE_URL = "https://openrouter.ai/api/beta";
|
|
2620
|
+
var DEFAULT_SITE_URL = "https://openrouter.ai";
|
|
2621
|
+
var TERMINAL_BATCH_STATUSES = new Set([
|
|
2622
|
+
"completed",
|
|
2623
|
+
"failed",
|
|
2624
|
+
"expired",
|
|
2625
|
+
"cancelled"
|
|
2626
|
+
]);
|
|
2588
2627
|
var withoutLatestPrefix = (model) => model.startsWith("~") ? model.slice(1) : model;
|
|
2589
2628
|
var openRouterModelMatchesRule = (model, rule) => {
|
|
2590
2629
|
const normalizedModel = withoutLatestPrefix(model);
|
|
@@ -2598,6 +2637,22 @@ var assertAllowedModel = (model, allowedModels) => {
|
|
|
2598
2637
|
return;
|
|
2599
2638
|
throw new Error(`OpenRouter model "${model}" is not allowed`);
|
|
2600
2639
|
};
|
|
2640
|
+
var assertAllowedModelsInValue = (value, allowedModels, key = "") => {
|
|
2641
|
+
if (key === "model" && typeof value === "string")
|
|
2642
|
+
assertAllowedModel(value, allowedModels);
|
|
2643
|
+
if ((key === "models" || key === "analysis_models" || key === "allowed_models") && Array.isArray(value)) {
|
|
2644
|
+
for (const model of value)
|
|
2645
|
+
if (typeof model === "string")
|
|
2646
|
+
assertAllowedModel(model, allowedModels);
|
|
2647
|
+
}
|
|
2648
|
+
if (Array.isArray(value)) {
|
|
2649
|
+
for (const item of value)
|
|
2650
|
+
assertAllowedModelsInValue(item, allowedModels);
|
|
2651
|
+
} else if (value && typeof value === "object") {
|
|
2652
|
+
for (const [childKey, child] of Object.entries(value))
|
|
2653
|
+
assertAllowedModelsInValue(child, allowedModels, childKey);
|
|
2654
|
+
}
|
|
2655
|
+
};
|
|
2601
2656
|
var normalizePath = (path) => path.startsWith("/") ? path : `/${path}`;
|
|
2602
2657
|
var encodeModelPath = (model) => model.split("/").map(encodeURIComponent).join("/");
|
|
2603
2658
|
var withQuery = (url, query) => {
|
|
@@ -2648,6 +2703,54 @@ var parseImageSSE = async function* (response) {
|
|
|
2648
2703
|
}
|
|
2649
2704
|
};
|
|
2650
2705
|
var toBytes = (value) => typeof value === "string" ? new TextEncoder().encode(value) : value;
|
|
2706
|
+
var toBase64Url = (bytes) => {
|
|
2707
|
+
let binary = "";
|
|
2708
|
+
for (const byte of bytes)
|
|
2709
|
+
binary += String.fromCharCode(byte);
|
|
2710
|
+
return btoa(binary).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/u, "");
|
|
2711
|
+
};
|
|
2712
|
+
var generateOpenRouterPKCE = async () => {
|
|
2713
|
+
const random = crypto.getRandomValues(new Uint8Array(32));
|
|
2714
|
+
const codeVerifier = toBase64Url(random);
|
|
2715
|
+
const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(codeVerifier));
|
|
2716
|
+
return {
|
|
2717
|
+
codeChallenge: toBase64Url(new Uint8Array(digest)),
|
|
2718
|
+
codeChallengeMethod: "S256",
|
|
2719
|
+
codeVerifier
|
|
2720
|
+
};
|
|
2721
|
+
};
|
|
2722
|
+
var createOpenRouterAuthorizationUrl = (options = {}) => {
|
|
2723
|
+
const url = new URL("/auth", options.baseUrl ?? DEFAULT_SITE_URL);
|
|
2724
|
+
if (options.callbackUrl)
|
|
2725
|
+
url.searchParams.set("callback_url", options.callbackUrl);
|
|
2726
|
+
if (options.codeChallenge)
|
|
2727
|
+
url.searchParams.set("code_challenge", options.codeChallenge);
|
|
2728
|
+
if (options.codeChallengeMethod)
|
|
2729
|
+
url.searchParams.set("code_challenge_method", options.codeChallengeMethod);
|
|
2730
|
+
if (options.keyLabel)
|
|
2731
|
+
url.searchParams.set("key_label", options.keyLabel);
|
|
2732
|
+
return url.toString();
|
|
2733
|
+
};
|
|
2734
|
+
var exchangeOpenRouterAuthCode = async (body, options = {}) => {
|
|
2735
|
+
const response = await (options.fetch ?? globalThis.fetch)(`${(options.baseUrl ?? DEFAULT_BASE_URL6).replace(/\/$/, "")}/auth/keys`, {
|
|
2736
|
+
body: JSON.stringify(body),
|
|
2737
|
+
headers: { "Content-Type": "application/json" },
|
|
2738
|
+
method: "POST"
|
|
2739
|
+
});
|
|
2740
|
+
if (!response.ok)
|
|
2741
|
+
throw ProviderError.fromResponse("openrouter", response.status, await response.text());
|
|
2742
|
+
return response.json();
|
|
2743
|
+
};
|
|
2744
|
+
var createOpenRouterKeyLinks = async (key, siteUrl = DEFAULT_SITE_URL) => {
|
|
2745
|
+
const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(key)));
|
|
2746
|
+
const hash = Array.from(digest, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
2747
|
+
const root = siteUrl.replace(/\/$/, "");
|
|
2748
|
+
return {
|
|
2749
|
+
hash,
|
|
2750
|
+
logsUrl: `${root}/logs?api_key_hash=${hash}`,
|
|
2751
|
+
settingsUrl: `${root}/keys/${hash}`
|
|
2752
|
+
};
|
|
2753
|
+
};
|
|
2651
2754
|
var hexToBytes = (hex) => {
|
|
2652
2755
|
if (!/^[0-9a-f]+$/iu.test(hex) || hex.length % 2 !== 0)
|
|
2653
2756
|
return;
|
|
@@ -2693,9 +2796,11 @@ var createOpenRouterClient = (config2) => {
|
|
|
2693
2796
|
if (!config2.apiKey && !config2.tokenSource)
|
|
2694
2797
|
throw new Error("createOpenRouterClient() requires either apiKey or tokenSource");
|
|
2695
2798
|
const baseUrl = (config2.baseUrl ?? DEFAULT_BASE_URL6).replace(/\/$/, "");
|
|
2799
|
+
const batchBaseUrl = (config2.batchBaseUrl ?? (config2.baseUrl ? new URL("../beta", `${baseUrl}/`).toString() : DEFAULT_BATCH_BASE_URL)).replace(/\/$/, "");
|
|
2696
2800
|
const fetchImpl = config2.fetch ?? globalThis.fetch;
|
|
2697
2801
|
const allowedModels = config2.allowedModels ? [...config2.allowedModels] : undefined;
|
|
2698
|
-
const
|
|
2802
|
+
const defaultWorkspaceId = config2.workspaceId;
|
|
2803
|
+
const requestRawAt = async (rootUrl, path, options = {}) => {
|
|
2699
2804
|
const token = config2.tokenSource ? await Promise.resolve(config2.tokenSource()) : config2.apiKey;
|
|
2700
2805
|
const suppliedHeaders = typeof config2.headers === "function" ? await config2.headers() : config2.headers ?? {};
|
|
2701
2806
|
const headers = new Headers(suppliedHeaders);
|
|
@@ -2709,13 +2814,16 @@ var createOpenRouterClient = (config2) => {
|
|
|
2709
2814
|
body = JSON.stringify(options.body);
|
|
2710
2815
|
}
|
|
2711
2816
|
const { query, ...requestInit } = options;
|
|
2712
|
-
const response = await fetchImpl(withQuery(`${
|
|
2817
|
+
const response = await fetchImpl(withQuery(`${rootUrl}${normalizePath(path)}`, options.query), { ...requestInit, body, headers });
|
|
2713
2818
|
if (!response.ok) {
|
|
2714
2819
|
throw ProviderError.fromResponse("openrouter", response.status, await response.text());
|
|
2715
2820
|
}
|
|
2716
2821
|
return response;
|
|
2717
2822
|
};
|
|
2823
|
+
const requestRaw = (path, options = {}) => requestRawAt(baseUrl, path, options);
|
|
2718
2824
|
const request = async (path, options = {}) => (await requestRaw(path, options)).json();
|
|
2825
|
+
const requestBatch = async (path, options = {}) => (await requestRawAt(batchBaseUrl, path, options)).json();
|
|
2826
|
+
const getBatch = (id) => requestBatch(`/batches/${encodeURIComponent(id)}`);
|
|
2719
2827
|
const listModels = async (query) => {
|
|
2720
2828
|
const result = await request("/models", { query });
|
|
2721
2829
|
if (!allowedModels)
|
|
@@ -2734,10 +2842,45 @@ var createOpenRouterClient = (config2) => {
|
|
|
2734
2842
|
};
|
|
2735
2843
|
};
|
|
2736
2844
|
return {
|
|
2737
|
-
|
|
2845
|
+
addWorkspaceMembers: (id, userIds) => request(`/workspaces/${encodeURIComponent(id)}/members/add`, { body: { user_ids: [...userIds] }, method: "POST" }),
|
|
2846
|
+
createAuthCode: (body) => request("/auth/keys/code", {
|
|
2847
|
+
body: {
|
|
2848
|
+
...body,
|
|
2849
|
+
workspace_id: body.workspace_id ?? defaultWorkspaceId
|
|
2850
|
+
},
|
|
2738
2851
|
method: "POST"
|
|
2739
2852
|
}),
|
|
2740
|
-
|
|
2853
|
+
createPresetFromChatCompletions: (slug, body) => {
|
|
2854
|
+
assertAllowedModelsInValue(body, allowedModels);
|
|
2855
|
+
return request(`/presets/${encodeURIComponent(slug)}/chat/completions`, { body, method: "POST" });
|
|
2856
|
+
},
|
|
2857
|
+
createPresetFromMessages: (slug, body) => {
|
|
2858
|
+
assertAllowedModelsInValue(body, allowedModels);
|
|
2859
|
+
return request(`/presets/${encodeURIComponent(slug)}/messages`, { body, method: "POST" });
|
|
2860
|
+
},
|
|
2861
|
+
createPresetFromResponses: (slug, body) => {
|
|
2862
|
+
assertAllowedModelsInValue(body, allowedModels);
|
|
2863
|
+
return request(`/presets/${encodeURIComponent(slug)}/responses`, { body, method: "POST" });
|
|
2864
|
+
},
|
|
2865
|
+
createWorkspace: (body) => {
|
|
2866
|
+
assertAllowedModelsInValue(body, allowedModels);
|
|
2867
|
+
return request("/workspaces", {
|
|
2868
|
+
body,
|
|
2869
|
+
method: "POST"
|
|
2870
|
+
});
|
|
2871
|
+
},
|
|
2872
|
+
createBatch: (body) => {
|
|
2873
|
+
assertAllowedModel(body.model, allowedModels);
|
|
2874
|
+
return requestBatch("/batches", {
|
|
2875
|
+
body: {
|
|
2876
|
+
endpoint: body.endpoint,
|
|
2877
|
+
model: body.model,
|
|
2878
|
+
requests: body.requests,
|
|
2879
|
+
...body.completion_window ? { completion_window: body.completion_window } : {}
|
|
2880
|
+
},
|
|
2881
|
+
method: "POST"
|
|
2882
|
+
});
|
|
2883
|
+
},
|
|
2741
2884
|
createEmbedding: (body) => {
|
|
2742
2885
|
assertAllowedModel(body.model, allowedModels);
|
|
2743
2886
|
return request("/embeddings", {
|
|
@@ -2752,8 +2895,12 @@ var createOpenRouterClient = (config2) => {
|
|
|
2752
2895
|
method: "POST"
|
|
2753
2896
|
});
|
|
2754
2897
|
},
|
|
2755
|
-
deleteFile: (id, workspaceId) => request(`/files/${encodeURIComponent(id)}`, { method: "DELETE", query: { workspace_id: workspaceId } }),
|
|
2756
|
-
|
|
2898
|
+
deleteFile: (id, workspaceId = defaultWorkspaceId) => request(`/files/${encodeURIComponent(id)}`, { method: "DELETE", query: { workspace_id: workspaceId } }),
|
|
2899
|
+
deleteWorkspace: (id) => request(`/workspaces/${encodeURIComponent(id)}`, {
|
|
2900
|
+
method: "DELETE"
|
|
2901
|
+
}),
|
|
2902
|
+
deleteWorkspaceBudget: (id, interval) => request(`/workspaces/${encodeURIComponent(id)}/budgets/${interval}`, { method: "DELETE" }),
|
|
2903
|
+
downloadFile: (id, workspaceId = defaultWorkspaceId) => requestRaw(`/files/${encodeURIComponent(id)}/content`, {
|
|
2757
2904
|
query: { workspace_id: workspaceId }
|
|
2758
2905
|
}),
|
|
2759
2906
|
downloadVideo: (id, index = 0) => requestRaw(`/videos/${encodeURIComponent(id)}/content`, {
|
|
@@ -2766,15 +2913,25 @@ var createOpenRouterClient = (config2) => {
|
|
|
2766
2913
|
method: "POST"
|
|
2767
2914
|
});
|
|
2768
2915
|
},
|
|
2769
|
-
getBatch
|
|
2916
|
+
getBatch,
|
|
2917
|
+
getActivity: (query) => request("/activity", {
|
|
2918
|
+
query: {
|
|
2919
|
+
...query,
|
|
2920
|
+
workspace_id: query?.workspace_id ?? defaultWorkspaceId
|
|
2921
|
+
}
|
|
2922
|
+
}),
|
|
2923
|
+
getAnalyticsMeta: () => request("/analytics/meta"),
|
|
2770
2924
|
getCredits: () => request("/credits"),
|
|
2771
2925
|
getCurrentKey: () => request("/key"),
|
|
2772
|
-
getFile: (id, workspaceId) => request(`/files/${encodeURIComponent(id)}`, {
|
|
2926
|
+
getFile: (id, workspaceId = defaultWorkspaceId) => request(`/files/${encodeURIComponent(id)}`, {
|
|
2773
2927
|
query: { workspace_id: workspaceId }
|
|
2774
2928
|
}),
|
|
2775
2929
|
getGeneration: (id) => request("/generation", {
|
|
2776
2930
|
query: { id }
|
|
2777
2931
|
}),
|
|
2932
|
+
getGenerationContent: (id) => request("/generation/content", {
|
|
2933
|
+
query: { id }
|
|
2934
|
+
}),
|
|
2778
2935
|
getModelEndpoints: (model) => {
|
|
2779
2936
|
assertAllowedModel(model, allowedModels);
|
|
2780
2937
|
return request(`/models/${encodeModelPath(model)}/endpoints`);
|
|
@@ -2787,9 +2944,20 @@ var createOpenRouterClient = (config2) => {
|
|
|
2787
2944
|
assertAllowedModel(model, allowedModels);
|
|
2788
2945
|
return request(`/images/models/${encodeModelPath(model)}/endpoints`);
|
|
2789
2946
|
},
|
|
2947
|
+
getPreset: (slug) => request(`/presets/${encodeURIComponent(slug)}`),
|
|
2948
|
+
getPresetVersion: (slug, version) => request(`/presets/${encodeURIComponent(slug)}/versions/${encodeURIComponent(String(version))}`),
|
|
2949
|
+
getTaskClassifications: (window2 = "7d") => request("/classifications/task", {
|
|
2950
|
+
query: { window: window2 }
|
|
2951
|
+
}),
|
|
2790
2952
|
getVideo: (id) => request(`/videos/${encodeURIComponent(id)}`),
|
|
2953
|
+
getWorkspace: (id) => request(`/workspaces/${encodeURIComponent(id)}`),
|
|
2791
2954
|
listImageModels: async () => filterModelList(await request("/images/models")),
|
|
2792
|
-
listFiles: (query) => request("/files", {
|
|
2955
|
+
listFiles: (query) => request("/files", {
|
|
2956
|
+
query: {
|
|
2957
|
+
...query,
|
|
2958
|
+
workspace_id: query?.workspace_id ?? defaultWorkspaceId
|
|
2959
|
+
}
|
|
2960
|
+
}),
|
|
2793
2961
|
listModels,
|
|
2794
2962
|
listUserModels: async () => filterModelList(await request("/models/user")),
|
|
2795
2963
|
listZdrEndpoints: async () => {
|
|
@@ -2804,11 +2972,20 @@ var createOpenRouterClient = (config2) => {
|
|
|
2804
2972
|
countModels: (outputModalities) => request("/models/count", {
|
|
2805
2973
|
query: { output_modalities: outputModalities }
|
|
2806
2974
|
}),
|
|
2807
|
-
listPresets: (offset = 0, limit = 100) => request("/presets", {
|
|
2975
|
+
listPresets: (offset = 0, limit = 100) => request("/presets", {
|
|
2976
|
+
query: { limit, offset }
|
|
2977
|
+
}),
|
|
2808
2978
|
listPresetVersions: (slug, offset = 0, limit = 100) => request(`/presets/${encodeURIComponent(slug)}/versions`, { query: { limit, offset } }),
|
|
2809
2979
|
listProviders: () => request("/providers"),
|
|
2810
2980
|
listRerankModels: async () => filterModelList(await request("/rerank/models")),
|
|
2811
2981
|
listVideoModels: async () => filterModelList(await request("/videos/models")),
|
|
2982
|
+
listWorkspaceBudgets: (id) => request(`/workspaces/${encodeURIComponent(id)}/budgets`),
|
|
2983
|
+
listWorkspaces: (offset = 0, limit = 100) => request("/workspaces", { query: { limit, offset } }),
|
|
2984
|
+
queryAnalytics: (body) => request("/analytics/query", {
|
|
2985
|
+
body,
|
|
2986
|
+
method: "POST"
|
|
2987
|
+
}),
|
|
2988
|
+
removeWorkspaceMembers: (id, userIds) => request(`/workspaces/${encodeURIComponent(id)}/members/remove`, { body: { user_ids: [...userIds] }, method: "POST" }),
|
|
2812
2989
|
request,
|
|
2813
2990
|
requestRaw,
|
|
2814
2991
|
streamImage: async function* (body, options = {}) {
|
|
@@ -2861,8 +3038,41 @@ var createOpenRouterClient = (config2) => {
|
|
|
2861
3038
|
return request("/files", {
|
|
2862
3039
|
body,
|
|
2863
3040
|
method: "POST",
|
|
2864
|
-
query: { workspace_id: options.workspaceId }
|
|
3041
|
+
query: { workspace_id: options.workspaceId ?? defaultWorkspaceId }
|
|
2865
3042
|
});
|
|
3043
|
+
},
|
|
3044
|
+
updateWorkspace: (id, body) => {
|
|
3045
|
+
assertAllowedModelsInValue(body, allowedModels);
|
|
3046
|
+
return request(`/workspaces/${encodeURIComponent(id)}`, { body, method: "PATCH" });
|
|
3047
|
+
},
|
|
3048
|
+
upsertWorkspaceBudget: (id, interval, limitUsd) => request(`/workspaces/${encodeURIComponent(id)}/budgets/${interval}`, { body: { limit_usd: limitUsd }, method: "PUT" }),
|
|
3049
|
+
waitForBatch: async (id, options = {}) => {
|
|
3050
|
+
const intervalMs = options.intervalMs ?? 1000;
|
|
3051
|
+
const timeoutMs = options.timeoutMs;
|
|
3052
|
+
if (!Number.isFinite(intervalMs) || intervalMs < 0)
|
|
3053
|
+
throw new Error("OpenRouter batch intervalMs must be non-negative");
|
|
3054
|
+
if (timeoutMs !== undefined && (!Number.isFinite(timeoutMs) || timeoutMs < 0))
|
|
3055
|
+
throw new Error("OpenRouter batch timeoutMs must be non-negative");
|
|
3056
|
+
const startedAt = Date.now();
|
|
3057
|
+
for (;; ) {
|
|
3058
|
+
options.signal?.throwIfAborted();
|
|
3059
|
+
const batch = await getBatch(id);
|
|
3060
|
+
if (TERMINAL_BATCH_STATUSES.has(batch.status))
|
|
3061
|
+
return batch;
|
|
3062
|
+
if (timeoutMs !== undefined && Date.now() - startedAt + intervalMs > timeoutMs)
|
|
3063
|
+
throw new Error(`Timed out waiting for OpenRouter batch "${id}"`);
|
|
3064
|
+
await new Promise((resolve, reject) => {
|
|
3065
|
+
const onAbort = () => {
|
|
3066
|
+
clearTimeout(timeout);
|
|
3067
|
+
reject(options.signal?.reason);
|
|
3068
|
+
};
|
|
3069
|
+
const timeout = setTimeout(() => {
|
|
3070
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
3071
|
+
resolve();
|
|
3072
|
+
}, intervalMs);
|
|
3073
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
3074
|
+
});
|
|
3075
|
+
}
|
|
2866
3076
|
}
|
|
2867
3077
|
};
|
|
2868
3078
|
};
|
|
@@ -2999,7 +3209,7 @@ var assertAllowedPreset = (preset, allowedPresets) => {
|
|
|
2999
3209
|
var assertIndirectModels = (value, allowedModels, key = "") => {
|
|
3000
3210
|
if (key === "model" && typeof value === "string")
|
|
3001
3211
|
assertAllowedModel2(value, allowedModels);
|
|
3002
|
-
if ((key === "models" || key === "analysis_models") && Array.isArray(value)) {
|
|
3212
|
+
if ((key === "models" || key === "analysis_models" || key === "allowed_models") && Array.isArray(value)) {
|
|
3003
3213
|
for (const model of value) {
|
|
3004
3214
|
if (typeof model === "string")
|
|
3005
3215
|
assertAllowedModel2(model, allowedModels);
|
|
@@ -7313,6 +7523,7 @@ export {
|
|
|
7313
7523
|
meta,
|
|
7314
7524
|
google,
|
|
7315
7525
|
getProviderHealth,
|
|
7526
|
+
generateOpenRouterPKCE,
|
|
7316
7527
|
generateObjectAI,
|
|
7317
7528
|
generateId,
|
|
7318
7529
|
generateAIWithTools,
|
|
@@ -7320,13 +7531,18 @@ export {
|
|
|
7320
7531
|
gemini,
|
|
7321
7532
|
formCard,
|
|
7322
7533
|
fetchProviderApiStatus,
|
|
7534
|
+
exchangeOpenRouterAuthCode,
|
|
7535
|
+
estimateOpenRouterModelCost,
|
|
7536
|
+
estimateOpenRouterCost,
|
|
7323
7537
|
diffCard,
|
|
7324
7538
|
deepseek,
|
|
7325
7539
|
credentialCard,
|
|
7326
7540
|
createUiCards,
|
|
7327
7541
|
createSyncConversationStore,
|
|
7328
7542
|
createProviderProxyResponse,
|
|
7543
|
+
createOpenRouterKeyLinks,
|
|
7329
7544
|
createOpenRouterClient,
|
|
7545
|
+
createOpenRouterAuthorizationUrl,
|
|
7330
7546
|
createOAuth2ClientCredentialsTokenSource,
|
|
7331
7547
|
createMemoryStore,
|
|
7332
7548
|
createConversationManager,
|
|
@@ -7364,5 +7580,5 @@ export {
|
|
|
7364
7580
|
BUILTIN_UI_CARDS
|
|
7365
7581
|
};
|
|
7366
7582
|
|
|
7367
|
-
//# debugId=
|
|
7583
|
+
//# debugId=25187F8D2370EC5064756E2164756E21
|
|
7368
7584
|
//# sourceMappingURL=index.js.map
|