@absolutejs/ai 0.3.0 → 0.3.1
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/CHANGELOG.md +6 -0
- package/changelog.json +13 -0
- package/dist/ai/client/index.js +3 -1
- package/dist/ai/client/index.js.map +2 -2
- package/dist/ai/index.js +7740 -7712
- package/dist/ai/index.js.map +18 -18
- package/dist/ai/models/index.js +71 -1
- package/dist/ai/models/index.js.map +2 -2
- package/dist/ai/providers/anthropic.js +27 -25
- package/dist/ai/providers/anthropic.js.map +2 -2
- package/dist/ai/providers/gemini.js +13 -11
- package/dist/ai/providers/gemini.js.map +2 -2
- package/dist/ai/providers/ollama.js +5 -3
- package/dist/ai/providers/ollama.js.map +2 -2
- package/dist/ai/providers/openai.js +64 -41
- package/dist/ai/providers/openai.js.map +3 -3
- package/dist/ai/providers/openaiCompatible.js +82 -59
- package/dist/ai/providers/openaiCompatible.js.map +3 -3
- package/dist/ai/providers/openaiResponses.js +44 -21
- package/dist/ai/providers/openaiResponses.js.map +3 -3
- package/dist/ai/providers/openrouter.js +148 -125
- package/dist/ai/providers/openrouter.js.map +3 -3
- package/dist/ai/providers/openrouterSDK.js +3 -1
- package/dist/ai/providers/openrouterSDK.js.map +2 -2
- package/dist/ai/research.js +4 -2
- package/dist/ai/research.js.map +2 -2
- package/dist/ai/tools/index.js +58 -55
- package/dist/ai/tools/index.js.map +5 -5
- package/dist/ai/tools/untrusted.js +3 -1
- package/dist/ai/tools/untrusted.js.map +2 -2
- package/dist/ai/ui/index.js +72 -2
- package/dist/ai/ui/index.js.map +2 -2
- package/dist/angular/ai/index.js +1 -1
- package/dist/angular/ai/index.js.map +1 -1
- package/dist/react/ai/index.js +74 -4
- package/dist/react/ai/index.js.map +2 -2
- package/dist/svelte/ai/index.js +71 -1
- package/dist/svelte/ai/index.js.map +2 -2
- package/dist/vue/ai/index.js +71 -1
- package/dist/vue/ai/index.js.map +2 -2
- package/package.json +1 -1
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
var __require = import.meta.require;
|
|
3
|
+
|
|
2
4
|
// src/ai/inputCapacity.ts
|
|
3
5
|
class AIInputError extends Error {
|
|
4
6
|
code;
|
|
@@ -789,13 +791,13 @@ var compatibleReasoningBody = (provider, model, reasoning) => {
|
|
|
789
791
|
var geminiThinkingConfig = (model, reasoning) => {
|
|
790
792
|
if (!reasoning)
|
|
791
793
|
return;
|
|
792
|
-
const
|
|
794
|
+
const profile2 = getModelReasoning("google", model);
|
|
793
795
|
const effort = resolveEffort(reasoning);
|
|
794
|
-
if (!
|
|
796
|
+
if (!profile2 || !effort)
|
|
795
797
|
return;
|
|
796
|
-
if (!
|
|
798
|
+
if (!profile2.efforts.includes(effort))
|
|
797
799
|
throw new Error(`Unsupported reasoning effort ${effort} for ${model}`);
|
|
798
|
-
if (
|
|
800
|
+
if (profile2.kind === "effort")
|
|
799
801
|
return { thinkingLevel: effort };
|
|
800
802
|
const budgets = {
|
|
801
803
|
none: 0,
|
|
@@ -859,7 +861,7 @@ var convertToolBlock = (block) => {
|
|
|
859
861
|
}
|
|
860
862
|
if (block.type === "tool_use") {
|
|
861
863
|
if (block.providerData)
|
|
862
|
-
return
|
|
864
|
+
return Object.fromEntries(Object.entries(block.providerData).filter(([key]) => key !== "id"));
|
|
863
865
|
return {
|
|
864
866
|
arguments: typeof block.input === "string" ? block.input : JSON.stringify(block.input),
|
|
865
867
|
call_id: block.id,
|
|
@@ -897,10 +899,30 @@ var buildInput = (messages) => {
|
|
|
897
899
|
}
|
|
898
900
|
return input;
|
|
899
901
|
};
|
|
902
|
+
var isStrictCompatible = (schema) => {
|
|
903
|
+
if (Array.isArray(schema))
|
|
904
|
+
return schema.every(isStrictCompatible);
|
|
905
|
+
if (!isRecord(schema))
|
|
906
|
+
return true;
|
|
907
|
+
const { properties } = schema;
|
|
908
|
+
if (isRecord(properties)) {
|
|
909
|
+
const required = Array.isArray(schema.required) ? schema.required : [];
|
|
910
|
+
if (schema.additionalProperties !== false)
|
|
911
|
+
return false;
|
|
912
|
+
if (!Object.keys(properties).every((key) => required.includes(key)))
|
|
913
|
+
return false;
|
|
914
|
+
}
|
|
915
|
+
const nested = [schema.items, schema.anyOf];
|
|
916
|
+
for (const map of [properties, schema.$defs, schema.definitions])
|
|
917
|
+
if (isRecord(map))
|
|
918
|
+
nested.push(...Object.values(map));
|
|
919
|
+
return nested.every(isStrictCompatible);
|
|
920
|
+
};
|
|
900
921
|
var mapToolDefinition = (tool) => ({
|
|
901
922
|
description: tool.description,
|
|
902
923
|
name: tool.name,
|
|
903
924
|
parameters: tool.input_schema,
|
|
925
|
+
strict: isStrictCompatible(tool.input_schema),
|
|
904
926
|
type: "function"
|
|
905
927
|
});
|
|
906
928
|
var buildTools = (tools, isImageModel) => {
|
|
@@ -935,9 +957,10 @@ var buildResponsesRequestBody = (params, isImageModel, capabilityModel = params.
|
|
|
935
957
|
body.parallel_tool_calls = params.parallelToolCalls;
|
|
936
958
|
}
|
|
937
959
|
}
|
|
938
|
-
|
|
960
|
+
const samples = !isOpenAIReasoningModel(capabilityModel);
|
|
961
|
+
if (samples && typeof params.temperature === "number")
|
|
939
962
|
body.temperature = params.temperature;
|
|
940
|
-
if (typeof params.topP === "number")
|
|
963
|
+
if (samples && typeof params.topP === "number")
|
|
941
964
|
body.top_p = params.topP;
|
|
942
965
|
if (typeof params.maxTokens === "number")
|
|
943
966
|
body.max_output_tokens = params.maxTokens;
|
|
@@ -1312,31 +1335,31 @@ var resolveImageModels = (imageModels) => {
|
|
|
1312
1335
|
}
|
|
1313
1336
|
return new Set(imageModels);
|
|
1314
1337
|
};
|
|
1315
|
-
var openaiResponses = (
|
|
1316
|
-
if (!
|
|
1338
|
+
var openaiResponses = (config2) => {
|
|
1339
|
+
if (!config2.apiKey && !config2.tokenSource)
|
|
1317
1340
|
throw new Error("openaiResponses() requires either apiKey or tokenSource");
|
|
1318
|
-
const baseUrl =
|
|
1319
|
-
const fetchImpl =
|
|
1320
|
-
const imageModels = resolveImageModels(
|
|
1321
|
-
const providerName =
|
|
1322
|
-
const resolveKey = async () =>
|
|
1323
|
-
const resolveHeaders = async (params) => typeof
|
|
1341
|
+
const baseUrl = config2.baseUrl ?? DEFAULT_BASE_URL;
|
|
1342
|
+
const fetchImpl = config2.fetch ?? globalThis.fetch;
|
|
1343
|
+
const imageModels = resolveImageModels(config2.imageModels);
|
|
1344
|
+
const providerName = config2.providerName ?? "openai-responses";
|
|
1345
|
+
const resolveKey = async () => config2.tokenSource ? await Promise.resolve(config2.tokenSource()) : config2.apiKey;
|
|
1346
|
+
const resolveHeaders = async (params) => typeof config2.headers === "function" ? await config2.headers(params) : config2.headers ?? {};
|
|
1324
1347
|
return instrumentAIProvider({
|
|
1325
1348
|
inputCapacity: openaiInputCapacity({
|
|
1326
1349
|
baseUrl,
|
|
1327
1350
|
fetch: fetchImpl,
|
|
1328
1351
|
key: resolveKey,
|
|
1329
1352
|
headers: resolveHeaders,
|
|
1330
|
-
modelLimits:
|
|
1353
|
+
modelLimits: config2.modelLimits,
|
|
1331
1354
|
body: (params) => {
|
|
1332
|
-
const built = buildResponsesRequestBody(params, imageModels.has(params.model),
|
|
1333
|
-
return
|
|
1355
|
+
const built = buildResponsesRequestBody(params, imageModels.has(params.model), config2.modelForCapabilities?.(params.model) ?? params.model);
|
|
1356
|
+
return config2.transformRequestBody ? config2.transformRequestBody(built, params) : built;
|
|
1334
1357
|
}
|
|
1335
1358
|
}),
|
|
1336
1359
|
stream: (params) => {
|
|
1337
1360
|
const isImageModel = imageModels.has(params.model);
|
|
1338
|
-
const builtBody = buildResponsesRequestBody(params, isImageModel,
|
|
1339
|
-
const body =
|
|
1361
|
+
const builtBody = buildResponsesRequestBody(params, isImageModel, config2.modelForCapabilities?.(params.model) ?? params.model);
|
|
1362
|
+
const body = config2.transformRequestBody ? config2.transformRequestBody(builtBody, params) : builtBody;
|
|
1340
1363
|
return async function* () {
|
|
1341
1364
|
const [apiKey, headers] = await Promise.all([
|
|
1342
1365
|
resolveKey(),
|
|
@@ -1720,12 +1743,12 @@ var processSSELine2 = function* (line, pendingToolCalls, providerName) {
|
|
|
1720
1743
|
}
|
|
1721
1744
|
if (isRecord2(parsed.error)) {
|
|
1722
1745
|
const error = parsed.error;
|
|
1723
|
-
const
|
|
1746
|
+
const metadata2 = isRecord2(error.metadata) ? error.metadata : undefined;
|
|
1724
1747
|
const status = typeof error.code === "number" ? error.code : null;
|
|
1725
|
-
const type =
|
|
1748
|
+
const type = metadata2 && typeof metadata2.error_type === "string" ? metadata2.error_type : typeof error.error_type === "string" ? error.error_type : null;
|
|
1726
1749
|
throw new ProviderError({
|
|
1727
1750
|
message: typeof error.message === "string" ? error.message : "OpenRouter stream failed",
|
|
1728
|
-
metadata,
|
|
1751
|
+
metadata: metadata2,
|
|
1729
1752
|
provider: providerName,
|
|
1730
1753
|
retryable: status === 408 || status === 409 || status === 425 || status === 429 || status !== null && status >= 500,
|
|
1731
1754
|
status,
|
|
@@ -1750,15 +1773,15 @@ var processSSELine2 = function* (line, pendingToolCalls, providerName) {
|
|
|
1750
1773
|
}
|
|
1751
1774
|
if (isRecord2(firstChoice.error)) {
|
|
1752
1775
|
const error = firstChoice.error;
|
|
1753
|
-
const
|
|
1776
|
+
const metadata2 = isRecord2(error.metadata) ? error.metadata : undefined;
|
|
1754
1777
|
const status = typeof error.code === "number" ? error.code : null;
|
|
1755
1778
|
throw new ProviderError({
|
|
1756
1779
|
message: typeof error.message === "string" ? error.message : "OpenRouter stream failed",
|
|
1757
|
-
metadata,
|
|
1780
|
+
metadata: metadata2,
|
|
1758
1781
|
provider: providerName,
|
|
1759
1782
|
retryable: status === 429 || status !== null && status >= 500,
|
|
1760
1783
|
status,
|
|
1761
|
-
type:
|
|
1784
|
+
type: metadata2 && typeof metadata2.error_type === "string" ? metadata2.error_type : null
|
|
1762
1785
|
});
|
|
1763
1786
|
}
|
|
1764
1787
|
yield* processChoice(firstChoice, pendingToolCalls);
|
|
@@ -1857,32 +1880,32 @@ var fetchOpenAIStream = async function* (baseUrl, apiKey, body, fetchImpl, heade
|
|
|
1857
1880
|
}
|
|
1858
1881
|
}, providerName, signal);
|
|
1859
1882
|
};
|
|
1860
|
-
var openai = (
|
|
1861
|
-
const baseUrl =
|
|
1862
|
-
const fetchImpl =
|
|
1863
|
-
const providerName =
|
|
1864
|
-
if (!
|
|
1883
|
+
var openai = (config2) => {
|
|
1884
|
+
const baseUrl = config2.baseUrl ?? DEFAULT_BASE_URL2;
|
|
1885
|
+
const fetchImpl = config2.fetch ?? globalThis.fetch;
|
|
1886
|
+
const providerName = config2.providerName ?? "openai";
|
|
1887
|
+
if (!config2.apiKey && !config2.tokenSource) {
|
|
1865
1888
|
throw new Error("openai() requires either apiKey or tokenSource");
|
|
1866
1889
|
}
|
|
1867
1890
|
const resolveKey = async () => {
|
|
1868
|
-
if (
|
|
1869
|
-
return await Promise.resolve(
|
|
1891
|
+
if (config2.tokenSource) {
|
|
1892
|
+
return await Promise.resolve(config2.tokenSource());
|
|
1870
1893
|
}
|
|
1871
|
-
return
|
|
1894
|
+
return config2.apiKey;
|
|
1872
1895
|
};
|
|
1873
|
-
const resolveHeaders = async (params) => typeof
|
|
1896
|
+
const resolveHeaders = async (params) => typeof config2.headers === "function" ? await config2.headers(params) : config2.headers ?? {};
|
|
1874
1897
|
return instrumentAIProvider({
|
|
1875
|
-
inputCapacity:
|
|
1898
|
+
inputCapacity: config2.transformRequestBody ? undefined : openaiInputCapacity({
|
|
1876
1899
|
baseUrl,
|
|
1877
1900
|
fetch: fetchImpl,
|
|
1878
1901
|
key: resolveKey,
|
|
1879
1902
|
headers: resolveHeaders,
|
|
1880
|
-
modelLimits:
|
|
1881
|
-
body: (params) => buildResponsesRequestBody(params, false,
|
|
1903
|
+
modelLimits: config2.modelLimits,
|
|
1904
|
+
body: (params) => buildResponsesRequestBody(params, false, config2.modelForCapabilities?.(params.model) ?? params.model)
|
|
1882
1905
|
}),
|
|
1883
1906
|
stream: (params) => {
|
|
1884
|
-
const openaiBody = buildRequestBody(params,
|
|
1885
|
-
const body =
|
|
1907
|
+
const openaiBody = buildRequestBody(params, config2.modelForCapabilities?.(params.model) ?? params.model, providerName);
|
|
1908
|
+
const body = config2.transformRequestBody ? config2.transformRequestBody(openaiBody, params) : openaiBody;
|
|
1886
1909
|
return async function* () {
|
|
1887
1910
|
const [apiKey, headers] = await Promise.all([
|
|
1888
1911
|
resolveKey(),
|
|
@@ -2458,16 +2481,16 @@ async function* parseSSEStream3(body, providerName, signal) {
|
|
|
2458
2481
|
reader.releaseLock();
|
|
2459
2482
|
}
|
|
2460
2483
|
}
|
|
2461
|
-
var fetchAndStream = async function* (baseUrl,
|
|
2484
|
+
var fetchAndStream = async function* (baseUrl, config2, params, configuredMax, promptCaching, providerName) {
|
|
2462
2485
|
const builtBody = buildRequestBody2(params, configuredMax, promptCaching);
|
|
2463
|
-
const body =
|
|
2486
|
+
const body = config2.transformRequestBody ? config2.transformRequestBody(builtBody, params) : builtBody;
|
|
2464
2487
|
const target = `${baseUrl}/v1/messages`;
|
|
2465
|
-
const fetchImpl =
|
|
2466
|
-
const token =
|
|
2467
|
-
const suppliedHeaders = typeof
|
|
2488
|
+
const fetchImpl = config2.fetch ?? fetch;
|
|
2489
|
+
const token = config2.tokenSource ? await Promise.resolve(config2.tokenSource()) : config2.apiKey;
|
|
2490
|
+
const suppliedHeaders = typeof config2.headers === "function" ? await config2.headers(params) : config2.headers ?? {};
|
|
2468
2491
|
const requestHeaders = new Headers(suppliedHeaders);
|
|
2469
2492
|
requestHeaders.set("Content-Type", "application/json");
|
|
2470
|
-
if (
|
|
2493
|
+
if (config2.authStyle === "bearer") {
|
|
2471
2494
|
requestHeaders.set("Authorization", `Bearer ${token}`);
|
|
2472
2495
|
} else {
|
|
2473
2496
|
requestHeaders.set("anthropic-version", API_VERSION);
|
|
@@ -2493,24 +2516,24 @@ var fetchAndStream = async function* (baseUrl, config, params, configuredMax, pr
|
|
|
2493
2516
|
}
|
|
2494
2517
|
yield* parseSSEStream3(response.body, providerName, params.signal);
|
|
2495
2518
|
};
|
|
2496
|
-
var anthropic = (
|
|
2497
|
-
if (!
|
|
2519
|
+
var anthropic = (config2) => {
|
|
2520
|
+
if (!config2.apiKey && !config2.tokenSource)
|
|
2498
2521
|
throw new Error("anthropic() requires either apiKey or tokenSource");
|
|
2499
|
-
const baseUrl =
|
|
2500
|
-
const configuredMax =
|
|
2501
|
-
const promptCaching =
|
|
2502
|
-
const providerName =
|
|
2522
|
+
const baseUrl = config2.baseUrl ?? DEFAULT_BASE_URL3;
|
|
2523
|
+
const configuredMax = config2.maxTokens ?? DEFAULT_MAX_TOKENS;
|
|
2524
|
+
const promptCaching = config2.promptCaching ?? true;
|
|
2525
|
+
const providerName = config2.providerName ?? "anthropic";
|
|
2503
2526
|
const capacityRequest = async (params, path, body) => {
|
|
2504
|
-
const token =
|
|
2505
|
-
const headers = new Headers(typeof
|
|
2527
|
+
const token = config2.tokenSource ? await config2.tokenSource() : config2.apiKey;
|
|
2528
|
+
const headers = new Headers(typeof config2.headers === "function" ? await config2.headers(params) : config2.headers);
|
|
2506
2529
|
headers.set("Content-Type", "application/json");
|
|
2507
|
-
if (
|
|
2530
|
+
if (config2.authStyle === "bearer")
|
|
2508
2531
|
headers.set("Authorization", `Bearer ${token}`);
|
|
2509
2532
|
else {
|
|
2510
2533
|
headers.set("anthropic-version", API_VERSION);
|
|
2511
2534
|
headers.set("x-api-key", token);
|
|
2512
2535
|
}
|
|
2513
|
-
return capacityJson(await (
|
|
2536
|
+
return capacityJson(await (config2.fetch ?? fetch)(`${baseUrl}${path}`, {
|
|
2514
2537
|
method: body ? "POST" : "GET",
|
|
2515
2538
|
headers,
|
|
2516
2539
|
body: body ? JSON.stringify(body) : undefined,
|
|
@@ -2519,7 +2542,7 @@ var anthropic = (config) => {
|
|
|
2519
2542
|
};
|
|
2520
2543
|
const countingRequest = (params) => {
|
|
2521
2544
|
const built = buildRequestBody2(params, configuredMax, promptCaching);
|
|
2522
|
-
const body =
|
|
2545
|
+
const body = config2.transformRequestBody ? config2.transformRequestBody(built, params) : built;
|
|
2523
2546
|
const counted = {};
|
|
2524
2547
|
for (const key of [
|
|
2525
2548
|
"model",
|
|
@@ -2549,7 +2572,7 @@ var anthropic = (config) => {
|
|
|
2549
2572
|
const inputCapacity = {
|
|
2550
2573
|
outputTokens: (params) => {
|
|
2551
2574
|
const built = buildRequestBody2(params, configuredMax, promptCaching);
|
|
2552
|
-
const body =
|
|
2575
|
+
const body = config2.transformRequestBody ? config2.transformRequestBody(built, params) : built;
|
|
2553
2576
|
return positiveTokenLimit(body.max_tokens);
|
|
2554
2577
|
},
|
|
2555
2578
|
getLimits: cacheModelLimits(async (params) => {
|
|
@@ -2560,7 +2583,7 @@ var anthropic = (config) => {
|
|
|
2560
2583
|
contextWindowTokens: context,
|
|
2561
2584
|
maxOutputTokens: positiveTokenLimit(data.max_tokens)
|
|
2562
2585
|
};
|
|
2563
|
-
},
|
|
2586
|
+
}, config2.tokenSource || typeof config2.headers === "function" ? 0 : 300000),
|
|
2564
2587
|
countScope: (params) => countingRequest(params).scope,
|
|
2565
2588
|
countTokens: async (params) => {
|
|
2566
2589
|
const { counted } = countingRequest(params);
|
|
@@ -2569,7 +2592,7 @@ var anthropic = (config) => {
|
|
|
2569
2592
|
};
|
|
2570
2593
|
return instrumentAIProvider({
|
|
2571
2594
|
inputCapacity,
|
|
2572
|
-
stream: (params) => fetchAndStream(baseUrl,
|
|
2595
|
+
stream: (params) => fetchAndStream(baseUrl, config2, params, configuredMax, promptCaching, providerName)
|
|
2573
2596
|
}, providerName);
|
|
2574
2597
|
};
|
|
2575
2598
|
|
|
@@ -2760,8 +2783,8 @@ var constantTimeEqual = (left, right) => {
|
|
|
2760
2783
|
};
|
|
2761
2784
|
var verifyOpenRouterWebhookSignature = async (options) => {
|
|
2762
2785
|
const fields = new Map(options.header.split(",").map((part) => {
|
|
2763
|
-
const [
|
|
2764
|
-
return [
|
|
2786
|
+
const [key2, ...rest] = part.trim().split("=");
|
|
2787
|
+
return [key2, rest.join("=")];
|
|
2765
2788
|
}));
|
|
2766
2789
|
const timestamp = fields.get("t");
|
|
2767
2790
|
const supplied = fields.get("v1");
|
|
@@ -2782,17 +2805,17 @@ var verifyOpenRouterWebhookSignature = async (options) => {
|
|
|
2782
2805
|
const suppliedBytes = hexToBytes(supplied);
|
|
2783
2806
|
return suppliedBytes ? constantTimeEqual(expected, suppliedBytes) : false;
|
|
2784
2807
|
};
|
|
2785
|
-
var createOpenRouterClient = (
|
|
2786
|
-
if (!
|
|
2808
|
+
var createOpenRouterClient = (config2) => {
|
|
2809
|
+
if (!config2.apiKey && !config2.tokenSource)
|
|
2787
2810
|
throw new Error("createOpenRouterClient() requires either apiKey or tokenSource");
|
|
2788
|
-
const baseUrl = (
|
|
2789
|
-
const batchBaseUrl = (
|
|
2790
|
-
const fetchImpl =
|
|
2791
|
-
const allowedModels =
|
|
2792
|
-
const defaultWorkspaceId =
|
|
2811
|
+
const baseUrl = (config2.baseUrl ?? DEFAULT_BASE_URL4).replace(/\/$/, "");
|
|
2812
|
+
const batchBaseUrl = (config2.batchBaseUrl ?? (config2.baseUrl ? new URL("../beta", `${baseUrl}/`).toString() : DEFAULT_BATCH_BASE_URL)).replace(/\/$/, "");
|
|
2813
|
+
const fetchImpl = config2.fetch ?? globalThis.fetch;
|
|
2814
|
+
const allowedModels = config2.allowedModels ? [...config2.allowedModels] : undefined;
|
|
2815
|
+
const defaultWorkspaceId = config2.workspaceId;
|
|
2793
2816
|
const requestRawAt = async (rootUrl, path, options = {}) => {
|
|
2794
|
-
const token =
|
|
2795
|
-
const suppliedHeaders = typeof
|
|
2817
|
+
const token = config2.tokenSource ? await Promise.resolve(config2.tokenSource()) : config2.apiKey;
|
|
2818
|
+
const suppliedHeaders = typeof config2.headers === "function" ? await config2.headers() : config2.headers ?? {};
|
|
2796
2819
|
const headers = new Headers(suppliedHeaders);
|
|
2797
2820
|
new Headers(options.headers).forEach((value, key) => headers.set(key, value));
|
|
2798
2821
|
headers.set("Authorization", `Bearer ${token}`);
|
|
@@ -3097,20 +3120,20 @@ var assertNonEmptyPolicy = (label, value) => {
|
|
|
3097
3120
|
throw new Error(`openrouter() ${label} must not be empty`);
|
|
3098
3121
|
}
|
|
3099
3122
|
};
|
|
3100
|
-
var assertRoutingPolicy = (
|
|
3101
|
-
assertNonEmptyPolicy("allowedProviders",
|
|
3102
|
-
assertNonEmptyPolicy("routing.only",
|
|
3103
|
-
assertNonEmptyPolicy("allowedPresets",
|
|
3104
|
-
if (
|
|
3123
|
+
var assertRoutingPolicy = (config2) => {
|
|
3124
|
+
assertNonEmptyPolicy("allowedProviders", config2.allowedProviders);
|
|
3125
|
+
assertNonEmptyPolicy("routing.only", config2.routing?.only);
|
|
3126
|
+
assertNonEmptyPolicy("allowedPresets", config2.allowedPresets);
|
|
3127
|
+
if (config2.appCategories && config2.appCategories.length > MAX_APP_CATEGORIES) {
|
|
3105
3128
|
throw new Error("openrouter() appCategories supports at most 2 entries");
|
|
3106
3129
|
}
|
|
3107
|
-
if (!
|
|
3130
|
+
if (!config2.allowedProviders)
|
|
3108
3131
|
return;
|
|
3109
3132
|
const selected = [
|
|
3110
|
-
...
|
|
3111
|
-
...
|
|
3133
|
+
...config2.routing?.only ?? [],
|
|
3134
|
+
...config2.routing?.order ?? []
|
|
3112
3135
|
];
|
|
3113
|
-
const denied = selected.find((provider) => !
|
|
3136
|
+
const denied = selected.find((provider) => !config2.allowedProviders.some((rule) => providerMatchesRule(provider, rule)));
|
|
3114
3137
|
if (denied) {
|
|
3115
3138
|
throw new Error(`openrouter() provider "${denied}" is outside allowedProviders`);
|
|
3116
3139
|
}
|
|
@@ -3163,17 +3186,17 @@ var requestOptionsFor2 = (params, defaults) => {
|
|
|
3163
3186
|
...supplied
|
|
3164
3187
|
};
|
|
3165
3188
|
};
|
|
3166
|
-
var resolveAttributionHeaders = async (
|
|
3167
|
-
const supplied = typeof
|
|
3189
|
+
var resolveAttributionHeaders = async (config2, params) => {
|
|
3190
|
+
const supplied = typeof config2.headers === "function" ? await config2.headers() : config2.headers ?? {};
|
|
3168
3191
|
const headers = new Headers(supplied);
|
|
3169
|
-
if (
|
|
3170
|
-
headers.set("HTTP-Referer",
|
|
3171
|
-
if (
|
|
3172
|
-
headers.set("X-OpenRouter-Title",
|
|
3173
|
-
if (
|
|
3174
|
-
headers.set("X-OpenRouter-Categories",
|
|
3175
|
-
}
|
|
3176
|
-
const options = requestOptionsFor2(params,
|
|
3192
|
+
if (config2.appUrl)
|
|
3193
|
+
headers.set("HTTP-Referer", config2.appUrl);
|
|
3194
|
+
if (config2.appName)
|
|
3195
|
+
headers.set("X-OpenRouter-Title", config2.appName);
|
|
3196
|
+
if (config2.appCategories?.length) {
|
|
3197
|
+
headers.set("X-OpenRouter-Categories", config2.appCategories.join(","));
|
|
3198
|
+
}
|
|
3199
|
+
const options = requestOptionsFor2(params, config2.requestOptions);
|
|
3177
3200
|
if (options.routerMetadata ?? true)
|
|
3178
3201
|
headers.set("X-OpenRouter-Metadata", "enabled");
|
|
3179
3202
|
if (options.sessionId)
|
|
@@ -3333,13 +3356,13 @@ var assertAllowedModel2 = (model, allowedModels) => {
|
|
|
3333
3356
|
return;
|
|
3334
3357
|
throw new Error(`OpenRouter model "${model}" is not allowed`);
|
|
3335
3358
|
};
|
|
3336
|
-
var snapshotPolicy = (
|
|
3337
|
-
allowedModels:
|
|
3338
|
-
allowedPresets:
|
|
3359
|
+
var snapshotPolicy = (config2) => ({
|
|
3360
|
+
allowedModels: config2.allowedModels ? [...config2.allowedModels] : undefined,
|
|
3361
|
+
allowedPresets: config2.allowedPresets ? [...config2.allowedPresets] : undefined
|
|
3339
3362
|
});
|
|
3340
|
-
var transformOpenRouterRequest = (
|
|
3341
|
-
const options = requestOptionsFor2(params,
|
|
3342
|
-
assertRequestOptions(options, allowedModels, allowedPresets,
|
|
3363
|
+
var transformOpenRouterRequest = (config2, allowedModels, allowedPresets, body, params, skin = "openai") => {
|
|
3364
|
+
const options = requestOptionsFor2(params, config2.requestOptions);
|
|
3365
|
+
assertRequestOptions(options, allowedModels, allowedPresets, config2.allowedProviders);
|
|
3343
3366
|
const transformed = { ...body, ...options.extraBody };
|
|
3344
3367
|
if (options.audioOutput) {
|
|
3345
3368
|
transformed.audio = options.audioOutput;
|
|
@@ -3372,7 +3395,7 @@ var transformOpenRouterRequest = (config, allowedModels, allowedPresets, body, p
|
|
|
3372
3395
|
transformed.prompt_cache_key = options.promptCacheKey;
|
|
3373
3396
|
if (options.promptCacheOptions)
|
|
3374
3397
|
transformed.prompt_cache_options = options.promptCacheOptions;
|
|
3375
|
-
const routing = mapRouting({ ...
|
|
3398
|
+
const routing = mapRouting({ ...config2.routing, ...options.routing }, config2.allowedProviders);
|
|
3376
3399
|
if (Object.keys(routing).length > 0)
|
|
3377
3400
|
transformed.provider = routing;
|
|
3378
3401
|
if (options.fallbackModels)
|
|
@@ -3431,48 +3454,48 @@ var withOpenRouterPolicy = (provider, allowedModels, allowedPresets) => ({
|
|
|
3431
3454
|
return provider.stream(params);
|
|
3432
3455
|
}
|
|
3433
3456
|
});
|
|
3434
|
-
var openrouter = (
|
|
3435
|
-
assertRoutingPolicy(
|
|
3436
|
-
const { allowedModels, allowedPresets } = snapshotPolicy(
|
|
3457
|
+
var openrouter = (config2) => {
|
|
3458
|
+
assertRoutingPolicy(config2);
|
|
3459
|
+
const { allowedModels, allowedPresets } = snapshotPolicy(config2);
|
|
3437
3460
|
const provider = openai({
|
|
3438
|
-
apiKey:
|
|
3439
|
-
baseUrl:
|
|
3440
|
-
fetch:
|
|
3441
|
-
headers: (params) => resolveAttributionHeaders(
|
|
3461
|
+
apiKey: config2.apiKey,
|
|
3462
|
+
baseUrl: config2.baseUrl ?? DEFAULT_BASE_URL5,
|
|
3463
|
+
fetch: config2.fetch,
|
|
3464
|
+
headers: (params) => resolveAttributionHeaders(config2, params),
|
|
3442
3465
|
modelForCapabilities: modelForOpenAICapabilities,
|
|
3443
3466
|
providerName: "openrouter",
|
|
3444
|
-
tokenSource:
|
|
3445
|
-
transformRequestBody: (body, params) => transformOpenRouterRequest(
|
|
3467
|
+
tokenSource: config2.tokenSource,
|
|
3468
|
+
transformRequestBody: (body, params) => transformOpenRouterRequest(config2, allowedModels, allowedPresets, body, params)
|
|
3446
3469
|
});
|
|
3447
3470
|
return withOpenRouterPolicy(provider, allowedModels, allowedPresets);
|
|
3448
3471
|
};
|
|
3449
|
-
var openrouterResponses = (
|
|
3450
|
-
assertRoutingPolicy(
|
|
3451
|
-
const { allowedModels, allowedPresets } = snapshotPolicy(
|
|
3472
|
+
var openrouterResponses = (config2) => {
|
|
3473
|
+
assertRoutingPolicy(config2);
|
|
3474
|
+
const { allowedModels, allowedPresets } = snapshotPolicy(config2);
|
|
3452
3475
|
const provider = openaiResponses({
|
|
3453
|
-
apiKey:
|
|
3454
|
-
baseUrl:
|
|
3455
|
-
fetch:
|
|
3456
|
-
headers: (params) => resolveAttributionHeaders(
|
|
3476
|
+
apiKey: config2.apiKey,
|
|
3477
|
+
baseUrl: config2.baseUrl ?? DEFAULT_BASE_URL5,
|
|
3478
|
+
fetch: config2.fetch,
|
|
3479
|
+
headers: (params) => resolveAttributionHeaders(config2, params),
|
|
3457
3480
|
modelForCapabilities: modelForOpenAICapabilities,
|
|
3458
3481
|
providerName: "openrouter",
|
|
3459
|
-
tokenSource:
|
|
3460
|
-
transformRequestBody: (body, params) => transformOpenRouterRequest(
|
|
3482
|
+
tokenSource: config2.tokenSource,
|
|
3483
|
+
transformRequestBody: (body, params) => transformOpenRouterRequest(config2, allowedModels, allowedPresets, body, params)
|
|
3461
3484
|
});
|
|
3462
3485
|
return withOpenRouterPolicy(provider, allowedModels, allowedPresets);
|
|
3463
3486
|
};
|
|
3464
|
-
var openrouterMessages = (
|
|
3465
|
-
assertRoutingPolicy(
|
|
3466
|
-
const { allowedModels, allowedPresets } = snapshotPolicy(
|
|
3487
|
+
var openrouterMessages = (config2) => {
|
|
3488
|
+
assertRoutingPolicy(config2);
|
|
3489
|
+
const { allowedModels, allowedPresets } = snapshotPolicy(config2);
|
|
3467
3490
|
const provider = anthropic({
|
|
3468
|
-
apiKey:
|
|
3491
|
+
apiKey: config2.apiKey,
|
|
3469
3492
|
authStyle: "bearer",
|
|
3470
|
-
baseUrl:
|
|
3471
|
-
fetch:
|
|
3472
|
-
headers: (params) => resolveAttributionHeaders(
|
|
3493
|
+
baseUrl: config2.baseUrl ?? DEFAULT_BASE_URL5,
|
|
3494
|
+
fetch: config2.fetch,
|
|
3495
|
+
headers: (params) => resolveAttributionHeaders(config2, params),
|
|
3473
3496
|
providerName: "openrouter",
|
|
3474
|
-
tokenSource:
|
|
3475
|
-
transformRequestBody: (body, params) => transformOpenRouterRequest(
|
|
3497
|
+
tokenSource: config2.tokenSource,
|
|
3498
|
+
transformRequestBody: (body, params) => transformOpenRouterRequest(config2, allowedModels, allowedPresets, body, params, "messages")
|
|
3476
3499
|
});
|
|
3477
3500
|
return withOpenRouterPolicy(provider, allowedModels, allowedPresets);
|
|
3478
3501
|
};
|
|
@@ -3491,5 +3514,5 @@ export {
|
|
|
3491
3514
|
verifyOpenRouterWebhookSignature
|
|
3492
3515
|
};
|
|
3493
3516
|
|
|
3494
|
-
//# debugId=
|
|
3517
|
+
//# debugId=92C500CDC8976E3264756E2164756E21
|
|
3495
3518
|
//# sourceMappingURL=openrouter.js.map
|