@absolutejs/ai 0.0.51 → 0.0.53
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 +107 -8
- package/dist/ai/index.js +317 -13
- package/dist/ai/index.js.map +4 -4
- package/dist/ai/providers/openrouter.js +318 -14
- package/dist/ai/providers/openrouter.js.map +4 -4
- package/dist/ai/providers/openrouterSDK.js +37 -0
- package/dist/ai/providers/openrouterSDK.js.map +10 -0
- package/dist/src/ai/index.d.ts +2 -2
- package/dist/src/ai/providers/openrouter.d.ts +153 -5
- package/dist/src/ai/providers/openrouterClient.d.ts +380 -10
- package/dist/src/ai/providers/openrouterSDK.d.ts +21 -0
- package/package.json +10 -2
|
@@ -1990,7 +1990,46 @@ var anthropic = (config2) => {
|
|
|
1990
1990
|
};
|
|
1991
1991
|
|
|
1992
1992
|
// src/ai/providers/openrouterClient.ts
|
|
1993
|
+
var OPENROUTER_PRICING_KEYS = [
|
|
1994
|
+
"prompt",
|
|
1995
|
+
"completion",
|
|
1996
|
+
"request",
|
|
1997
|
+
"image",
|
|
1998
|
+
"web_search",
|
|
1999
|
+
"internal_reasoning",
|
|
2000
|
+
"input_cache_read",
|
|
2001
|
+
"input_cache_write"
|
|
2002
|
+
];
|
|
2003
|
+
var estimateOpenRouterCost = (pricing, units) => {
|
|
2004
|
+
const components = {};
|
|
2005
|
+
let total = 0;
|
|
2006
|
+
for (const key of OPENROUTER_PRICING_KEYS) {
|
|
2007
|
+
const quantity = units[key];
|
|
2008
|
+
if (quantity === undefined)
|
|
2009
|
+
continue;
|
|
2010
|
+
if (!Number.isFinite(quantity) || quantity < 0)
|
|
2011
|
+
throw new Error(`OpenRouter ${key} units must be non-negative`);
|
|
2012
|
+
const rawPrice = pricing[key];
|
|
2013
|
+
if (rawPrice === undefined)
|
|
2014
|
+
continue;
|
|
2015
|
+
const price = Number(rawPrice);
|
|
2016
|
+
if (!Number.isFinite(price) || price < 0)
|
|
2017
|
+
throw new Error(`OpenRouter ${key} price must be non-negative`);
|
|
2018
|
+
components[key] = price * quantity;
|
|
2019
|
+
total += components[key];
|
|
2020
|
+
}
|
|
2021
|
+
return { components, total };
|
|
2022
|
+
};
|
|
2023
|
+
var estimateOpenRouterModelCost = (model, units) => estimateOpenRouterCost(model.pricing ?? {}, units);
|
|
1993
2024
|
var DEFAULT_BASE_URL4 = "https://openrouter.ai/api/v1";
|
|
2025
|
+
var DEFAULT_BATCH_BASE_URL = "https://openrouter.ai/api/beta";
|
|
2026
|
+
var DEFAULT_SITE_URL = "https://openrouter.ai";
|
|
2027
|
+
var TERMINAL_BATCH_STATUSES = new Set([
|
|
2028
|
+
"completed",
|
|
2029
|
+
"failed",
|
|
2030
|
+
"expired",
|
|
2031
|
+
"cancelled"
|
|
2032
|
+
]);
|
|
1994
2033
|
var withoutLatestPrefix = (model) => model.startsWith("~") ? model.slice(1) : model;
|
|
1995
2034
|
var openRouterModelMatchesRule = (model, rule) => {
|
|
1996
2035
|
const normalizedModel = withoutLatestPrefix(model);
|
|
@@ -2004,6 +2043,22 @@ var assertAllowedModel = (model, allowedModels) => {
|
|
|
2004
2043
|
return;
|
|
2005
2044
|
throw new Error(`OpenRouter model "${model}" is not allowed`);
|
|
2006
2045
|
};
|
|
2046
|
+
var assertAllowedModelsInValue = (value, allowedModels, key = "") => {
|
|
2047
|
+
if (key === "model" && typeof value === "string")
|
|
2048
|
+
assertAllowedModel(value, allowedModels);
|
|
2049
|
+
if ((key === "models" || key === "analysis_models" || key === "allowed_models") && Array.isArray(value)) {
|
|
2050
|
+
for (const model of value)
|
|
2051
|
+
if (typeof model === "string")
|
|
2052
|
+
assertAllowedModel(model, allowedModels);
|
|
2053
|
+
}
|
|
2054
|
+
if (Array.isArray(value)) {
|
|
2055
|
+
for (const item of value)
|
|
2056
|
+
assertAllowedModelsInValue(item, allowedModels);
|
|
2057
|
+
} else if (value && typeof value === "object") {
|
|
2058
|
+
for (const [childKey, child] of Object.entries(value))
|
|
2059
|
+
assertAllowedModelsInValue(child, allowedModels, childKey);
|
|
2060
|
+
}
|
|
2061
|
+
};
|
|
2007
2062
|
var normalizePath = (path) => path.startsWith("/") ? path : `/${path}`;
|
|
2008
2063
|
var encodeModelPath = (model) => model.split("/").map(encodeURIComponent).join("/");
|
|
2009
2064
|
var withQuery = (url, query) => {
|
|
@@ -2054,6 +2109,54 @@ var parseImageSSE = async function* (response) {
|
|
|
2054
2109
|
}
|
|
2055
2110
|
};
|
|
2056
2111
|
var toBytes = (value) => typeof value === "string" ? new TextEncoder().encode(value) : value;
|
|
2112
|
+
var toBase64Url = (bytes) => {
|
|
2113
|
+
let binary = "";
|
|
2114
|
+
for (const byte of bytes)
|
|
2115
|
+
binary += String.fromCharCode(byte);
|
|
2116
|
+
return btoa(binary).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/u, "");
|
|
2117
|
+
};
|
|
2118
|
+
var generateOpenRouterPKCE = async () => {
|
|
2119
|
+
const random = crypto.getRandomValues(new Uint8Array(32));
|
|
2120
|
+
const codeVerifier = toBase64Url(random);
|
|
2121
|
+
const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(codeVerifier));
|
|
2122
|
+
return {
|
|
2123
|
+
codeChallenge: toBase64Url(new Uint8Array(digest)),
|
|
2124
|
+
codeChallengeMethod: "S256",
|
|
2125
|
+
codeVerifier
|
|
2126
|
+
};
|
|
2127
|
+
};
|
|
2128
|
+
var createOpenRouterAuthorizationUrl = (options = {}) => {
|
|
2129
|
+
const url = new URL("/auth", options.baseUrl ?? DEFAULT_SITE_URL);
|
|
2130
|
+
if (options.callbackUrl)
|
|
2131
|
+
url.searchParams.set("callback_url", options.callbackUrl);
|
|
2132
|
+
if (options.codeChallenge)
|
|
2133
|
+
url.searchParams.set("code_challenge", options.codeChallenge);
|
|
2134
|
+
if (options.codeChallengeMethod)
|
|
2135
|
+
url.searchParams.set("code_challenge_method", options.codeChallengeMethod);
|
|
2136
|
+
if (options.keyLabel)
|
|
2137
|
+
url.searchParams.set("key_label", options.keyLabel);
|
|
2138
|
+
return url.toString();
|
|
2139
|
+
};
|
|
2140
|
+
var exchangeOpenRouterAuthCode = async (body, options = {}) => {
|
|
2141
|
+
const response = await (options.fetch ?? globalThis.fetch)(`${(options.baseUrl ?? DEFAULT_BASE_URL4).replace(/\/$/, "")}/auth/keys`, {
|
|
2142
|
+
body: JSON.stringify(body),
|
|
2143
|
+
headers: { "Content-Type": "application/json" },
|
|
2144
|
+
method: "POST"
|
|
2145
|
+
});
|
|
2146
|
+
if (!response.ok)
|
|
2147
|
+
throw ProviderError.fromResponse("openrouter", response.status, await response.text());
|
|
2148
|
+
return response.json();
|
|
2149
|
+
};
|
|
2150
|
+
var createOpenRouterKeyLinks = async (key, siteUrl = DEFAULT_SITE_URL) => {
|
|
2151
|
+
const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(key)));
|
|
2152
|
+
const hash = Array.from(digest, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
2153
|
+
const root = siteUrl.replace(/\/$/, "");
|
|
2154
|
+
return {
|
|
2155
|
+
hash,
|
|
2156
|
+
logsUrl: `${root}/logs?api_key_hash=${hash}`,
|
|
2157
|
+
settingsUrl: `${root}/keys/${hash}`
|
|
2158
|
+
};
|
|
2159
|
+
};
|
|
2057
2160
|
var hexToBytes = (hex) => {
|
|
2058
2161
|
if (!/^[0-9a-f]+$/iu.test(hex) || hex.length % 2 !== 0)
|
|
2059
2162
|
return;
|
|
@@ -2099,9 +2202,11 @@ var createOpenRouterClient = (config2) => {
|
|
|
2099
2202
|
if (!config2.apiKey && !config2.tokenSource)
|
|
2100
2203
|
throw new Error("createOpenRouterClient() requires either apiKey or tokenSource");
|
|
2101
2204
|
const baseUrl = (config2.baseUrl ?? DEFAULT_BASE_URL4).replace(/\/$/, "");
|
|
2205
|
+
const batchBaseUrl = (config2.batchBaseUrl ?? (config2.baseUrl ? new URL("../beta", `${baseUrl}/`).toString() : DEFAULT_BATCH_BASE_URL)).replace(/\/$/, "");
|
|
2102
2206
|
const fetchImpl = config2.fetch ?? globalThis.fetch;
|
|
2103
2207
|
const allowedModels = config2.allowedModels ? [...config2.allowedModels] : undefined;
|
|
2104
|
-
const
|
|
2208
|
+
const defaultWorkspaceId = config2.workspaceId;
|
|
2209
|
+
const requestRawAt = async (rootUrl, path, options = {}) => {
|
|
2105
2210
|
const token = config2.tokenSource ? await Promise.resolve(config2.tokenSource()) : config2.apiKey;
|
|
2106
2211
|
const suppliedHeaders = typeof config2.headers === "function" ? await config2.headers() : config2.headers ?? {};
|
|
2107
2212
|
const headers = new Headers(suppliedHeaders);
|
|
@@ -2115,13 +2220,16 @@ var createOpenRouterClient = (config2) => {
|
|
|
2115
2220
|
body = JSON.stringify(options.body);
|
|
2116
2221
|
}
|
|
2117
2222
|
const { query, ...requestInit } = options;
|
|
2118
|
-
const response = await fetchImpl(withQuery(`${
|
|
2223
|
+
const response = await fetchImpl(withQuery(`${rootUrl}${normalizePath(path)}`, options.query), { ...requestInit, body, headers });
|
|
2119
2224
|
if (!response.ok) {
|
|
2120
2225
|
throw ProviderError.fromResponse("openrouter", response.status, await response.text());
|
|
2121
2226
|
}
|
|
2122
2227
|
return response;
|
|
2123
2228
|
};
|
|
2229
|
+
const requestRaw = (path, options = {}) => requestRawAt(baseUrl, path, options);
|
|
2124
2230
|
const request = async (path, options = {}) => (await requestRaw(path, options)).json();
|
|
2231
|
+
const requestBatch = async (path, options = {}) => (await requestRawAt(batchBaseUrl, path, options)).json();
|
|
2232
|
+
const getBatch = (id) => requestBatch(`/batches/${encodeURIComponent(id)}`);
|
|
2125
2233
|
const listModels = async (query) => {
|
|
2126
2234
|
const result = await request("/models", { query });
|
|
2127
2235
|
if (!allowedModels)
|
|
@@ -2140,10 +2248,52 @@ var createOpenRouterClient = (config2) => {
|
|
|
2140
2248
|
};
|
|
2141
2249
|
};
|
|
2142
2250
|
return {
|
|
2143
|
-
|
|
2251
|
+
addWorkspaceMembers: (id, userIds) => request(`/workspaces/${encodeURIComponent(id)}/members/add`, { body: { user_ids: [...userIds] }, method: "POST" }),
|
|
2252
|
+
createAuthCode: (body) => request("/auth/keys/code", {
|
|
2253
|
+
body: {
|
|
2254
|
+
...body,
|
|
2255
|
+
workspace_id: body.workspace_id ?? defaultWorkspaceId
|
|
2256
|
+
},
|
|
2144
2257
|
method: "POST"
|
|
2145
2258
|
}),
|
|
2146
|
-
|
|
2259
|
+
chat: (body) => {
|
|
2260
|
+
assertAllowedModelsInValue(body, allowedModels);
|
|
2261
|
+
return request("/chat/completions", {
|
|
2262
|
+
body: { ...body, stream: false },
|
|
2263
|
+
method: "POST"
|
|
2264
|
+
});
|
|
2265
|
+
},
|
|
2266
|
+
createPresetFromChatCompletions: (slug, body) => {
|
|
2267
|
+
assertAllowedModelsInValue(body, allowedModels);
|
|
2268
|
+
return request(`/presets/${encodeURIComponent(slug)}/chat/completions`, { body, method: "POST" });
|
|
2269
|
+
},
|
|
2270
|
+
createPresetFromMessages: (slug, body) => {
|
|
2271
|
+
assertAllowedModelsInValue(body, allowedModels);
|
|
2272
|
+
return request(`/presets/${encodeURIComponent(slug)}/messages`, { body, method: "POST" });
|
|
2273
|
+
},
|
|
2274
|
+
createPresetFromResponses: (slug, body) => {
|
|
2275
|
+
assertAllowedModelsInValue(body, allowedModels);
|
|
2276
|
+
return request(`/presets/${encodeURIComponent(slug)}/responses`, { body, method: "POST" });
|
|
2277
|
+
},
|
|
2278
|
+
createWorkspace: (body) => {
|
|
2279
|
+
assertAllowedModelsInValue(body, allowedModels);
|
|
2280
|
+
return request("/workspaces", {
|
|
2281
|
+
body,
|
|
2282
|
+
method: "POST"
|
|
2283
|
+
});
|
|
2284
|
+
},
|
|
2285
|
+
createBatch: (body) => {
|
|
2286
|
+
assertAllowedModel(body.model, allowedModels);
|
|
2287
|
+
return requestBatch("/batches", {
|
|
2288
|
+
body: {
|
|
2289
|
+
endpoint: body.endpoint,
|
|
2290
|
+
model: body.model,
|
|
2291
|
+
requests: body.requests,
|
|
2292
|
+
...body.completion_window ? { completion_window: body.completion_window } : {}
|
|
2293
|
+
},
|
|
2294
|
+
method: "POST"
|
|
2295
|
+
});
|
|
2296
|
+
},
|
|
2147
2297
|
createEmbedding: (body) => {
|
|
2148
2298
|
assertAllowedModel(body.model, allowedModels);
|
|
2149
2299
|
return request("/embeddings", {
|
|
@@ -2158,8 +2308,12 @@ var createOpenRouterClient = (config2) => {
|
|
|
2158
2308
|
method: "POST"
|
|
2159
2309
|
});
|
|
2160
2310
|
},
|
|
2161
|
-
deleteFile: (id, workspaceId) => request(`/files/${encodeURIComponent(id)}`, { method: "DELETE", query: { workspace_id: workspaceId } }),
|
|
2162
|
-
|
|
2311
|
+
deleteFile: (id, workspaceId = defaultWorkspaceId) => request(`/files/${encodeURIComponent(id)}`, { method: "DELETE", query: { workspace_id: workspaceId } }),
|
|
2312
|
+
deleteWorkspace: (id) => request(`/workspaces/${encodeURIComponent(id)}`, {
|
|
2313
|
+
method: "DELETE"
|
|
2314
|
+
}),
|
|
2315
|
+
deleteWorkspaceBudget: (id, interval) => request(`/workspaces/${encodeURIComponent(id)}/budgets/${interval}`, { method: "DELETE" }),
|
|
2316
|
+
downloadFile: (id, workspaceId = defaultWorkspaceId) => requestRaw(`/files/${encodeURIComponent(id)}/content`, {
|
|
2163
2317
|
query: { workspace_id: workspaceId }
|
|
2164
2318
|
}),
|
|
2165
2319
|
downloadVideo: (id, index = 0) => requestRaw(`/videos/${encodeURIComponent(id)}/content`, {
|
|
@@ -2172,15 +2326,25 @@ var createOpenRouterClient = (config2) => {
|
|
|
2172
2326
|
method: "POST"
|
|
2173
2327
|
});
|
|
2174
2328
|
},
|
|
2175
|
-
getBatch
|
|
2329
|
+
getBatch,
|
|
2330
|
+
getActivity: (query) => request("/activity", {
|
|
2331
|
+
query: {
|
|
2332
|
+
...query,
|
|
2333
|
+
workspace_id: query?.workspace_id ?? defaultWorkspaceId
|
|
2334
|
+
}
|
|
2335
|
+
}),
|
|
2336
|
+
getAnalyticsMeta: () => request("/analytics/meta"),
|
|
2176
2337
|
getCredits: () => request("/credits"),
|
|
2177
2338
|
getCurrentKey: () => request("/key"),
|
|
2178
|
-
getFile: (id, workspaceId) => request(`/files/${encodeURIComponent(id)}`, {
|
|
2339
|
+
getFile: (id, workspaceId = defaultWorkspaceId) => request(`/files/${encodeURIComponent(id)}`, {
|
|
2179
2340
|
query: { workspace_id: workspaceId }
|
|
2180
2341
|
}),
|
|
2181
2342
|
getGeneration: (id) => request("/generation", {
|
|
2182
2343
|
query: { id }
|
|
2183
2344
|
}),
|
|
2345
|
+
getGenerationContent: (id) => request("/generation/content", {
|
|
2346
|
+
query: { id }
|
|
2347
|
+
}),
|
|
2184
2348
|
getModelEndpoints: (model) => {
|
|
2185
2349
|
assertAllowedModel(model, allowedModels);
|
|
2186
2350
|
return request(`/models/${encodeModelPath(model)}/endpoints`);
|
|
@@ -2193,9 +2357,21 @@ var createOpenRouterClient = (config2) => {
|
|
|
2193
2357
|
assertAllowedModel(model, allowedModels);
|
|
2194
2358
|
return request(`/images/models/${encodeModelPath(model)}/endpoints`);
|
|
2195
2359
|
},
|
|
2360
|
+
getPreset: (slug) => request(`/presets/${encodeURIComponent(slug)}`),
|
|
2361
|
+
getPresetVersion: (slug, version) => request(`/presets/${encodeURIComponent(slug)}/versions/${encodeURIComponent(String(version))}`),
|
|
2362
|
+
getTaskClassifications: (window = "7d") => request("/classifications/task", {
|
|
2363
|
+
query: { window }
|
|
2364
|
+
}),
|
|
2196
2365
|
getVideo: (id) => request(`/videos/${encodeURIComponent(id)}`),
|
|
2366
|
+
getWorkspace: (id) => request(`/workspaces/${encodeURIComponent(id)}`),
|
|
2197
2367
|
listImageModels: async () => filterModelList(await request("/images/models")),
|
|
2198
|
-
|
|
2368
|
+
listEmbeddingModels: async () => filterModelList(await request("/embeddings/models")),
|
|
2369
|
+
listFiles: (query) => request("/files", {
|
|
2370
|
+
query: {
|
|
2371
|
+
...query,
|
|
2372
|
+
workspace_id: query?.workspace_id ?? defaultWorkspaceId
|
|
2373
|
+
}
|
|
2374
|
+
}),
|
|
2199
2375
|
listModels,
|
|
2200
2376
|
listUserModels: async () => filterModelList(await request("/models/user")),
|
|
2201
2377
|
listZdrEndpoints: async () => {
|
|
@@ -2210,11 +2386,20 @@ var createOpenRouterClient = (config2) => {
|
|
|
2210
2386
|
countModels: (outputModalities) => request("/models/count", {
|
|
2211
2387
|
query: { output_modalities: outputModalities }
|
|
2212
2388
|
}),
|
|
2213
|
-
listPresets: (offset = 0, limit = 100) => request("/presets", {
|
|
2389
|
+
listPresets: (offset = 0, limit = 100) => request("/presets", {
|
|
2390
|
+
query: { limit, offset }
|
|
2391
|
+
}),
|
|
2214
2392
|
listPresetVersions: (slug, offset = 0, limit = 100) => request(`/presets/${encodeURIComponent(slug)}/versions`, { query: { limit, offset } }),
|
|
2215
2393
|
listProviders: () => request("/providers"),
|
|
2216
2394
|
listRerankModels: async () => filterModelList(await request("/rerank/models")),
|
|
2217
2395
|
listVideoModels: async () => filterModelList(await request("/videos/models")),
|
|
2396
|
+
listWorkspaceBudgets: (id) => request(`/workspaces/${encodeURIComponent(id)}/budgets`),
|
|
2397
|
+
listWorkspaces: (offset = 0, limit = 100) => request("/workspaces", { query: { limit, offset } }),
|
|
2398
|
+
queryAnalytics: (body) => request("/analytics/query", {
|
|
2399
|
+
body,
|
|
2400
|
+
method: "POST"
|
|
2401
|
+
}),
|
|
2402
|
+
removeWorkspaceMembers: (id, userIds) => request(`/workspaces/${encodeURIComponent(id)}/members/remove`, { body: { user_ids: [...userIds] }, method: "POST" }),
|
|
2218
2403
|
request,
|
|
2219
2404
|
requestRaw,
|
|
2220
2405
|
streamImage: async function* (body, options = {}) {
|
|
@@ -2267,8 +2452,41 @@ var createOpenRouterClient = (config2) => {
|
|
|
2267
2452
|
return request("/files", {
|
|
2268
2453
|
body,
|
|
2269
2454
|
method: "POST",
|
|
2270
|
-
query: { workspace_id: options.workspaceId }
|
|
2455
|
+
query: { workspace_id: options.workspaceId ?? defaultWorkspaceId }
|
|
2271
2456
|
});
|
|
2457
|
+
},
|
|
2458
|
+
updateWorkspace: (id, body) => {
|
|
2459
|
+
assertAllowedModelsInValue(body, allowedModels);
|
|
2460
|
+
return request(`/workspaces/${encodeURIComponent(id)}`, { body, method: "PATCH" });
|
|
2461
|
+
},
|
|
2462
|
+
upsertWorkspaceBudget: (id, interval, limitUsd) => request(`/workspaces/${encodeURIComponent(id)}/budgets/${interval}`, { body: { limit_usd: limitUsd }, method: "PUT" }),
|
|
2463
|
+
waitForBatch: async (id, options = {}) => {
|
|
2464
|
+
const intervalMs = options.intervalMs ?? 1000;
|
|
2465
|
+
const timeoutMs = options.timeoutMs;
|
|
2466
|
+
if (!Number.isFinite(intervalMs) || intervalMs < 0)
|
|
2467
|
+
throw new Error("OpenRouter batch intervalMs must be non-negative");
|
|
2468
|
+
if (timeoutMs !== undefined && (!Number.isFinite(timeoutMs) || timeoutMs < 0))
|
|
2469
|
+
throw new Error("OpenRouter batch timeoutMs must be non-negative");
|
|
2470
|
+
const startedAt = Date.now();
|
|
2471
|
+
for (;; ) {
|
|
2472
|
+
options.signal?.throwIfAborted();
|
|
2473
|
+
const batch = await getBatch(id);
|
|
2474
|
+
if (TERMINAL_BATCH_STATUSES.has(batch.status))
|
|
2475
|
+
return batch;
|
|
2476
|
+
if (timeoutMs !== undefined && Date.now() - startedAt + intervalMs > timeoutMs)
|
|
2477
|
+
throw new Error(`Timed out waiting for OpenRouter batch "${id}"`);
|
|
2478
|
+
await new Promise((resolve, reject) => {
|
|
2479
|
+
const onAbort = () => {
|
|
2480
|
+
clearTimeout(timeout);
|
|
2481
|
+
reject(options.signal?.reason);
|
|
2482
|
+
};
|
|
2483
|
+
const timeout = setTimeout(() => {
|
|
2484
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
2485
|
+
resolve();
|
|
2486
|
+
}, intervalMs);
|
|
2487
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
2488
|
+
});
|
|
2489
|
+
}
|
|
2272
2490
|
}
|
|
2273
2491
|
};
|
|
2274
2492
|
};
|
|
@@ -2405,7 +2623,7 @@ var assertAllowedPreset = (preset, allowedPresets) => {
|
|
|
2405
2623
|
var assertIndirectModels = (value, allowedModels, key = "") => {
|
|
2406
2624
|
if (key === "model" && typeof value === "string")
|
|
2407
2625
|
assertAllowedModel2(value, allowedModels);
|
|
2408
|
-
if ((key === "models" || key === "analysis_models") && Array.isArray(value)) {
|
|
2626
|
+
if ((key === "models" || key === "analysis_models" || key === "allowed_models") && Array.isArray(value)) {
|
|
2409
2627
|
for (const model of value) {
|
|
2410
2628
|
if (typeof model === "string")
|
|
2411
2629
|
assertAllowedModel2(model, allowedModels);
|
|
@@ -2419,6 +2637,84 @@ var assertIndirectModels = (value, allowedModels, key = "") => {
|
|
|
2419
2637
|
assertIndirectModels(child, allowedModels, childKey);
|
|
2420
2638
|
}
|
|
2421
2639
|
};
|
|
2640
|
+
var assertIntegerRange = (label, value, minimum, maximum) => {
|
|
2641
|
+
if (value === undefined)
|
|
2642
|
+
return;
|
|
2643
|
+
if (!Number.isInteger(value) || value < minimum || maximum !== undefined && value > maximum)
|
|
2644
|
+
throw new Error(`OpenRouter ${label} must be an integer from ${minimum}${maximum === undefined ? " or greater" : ` to ${maximum}`}`);
|
|
2645
|
+
};
|
|
2646
|
+
var assertPluginOptions = (plugins) => {
|
|
2647
|
+
for (const plugin of plugins ?? []) {
|
|
2648
|
+
if (plugin.id === "response-healing")
|
|
2649
|
+
throw new Error("OpenRouter response-healing requires a non-streaming request; use createOpenRouterClient().chat()");
|
|
2650
|
+
if (plugin.id === "fusion") {
|
|
2651
|
+
const fusion = plugin;
|
|
2652
|
+
if (fusion.analysis_models && (fusion.analysis_models.length < 1 || fusion.analysis_models.length > 8))
|
|
2653
|
+
throw new Error("OpenRouter Fusion analysis_models must contain 1-8 models");
|
|
2654
|
+
assertIntegerRange("Fusion max_tool_calls", fusion.max_tool_calls, 1, 16);
|
|
2655
|
+
}
|
|
2656
|
+
if (plugin.id === "web") {
|
|
2657
|
+
const web = plugin;
|
|
2658
|
+
assertIntegerRange("web plugin max_results", web.max_results, 1, web.engine === "perplexity" ? 20 : 25);
|
|
2659
|
+
if (web.include_domains?.length && web.exclude_domains?.length && (web.engine === "firecrawl" || web.engine === "parallel" || web.engine === "perplexity"))
|
|
2660
|
+
throw new Error(`OpenRouter ${web.engine} web plugin cannot combine include_domains and exclude_domains`);
|
|
2661
|
+
}
|
|
2662
|
+
}
|
|
2663
|
+
};
|
|
2664
|
+
var assertServerToolOptions = (tools) => {
|
|
2665
|
+
for (const tool of tools ?? []) {
|
|
2666
|
+
if (tool.type === "openrouter:web_search") {
|
|
2667
|
+
const parameters = tool.parameters;
|
|
2668
|
+
assertIntegerRange("web search max_results", parameters?.max_results, 1, 25);
|
|
2669
|
+
if (parameters?.engine === "perplexity" && (parameters.max_results ?? 0) > 20)
|
|
2670
|
+
throw new Error("OpenRouter Perplexity web search max_results must be at most 20");
|
|
2671
|
+
assertIntegerRange("web search max_characters", parameters?.max_characters, 1, 1e5);
|
|
2672
|
+
assertIntegerRange("web search max_total_results", parameters?.max_total_results, 1);
|
|
2673
|
+
}
|
|
2674
|
+
if (tool.type === "openrouter:web_fetch") {
|
|
2675
|
+
assertIntegerRange("web fetch max_uses", tool.parameters?.max_uses, 1);
|
|
2676
|
+
assertIntegerRange("web fetch max_content_tokens", tool.parameters?.max_content_tokens, 1);
|
|
2677
|
+
}
|
|
2678
|
+
if (tool.type === "openrouter:image_generation") {
|
|
2679
|
+
const compression = tool.parameters?.output_compression;
|
|
2680
|
+
if (compression !== undefined && (!Number.isFinite(compression) || compression < 0 || compression > 100))
|
|
2681
|
+
throw new Error("OpenRouter image generation output_compression must be 0-100");
|
|
2682
|
+
}
|
|
2683
|
+
if (tool.type === "openrouter:subagent") {
|
|
2684
|
+
assertIntegerRange("subagent max_completion_tokens", tool.parameters.max_completion_tokens, 1);
|
|
2685
|
+
assertIntegerRange("subagent max_tool_calls", tool.parameters.max_tool_calls, 1, 25);
|
|
2686
|
+
const temperature = tool.parameters.temperature;
|
|
2687
|
+
if (temperature !== undefined && (!Number.isFinite(temperature) || temperature < 0 || temperature > 2))
|
|
2688
|
+
throw new Error("OpenRouter subagent temperature must be 0-2");
|
|
2689
|
+
assertServerToolOptions(tool.parameters.tools);
|
|
2690
|
+
}
|
|
2691
|
+
if (tool.type === "openrouter:advisor") {
|
|
2692
|
+
assertIntegerRange("advisor max_completion_tokens", tool.parameters?.max_completion_tokens, 1);
|
|
2693
|
+
const temperature = tool.parameters?.temperature;
|
|
2694
|
+
if (temperature !== undefined && (!Number.isFinite(temperature) || temperature < 0 || temperature > 2))
|
|
2695
|
+
throw new Error("OpenRouter advisor temperature must be 0-2");
|
|
2696
|
+
}
|
|
2697
|
+
if (tool.type === "openrouter:fusion") {
|
|
2698
|
+
const analysisModels = tool.parameters?.analysis_models;
|
|
2699
|
+
if (analysisModels && (analysisModels.length < 1 || analysisModels.length > 8))
|
|
2700
|
+
throw new Error("OpenRouter Fusion server tool analysis_models must contain 1-8 models");
|
|
2701
|
+
assertIntegerRange("Fusion server tool max_completion_tokens", tool.parameters?.max_completion_tokens, 1);
|
|
2702
|
+
assertIntegerRange("Fusion server tool max_tool_calls", tool.parameters?.max_tool_calls, 1, 16);
|
|
2703
|
+
const temperature = tool.parameters?.temperature;
|
|
2704
|
+
if (temperature !== undefined && (!Number.isFinite(temperature) || temperature < 0 || temperature > 2))
|
|
2705
|
+
throw new Error("OpenRouter Fusion server tool temperature must be 0-2");
|
|
2706
|
+
assertServerToolOptions(tool.parameters?.tools);
|
|
2707
|
+
}
|
|
2708
|
+
if (tool.type === "openrouter:shell") {
|
|
2709
|
+
assertIntegerRange("shell sleep_after_seconds", tool.parameters?.sleep_after_seconds, 0, 2592000);
|
|
2710
|
+
const environment = tool.parameters?.environment;
|
|
2711
|
+
if (environment?.type === "container_reference" && (environment.container_id.length < 1 || environment.container_id.length > 20))
|
|
2712
|
+
throw new Error("OpenRouter shell container_id must contain 1-20 characters");
|
|
2713
|
+
}
|
|
2714
|
+
if (tool.type === "openrouter:experimental__search_models")
|
|
2715
|
+
assertIntegerRange("model search max_results", tool.parameters?.max_results, 1, 20);
|
|
2716
|
+
}
|
|
2717
|
+
};
|
|
2422
2718
|
var assertRequestOptions = (options, allowedModels, allowedPresets, allowedProviders) => {
|
|
2423
2719
|
assertAllowedPreset(options.preset, allowedPresets);
|
|
2424
2720
|
assertRequestRoutingPolicy(options.routing, allowedProviders);
|
|
@@ -2438,6 +2734,8 @@ var assertRequestOptions = (options, allowedModels, allowedPresets, allowedProvi
|
|
|
2438
2734
|
assertIndirectModels(options.serverTools, allowedModels);
|
|
2439
2735
|
assertIndirectModels(options.messagesTools, allowedModels);
|
|
2440
2736
|
assertIndirectModels(options.plugins, allowedModels);
|
|
2737
|
+
assertPluginOptions(options.plugins);
|
|
2738
|
+
assertServerToolOptions(options.serverTools);
|
|
2441
2739
|
if (options.extraBody) {
|
|
2442
2740
|
const unsafe = Object.keys(options.extraBody).find((key) => SECURITY_SENSITIVE_EXTRA_BODY_FIELDS.has(key));
|
|
2443
2741
|
if (unsafe)
|
|
@@ -2600,8 +2898,14 @@ export {
|
|
|
2600
2898
|
openrouterMessages,
|
|
2601
2899
|
openrouter,
|
|
2602
2900
|
openRouterModelMatchesRule,
|
|
2603
|
-
|
|
2901
|
+
generateOpenRouterPKCE,
|
|
2902
|
+
exchangeOpenRouterAuthCode,
|
|
2903
|
+
estimateOpenRouterModelCost,
|
|
2904
|
+
estimateOpenRouterCost,
|
|
2905
|
+
createOpenRouterKeyLinks,
|
|
2906
|
+
createOpenRouterClient,
|
|
2907
|
+
createOpenRouterAuthorizationUrl
|
|
2604
2908
|
};
|
|
2605
2909
|
|
|
2606
|
-
//# debugId=
|
|
2910
|
+
//# debugId=438B311BAC94C67664756E2164756E21
|
|
2607
2911
|
//# sourceMappingURL=openrouter.js.map
|