@agentskit/adapters 0.12.0 → 0.13.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/catalog/index.cjs +153745 -0
- package/dist/catalog/index.cjs.map +1 -0
- package/dist/catalog/index.d.cts +205 -0
- package/dist/catalog/index.d.ts +205 -0
- package/dist/catalog/index.js +153479 -0
- package/dist/catalog/index.js.map +1 -0
- package/dist/chunk-6FPLWOVE.js +26 -0
- package/dist/chunk-6FPLWOVE.js.map +1 -0
- package/dist/chunk-726IKNNR.js +486 -0
- package/dist/chunk-726IKNNR.js.map +1 -0
- package/dist/createAdapter-Dfnf3Iio.d.cts +14 -0
- package/dist/createAdapter-Dfnf3Iio.d.ts +14 -0
- package/dist/createAdapter.cjs +28 -0
- package/dist/createAdapter.cjs.map +1 -0
- package/dist/createAdapter.d.cts +2 -0
- package/dist/createAdapter.d.ts +2 -0
- package/dist/createAdapter.js +3 -0
- package/dist/createAdapter.js.map +1 -0
- package/dist/index.cjs +297 -65
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +202 -77
- package/dist/index.d.ts +202 -77
- package/dist/index.js +277 -556
- package/dist/index.js.map +1 -1
- package/dist/utils-ddwu4MN4.d.cts +66 -0
- package/dist/utils-ddwu4MN4.d.ts +66 -0
- package/package.json +19 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"createAdapter.js"}
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var core = require('@agentskit/core');
|
|
4
|
+
|
|
3
5
|
// src/createAdapter.ts
|
|
4
6
|
function createAdapter(config) {
|
|
5
7
|
return {
|
|
@@ -399,8 +401,10 @@ function createStreamSource(doFetch, parse, errorLabel, retry) {
|
|
|
399
401
|
let abortController = new AbortController();
|
|
400
402
|
return {
|
|
401
403
|
stream: async function* () {
|
|
404
|
+
const controller = abortController;
|
|
405
|
+
if (!controller) return;
|
|
402
406
|
try {
|
|
403
|
-
const response = await fetchWithRetry(doFetch,
|
|
407
|
+
const response = await fetchWithRetry(doFetch, controller.signal, retry ?? {});
|
|
404
408
|
if (!response.ok || !response.body) {
|
|
405
409
|
yield { type: "error", content: `${errorLabel} error: ${response.status}` };
|
|
406
410
|
return;
|
|
@@ -440,8 +444,10 @@ function simulateStream(doFetch, extractText, errorLabel, options = {}) {
|
|
|
440
444
|
let abortController = new AbortController();
|
|
441
445
|
return {
|
|
442
446
|
stream: async function* () {
|
|
447
|
+
const controller = abortController;
|
|
448
|
+
if (!controller) return;
|
|
443
449
|
try {
|
|
444
|
-
const response = await fetchWithRetry(doFetch,
|
|
450
|
+
const response = await fetchWithRetry(doFetch, controller.signal, retry ?? {});
|
|
445
451
|
if (!response.ok) {
|
|
446
452
|
yield { type: "error", content: `${errorLabel} error: ${response.status}` };
|
|
447
453
|
return;
|
|
@@ -453,7 +459,7 @@ function simulateStream(doFetch, extractText, errorLabel, options = {}) {
|
|
|
453
459
|
if (delayMs > 0) {
|
|
454
460
|
await new Promise((resolve2, reject) => {
|
|
455
461
|
const timer = setTimeout(resolve2, delayMs);
|
|
456
|
-
|
|
462
|
+
controller.signal.addEventListener(
|
|
457
463
|
"abort",
|
|
458
464
|
() => {
|
|
459
465
|
clearTimeout(timer);
|
|
@@ -527,7 +533,14 @@ function anthropic(config) {
|
|
|
527
533
|
// src/openai.ts
|
|
528
534
|
function openai(config) {
|
|
529
535
|
const { apiKey, model, baseUrl = "https://api.openai.com", retry } = config;
|
|
530
|
-
const
|
|
536
|
+
const isCanonicalOpenAI = (() => {
|
|
537
|
+
try {
|
|
538
|
+
return new URL(baseUrl).host === "api.openai.com";
|
|
539
|
+
} catch {
|
|
540
|
+
return false;
|
|
541
|
+
}
|
|
542
|
+
})();
|
|
543
|
+
const includeUsage = config.includeUsage ?? isCanonicalOpenAI;
|
|
531
544
|
return {
|
|
532
545
|
capabilities: {
|
|
533
546
|
streaming: true,
|
|
@@ -584,15 +597,13 @@ function gemini(config) {
|
|
|
584
597
|
usage: true
|
|
585
598
|
},
|
|
586
599
|
createSource: (request) => {
|
|
600
|
+
const systemMessage = request.messages.find((message) => message.role === "system");
|
|
587
601
|
const body = {
|
|
588
602
|
contents: request.messages.filter((message) => message.role !== "system").map((message) => ({
|
|
589
603
|
role: message.role === "assistant" ? "model" : "user",
|
|
590
604
|
parts: [{ text: message.content }]
|
|
591
605
|
})),
|
|
592
|
-
systemInstruction:
|
|
593
|
-
role: "system",
|
|
594
|
-
parts: [{ text: request.messages.find((message) => message.role === "system").content }]
|
|
595
|
-
} : void 0
|
|
606
|
+
systemInstruction: systemMessage ? { role: "system", parts: [{ text: systemMessage.content }] } : void 0
|
|
596
607
|
};
|
|
597
608
|
return createStreamSource(
|
|
598
609
|
(signal) => fetch(
|
|
@@ -1058,15 +1069,13 @@ function vertex(config) {
|
|
|
1058
1069
|
reasoning: model.includes("pro")
|
|
1059
1070
|
},
|
|
1060
1071
|
createSource: (request) => {
|
|
1072
|
+
const systemMessage = request.messages.find((message) => message.role === "system");
|
|
1061
1073
|
const body = {
|
|
1062
1074
|
contents: request.messages.filter((message) => message.role !== "system").map((message) => ({
|
|
1063
1075
|
role: message.role === "assistant" ? "model" : "user",
|
|
1064
1076
|
parts: [{ text: message.content }]
|
|
1065
1077
|
})),
|
|
1066
|
-
systemInstruction:
|
|
1067
|
-
role: "system",
|
|
1068
|
-
parts: [{ text: request.messages.find((message) => message.role === "system").content }]
|
|
1069
|
-
} : void 0,
|
|
1078
|
+
systemInstruction: systemMessage ? { role: "system", parts: [{ text: systemMessage.content }] } : void 0,
|
|
1070
1079
|
tools: request.context?.tools && request.context.tools.length > 0 ? [{
|
|
1071
1080
|
functionDeclarations: request.context.tools.map((tool) => ({
|
|
1072
1081
|
name: tool.name,
|
|
@@ -1096,8 +1105,6 @@ function vertex(config) {
|
|
|
1096
1105
|
};
|
|
1097
1106
|
}
|
|
1098
1107
|
var vertexAdapter = vertex;
|
|
1099
|
-
|
|
1100
|
-
// src/bedrock.ts
|
|
1101
1108
|
var cachedSdk = null;
|
|
1102
1109
|
async function loadSdk() {
|
|
1103
1110
|
if (!cachedSdk) {
|
|
@@ -1109,9 +1116,11 @@ async function loadSdk() {
|
|
|
1109
1116
|
moduleId
|
|
1110
1117
|
);
|
|
1111
1118
|
} catch {
|
|
1112
|
-
throw new
|
|
1113
|
-
|
|
1114
|
-
|
|
1119
|
+
throw new core.AdapterError({
|
|
1120
|
+
code: core.ErrorCodes.AK_ADAPTER_MISSING,
|
|
1121
|
+
message: "Install @aws-sdk/client-bedrock-runtime to use the bedrock adapter: npm install @aws-sdk/client-bedrock-runtime",
|
|
1122
|
+
hint: "bedrock depends on the optional peer @aws-sdk/client-bedrock-runtime."
|
|
1123
|
+
});
|
|
1115
1124
|
}
|
|
1116
1125
|
})();
|
|
1117
1126
|
}
|
|
@@ -1212,9 +1221,11 @@ async function* parseAnthropicBedrockEvents(events) {
|
|
|
1212
1221
|
function bedrock(config) {
|
|
1213
1222
|
const { model, region, maxTokens = 4096 } = config;
|
|
1214
1223
|
if (!isAnthropicModel(model)) {
|
|
1215
|
-
throw new
|
|
1216
|
-
|
|
1217
|
-
|
|
1224
|
+
throw new core.ConfigError({
|
|
1225
|
+
code: core.ErrorCodes.AK_CONFIG_INVALID,
|
|
1226
|
+
message: `bedrock: model "${model}" is not supported in v1. Only anthropic.* models are wired up; Titan + others are tracked as a follow-up.`,
|
|
1227
|
+
hint: 'Pass an anthropic.* model id like "anthropic.claude-3-5-sonnet-20241022-v2:0".'
|
|
1228
|
+
});
|
|
1218
1229
|
}
|
|
1219
1230
|
let clientPromise = null;
|
|
1220
1231
|
const getClient = async () => {
|
|
@@ -1273,8 +1284,6 @@ function bedrock(config) {
|
|
|
1273
1284
|
};
|
|
1274
1285
|
}
|
|
1275
1286
|
var bedrockAdapter = bedrock;
|
|
1276
|
-
|
|
1277
|
-
// src/webllm.ts
|
|
1278
1287
|
var cachedSdk2 = null;
|
|
1279
1288
|
async function loadSdk2() {
|
|
1280
1289
|
if (!cachedSdk2) {
|
|
@@ -1286,7 +1295,11 @@ async function loadSdk2() {
|
|
|
1286
1295
|
moduleId
|
|
1287
1296
|
);
|
|
1288
1297
|
} catch {
|
|
1289
|
-
throw new
|
|
1298
|
+
throw new core.AdapterError({
|
|
1299
|
+
code: core.ErrorCodes.AK_ADAPTER_MISSING,
|
|
1300
|
+
message: "Install @mlc-ai/web-llm to use the webllm adapter: npm install @mlc-ai/web-llm",
|
|
1301
|
+
hint: "webllm is browser-only and depends on the optional peer @mlc-ai/web-llm."
|
|
1302
|
+
});
|
|
1290
1303
|
}
|
|
1291
1304
|
})();
|
|
1292
1305
|
}
|
|
@@ -1336,8 +1349,6 @@ function webllm(config) {
|
|
|
1336
1349
|
};
|
|
1337
1350
|
}
|
|
1338
1351
|
var webllmAdapter = webllm;
|
|
1339
|
-
|
|
1340
|
-
// src/router.ts
|
|
1341
1352
|
function requireCapabilities(request) {
|
|
1342
1353
|
const needs = {};
|
|
1343
1354
|
if (request.context?.tools && request.context.tools.length > 0) needs.tools = true;
|
|
@@ -1360,34 +1371,75 @@ function pickSyncPolicy(pool, policy) {
|
|
|
1360
1371
|
const c = pool.reduce((best, x) => (x.latencyMs ?? Infinity) < (best.latencyMs ?? Infinity) ? x : best, pool[0]);
|
|
1361
1372
|
return { c, reason: "fastest" };
|
|
1362
1373
|
}
|
|
1374
|
+
if (policy === "greenest") {
|
|
1375
|
+
const c = pool.reduce((best, x) => (x.gCO2PerKtok ?? Infinity) < (best.gCO2PerKtok ?? Infinity) ? x : best, pool[0]);
|
|
1376
|
+
return { c, reason: "greenest" };
|
|
1377
|
+
}
|
|
1378
|
+
if (policy === "green-cost") {
|
|
1379
|
+
const carbonValues = pool.map((p) => p.gCO2PerKtok).filter((v) => v != null);
|
|
1380
|
+
const costValues = pool.map((p) => p.cost).filter((v) => v != null);
|
|
1381
|
+
const maxC = Math.max(1, ...carbonValues);
|
|
1382
|
+
const maxCost = Math.max(1, ...costValues);
|
|
1383
|
+
const score = (x) => {
|
|
1384
|
+
const carbon = (x.gCO2PerKtok ?? maxC / 2) / maxC;
|
|
1385
|
+
const cost = (x.cost ?? maxCost / 2) / maxCost;
|
|
1386
|
+
return carbon + cost;
|
|
1387
|
+
};
|
|
1388
|
+
const c = pool.reduce((best, x) => score(x) < score(best) ? x : best, pool[0]);
|
|
1389
|
+
return { c, reason: "green-cost" };
|
|
1390
|
+
}
|
|
1363
1391
|
return { c: pool[0], reason: "capability-match" };
|
|
1364
1392
|
}
|
|
1393
|
+
function matchesRegion(candidate, region) {
|
|
1394
|
+
return region === void 0 || candidate.region === region;
|
|
1395
|
+
}
|
|
1365
1396
|
function createRouter(options) {
|
|
1366
1397
|
const { candidates } = options;
|
|
1367
|
-
if (candidates.length === 0)
|
|
1398
|
+
if (candidates.length === 0) {
|
|
1399
|
+
throw new core.ConfigError({
|
|
1400
|
+
code: core.ErrorCodes.AK_CONFIG_INVALID,
|
|
1401
|
+
message: "createRouter requires at least one candidate",
|
|
1402
|
+
hint: "Pass at least one candidate, e.g. createRouter({ candidates: [{ id, adapter, capabilities }] })."
|
|
1403
|
+
});
|
|
1404
|
+
}
|
|
1368
1405
|
const policy = options.policy ?? "cheapest";
|
|
1369
1406
|
return {
|
|
1370
1407
|
createSource: (request) => {
|
|
1371
1408
|
const need = requireCapabilities(request);
|
|
1409
|
+
const region = options.regionOf?.(request) ?? options.region;
|
|
1372
1410
|
const capable = candidates.filter((c2) => matchesCapabilities(need, c2.capabilities ?? c2.adapter.capabilities));
|
|
1411
|
+
const eligible = capable.filter((c2) => matchesRegion(c2, region));
|
|
1412
|
+
if (capable.length > 0 && eligible.length === 0 && region !== void 0) {
|
|
1413
|
+
throw new core.ConfigError({
|
|
1414
|
+
code: core.ErrorCodes.AK_CONFIG_INVALID,
|
|
1415
|
+
message: `no candidate satisfies required region: ${region}`,
|
|
1416
|
+
hint: "Set candidate.region to the requested data-residency region, or remove the router region requirement."
|
|
1417
|
+
});
|
|
1418
|
+
}
|
|
1373
1419
|
const classified = options.classify?.(request);
|
|
1374
1420
|
if (typeof classified === "string") {
|
|
1375
|
-
const c2 =
|
|
1421
|
+
const c2 = eligible.find((x) => x.id === classified);
|
|
1376
1422
|
if (c2) {
|
|
1377
|
-
options.onRoute?.({ id: c2.id, reason: "classify:id", request });
|
|
1423
|
+
options.onRoute?.({ id: c2.id, reason: region ? `classify:id:${region}` : "classify:id", request });
|
|
1378
1424
|
return c2.adapter.createSource(request);
|
|
1379
1425
|
}
|
|
1380
1426
|
}
|
|
1381
|
-
let pool =
|
|
1427
|
+
let pool = eligible;
|
|
1382
1428
|
let pickedBy;
|
|
1383
1429
|
if (Array.isArray(classified) && classified.length > 0) {
|
|
1384
|
-
const filtered =
|
|
1430
|
+
const filtered = eligible.filter((c2) => c2.tags && classified.every((t) => c2.tags.includes(t)));
|
|
1385
1431
|
if (filtered.length > 0) {
|
|
1386
1432
|
pool = filtered;
|
|
1387
|
-
pickedBy = "classify:tags";
|
|
1433
|
+
pickedBy = region ? `classify:tags:${region}` : "classify:tags";
|
|
1388
1434
|
}
|
|
1389
1435
|
}
|
|
1390
|
-
if (pool.length === 0)
|
|
1436
|
+
if (pool.length === 0) {
|
|
1437
|
+
throw new core.AdapterError({
|
|
1438
|
+
code: core.ErrorCodes.AK_ADAPTER_STREAM_FAILED,
|
|
1439
|
+
message: "no candidate satisfies the request",
|
|
1440
|
+
hint: "Ensure at least one candidate declares the required capabilities (tools, json, etc.)."
|
|
1441
|
+
});
|
|
1442
|
+
}
|
|
1391
1443
|
if (typeof policy === "function") {
|
|
1392
1444
|
const maybe = policy({ request, candidates: pool });
|
|
1393
1445
|
if (maybe instanceof Promise) {
|
|
@@ -1397,14 +1449,26 @@ function createRouter(options) {
|
|
|
1397
1449
|
stream: async function* () {
|
|
1398
1450
|
const id = await maybe;
|
|
1399
1451
|
const c3 = pool.find((x) => x.id === id);
|
|
1400
|
-
if (!c3)
|
|
1452
|
+
if (!c3) {
|
|
1453
|
+
throw new core.ConfigError({
|
|
1454
|
+
code: core.ErrorCodes.AK_CONFIG_INVALID,
|
|
1455
|
+
message: `policy returned unknown id: ${id}`,
|
|
1456
|
+
hint: "Custom policy functions must return one of the candidate ids."
|
|
1457
|
+
});
|
|
1458
|
+
}
|
|
1401
1459
|
options.onRoute?.({ id: c3.id, reason: pickedBy ?? "custom policy", request });
|
|
1402
1460
|
for await (const chunk of c3.adapter.createSource(request).stream()) yield chunk;
|
|
1403
1461
|
}
|
|
1404
1462
|
};
|
|
1405
1463
|
}
|
|
1406
1464
|
const c2 = pool.find((x) => x.id === maybe);
|
|
1407
|
-
if (!c2)
|
|
1465
|
+
if (!c2) {
|
|
1466
|
+
throw new core.ConfigError({
|
|
1467
|
+
code: core.ErrorCodes.AK_CONFIG_INVALID,
|
|
1468
|
+
message: `policy returned unknown id: ${maybe}`,
|
|
1469
|
+
hint: "Custom policy functions must return one of the candidate ids."
|
|
1470
|
+
});
|
|
1471
|
+
}
|
|
1408
1472
|
options.onRoute?.({ id: c2.id, reason: pickedBy ?? "custom policy", request });
|
|
1409
1473
|
return c2.adapter.createSource(request);
|
|
1410
1474
|
}
|
|
@@ -1415,7 +1479,56 @@ function createRouter(options) {
|
|
|
1415
1479
|
};
|
|
1416
1480
|
}
|
|
1417
1481
|
|
|
1418
|
-
// src/
|
|
1482
|
+
// src/carbon.ts
|
|
1483
|
+
var DEFAULT_CARBON_TABLE = {
|
|
1484
|
+
// Anthropic — primarily AWS us-east-* / eu-west-* via Bedrock-style fronts.
|
|
1485
|
+
"anthropic:us-east-1": 0.42,
|
|
1486
|
+
"anthropic:us-west-2": 0.18,
|
|
1487
|
+
"anthropic:eu-central-1": 0.32,
|
|
1488
|
+
"anthropic:eu-west-1": 0.27,
|
|
1489
|
+
// OpenAI — Azure East US / West Europe / Sweden Central.
|
|
1490
|
+
"openai:eastus": 0.4,
|
|
1491
|
+
"openai:westus3": 0.19,
|
|
1492
|
+
"openai:swedencentral": 0.04,
|
|
1493
|
+
"openai:westeurope": 0.28,
|
|
1494
|
+
// Google (Vertex / Gemini) — typically reports lowest PUE.
|
|
1495
|
+
"google:us-central1": 0.34,
|
|
1496
|
+
"google:us-west1": 0.16,
|
|
1497
|
+
"google:europe-west1": 0.21,
|
|
1498
|
+
"google:europe-north1": 0.05,
|
|
1499
|
+
// AWS Bedrock direct.
|
|
1500
|
+
"aws:us-east-1": 0.42,
|
|
1501
|
+
"aws:us-west-2": 0.18,
|
|
1502
|
+
"aws:eu-west-1": 0.27,
|
|
1503
|
+
// Local / on-device — only the device's grid matters.
|
|
1504
|
+
"ollama:local": 0.3,
|
|
1505
|
+
"webllm:browser": 0.3,
|
|
1506
|
+
"lmstudio:local": 0.3,
|
|
1507
|
+
// Self-hosted / community.
|
|
1508
|
+
"groq:us-east-1": 0.4,
|
|
1509
|
+
"fireworks:us-west-2": 0.18,
|
|
1510
|
+
"together:us-east-1": 0.42,
|
|
1511
|
+
"cerebras:us-west-2": 0.18
|
|
1512
|
+
};
|
|
1513
|
+
function defaultKey(candidate) {
|
|
1514
|
+
if (!candidate.region) return void 0;
|
|
1515
|
+
const provider = candidate.id.split(/[-:]/)[0];
|
|
1516
|
+
return `${provider}:${candidate.region}`;
|
|
1517
|
+
}
|
|
1518
|
+
function applyCarbonTable(candidates, options = {}) {
|
|
1519
|
+
const table = options.table ?? DEFAULT_CARBON_TABLE;
|
|
1520
|
+
const keyFor = options.keyFor ?? defaultKey;
|
|
1521
|
+
return candidates.map((c) => {
|
|
1522
|
+
if (c.gCO2PerKtok != null) return c;
|
|
1523
|
+
const key = keyFor(c);
|
|
1524
|
+
const value = key ? table[key] : void 0;
|
|
1525
|
+
return { ...c, gCO2PerKtok: value ?? options.fallback };
|
|
1526
|
+
});
|
|
1527
|
+
}
|
|
1528
|
+
function estimateCO2Grams(gCO2PerKtok, tokens) {
|
|
1529
|
+
if (gCO2PerKtok == null) return 0;
|
|
1530
|
+
return tokens / 1e3 * gCO2PerKtok;
|
|
1531
|
+
}
|
|
1419
1532
|
async function drain(source, timeoutMs) {
|
|
1420
1533
|
const chunks = [];
|
|
1421
1534
|
let text = "";
|
|
@@ -1460,7 +1573,11 @@ function majorityVote(branches, candidates) {
|
|
|
1460
1573
|
}
|
|
1461
1574
|
function createEnsembleAdapter(options) {
|
|
1462
1575
|
if (options.candidates.length === 0) {
|
|
1463
|
-
throw new
|
|
1576
|
+
throw new core.ConfigError({
|
|
1577
|
+
code: core.ErrorCodes.AK_CONFIG_INVALID,
|
|
1578
|
+
message: "createEnsembleAdapter requires at least one candidate",
|
|
1579
|
+
hint: "Pass at least one candidate, e.g. createEnsembleAdapter({ candidates: [{ id, adapter }] })."
|
|
1580
|
+
});
|
|
1464
1581
|
}
|
|
1465
1582
|
const aggregate = options.aggregate ?? "majority-vote";
|
|
1466
1583
|
return {
|
|
@@ -1500,7 +1617,14 @@ function createEnsembleAdapter(options) {
|
|
|
1500
1617
|
if (aborted) return;
|
|
1501
1618
|
const text = await finalText(branches);
|
|
1502
1619
|
if (!text && branches.every((b) => b.error)) {
|
|
1503
|
-
|
|
1620
|
+
const summary = branches.map((b) => `${b.id}: ${b.error?.message ?? "unknown"}`).join("; ");
|
|
1621
|
+
const err = new core.AdapterError({
|
|
1622
|
+
code: core.ErrorCodes.AK_ADAPTER_STREAM_FAILED,
|
|
1623
|
+
message: `all ensemble branches failed (${summary})`,
|
|
1624
|
+
hint: "Inspect each branch error via options.onBranches or the err.branchErrors field."
|
|
1625
|
+
});
|
|
1626
|
+
err.branchErrors = branches.map((b) => ({ id: b.id, error: b.error }));
|
|
1627
|
+
throw err;
|
|
1504
1628
|
}
|
|
1505
1629
|
yield { type: "text", content: text, metadata: { ensemble: branches.map((b) => ({ id: b.id, bytes: b.text.length, error: b.error?.message })) } };
|
|
1506
1630
|
yield { type: "done" };
|
|
@@ -1509,11 +1633,13 @@ function createEnsembleAdapter(options) {
|
|
|
1509
1633
|
}
|
|
1510
1634
|
};
|
|
1511
1635
|
}
|
|
1512
|
-
|
|
1513
|
-
// src/fallback.ts
|
|
1514
1636
|
function createFallbackAdapter(candidates, options = {}) {
|
|
1515
1637
|
if (candidates.length === 0) {
|
|
1516
|
-
throw new
|
|
1638
|
+
throw new core.ConfigError({
|
|
1639
|
+
code: core.ErrorCodes.AK_CONFIG_INVALID,
|
|
1640
|
+
message: "createFallbackAdapter requires at least one candidate",
|
|
1641
|
+
hint: 'Pass at least one candidate, e.g. createFallbackAdapter([{ id: "primary", adapter }]).'
|
|
1642
|
+
});
|
|
1517
1643
|
}
|
|
1518
1644
|
return {
|
|
1519
1645
|
createSource: (request) => {
|
|
@@ -1568,14 +1694,16 @@ function createFallbackAdapter(candidates, options = {}) {
|
|
|
1568
1694
|
}
|
|
1569
1695
|
}
|
|
1570
1696
|
const summary = errors.map((e) => `${e.id}: ${e.error.message}`).join("; ");
|
|
1571
|
-
throw new
|
|
1697
|
+
throw new core.AdapterError({
|
|
1698
|
+
code: core.ErrorCodes.AK_ADAPTER_STREAM_FAILED,
|
|
1699
|
+
message: `all fallback candidates failed (${summary})`,
|
|
1700
|
+
hint: "Check each candidate adapter's configuration and provider keys."
|
|
1701
|
+
});
|
|
1572
1702
|
}
|
|
1573
1703
|
};
|
|
1574
1704
|
}
|
|
1575
1705
|
};
|
|
1576
1706
|
}
|
|
1577
|
-
|
|
1578
|
-
// src/mock.ts
|
|
1579
1707
|
function mockAdapter(options) {
|
|
1580
1708
|
const { response, delayMs = 0, history } = options;
|
|
1581
1709
|
let callIndex = 0;
|
|
@@ -1660,21 +1788,34 @@ function inMemorySink() {
|
|
|
1660
1788
|
}
|
|
1661
1789
|
function replayAdapter(fixture) {
|
|
1662
1790
|
if (fixture.length === 0) {
|
|
1663
|
-
throw new
|
|
1791
|
+
throw new core.ConfigError({
|
|
1792
|
+
code: core.ErrorCodes.AK_CONFIG_INVALID,
|
|
1793
|
+
message: "replayAdapter: fixture is empty",
|
|
1794
|
+
hint: "Pass a non-empty fixture; record one with recordingAdapter() first."
|
|
1795
|
+
});
|
|
1664
1796
|
}
|
|
1665
1797
|
return mockAdapter({
|
|
1666
1798
|
response: fixture.map((turn) => turn.chunks)
|
|
1667
1799
|
});
|
|
1668
1800
|
}
|
|
1669
1801
|
|
|
1802
|
+
// src/embedders/shared.ts
|
|
1803
|
+
var ERROR_BODY_PREVIEW_CHARS = 200;
|
|
1804
|
+
async function throwIfNotOk(response, label, url) {
|
|
1805
|
+
if (response.ok) return;
|
|
1806
|
+
const body = await response.text().catch(() => "");
|
|
1807
|
+
throw new Error(
|
|
1808
|
+
`HTTP ${response.status} from ${label} ${url}: ${body.slice(0, ERROR_BODY_PREVIEW_CHARS)}`
|
|
1809
|
+
);
|
|
1810
|
+
}
|
|
1811
|
+
|
|
1670
1812
|
// src/embedders/openai.ts
|
|
1671
1813
|
async function fetchAvailableModels(baseUrl, apiKey) {
|
|
1672
|
-
const
|
|
1814
|
+
const url = `${baseUrl}/v1/models`;
|
|
1815
|
+
const response = await fetch(url, {
|
|
1673
1816
|
headers: { "Authorization": `Bearer ${apiKey}` }
|
|
1674
1817
|
});
|
|
1675
|
-
|
|
1676
|
-
throw new Error(`HTTP ${response.status}`);
|
|
1677
|
-
}
|
|
1818
|
+
await throwIfNotOk(response, "openai", url);
|
|
1678
1819
|
const data = await response.json();
|
|
1679
1820
|
return data.data.map((m) => m.id).filter((id) => id.includes("embed")).sort();
|
|
1680
1821
|
}
|
|
@@ -1714,10 +1855,9 @@ function openaiEmbedder(config) {
|
|
|
1714
1855
|
|
|
1715
1856
|
// src/embedders/gemini.ts
|
|
1716
1857
|
async function fetchAvailableModels2(baseUrl, apiKey) {
|
|
1717
|
-
const
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
}
|
|
1858
|
+
const url = `${baseUrl}/v1beta/models?key=${apiKey}`;
|
|
1859
|
+
const response = await fetch(url);
|
|
1860
|
+
await throwIfNotOk(response, "gemini", `${baseUrl}/v1beta/models`);
|
|
1721
1861
|
const data = await response.json();
|
|
1722
1862
|
return data.models.filter((m) => m.supportedGenerationMethods.includes("embedContent")).map((m) => m.name.replace("models/", "")).sort();
|
|
1723
1863
|
}
|
|
@@ -1764,10 +1904,9 @@ function geminiEmbedder(config) {
|
|
|
1764
1904
|
|
|
1765
1905
|
// src/embedders/ollama.ts
|
|
1766
1906
|
async function fetchAvailableModels3(baseUrl) {
|
|
1767
|
-
const
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
}
|
|
1907
|
+
const url = `${baseUrl}/api/tags`;
|
|
1908
|
+
const response = await fetch(url);
|
|
1909
|
+
await throwIfNotOk(response, "ollama", url);
|
|
1771
1910
|
const data = await response.json();
|
|
1772
1911
|
return data.models.map((m) => m.name).filter((name) => name.includes("embed")).sort();
|
|
1773
1912
|
}
|
|
@@ -1801,21 +1940,18 @@ function ollamaEmbedder(config) {
|
|
|
1801
1940
|
return data.embeddings[0];
|
|
1802
1941
|
};
|
|
1803
1942
|
}
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
const response = await fetch(`${baseUrl}/v1/models`, {
|
|
1943
|
+
async function fetchAvailableModels4(provider, baseUrl, apiKey) {
|
|
1944
|
+
const url = `${baseUrl}/v1/models`;
|
|
1945
|
+
const response = await fetch(url, {
|
|
1808
1946
|
headers: { "Authorization": `Bearer ${apiKey}` }
|
|
1809
1947
|
});
|
|
1810
|
-
|
|
1811
|
-
throw new Error(`HTTP ${response.status}`);
|
|
1812
|
-
}
|
|
1948
|
+
await throwIfNotOk(response, provider, url);
|
|
1813
1949
|
const data = await response.json();
|
|
1814
1950
|
return data.data.map((m) => m.id).filter((id) => id.includes("embed")).sort();
|
|
1815
1951
|
}
|
|
1816
1952
|
async function buildModelError4(provider, baseUrl, apiKey, originalError) {
|
|
1817
1953
|
try {
|
|
1818
|
-
const models = await fetchAvailableModels4(baseUrl, apiKey);
|
|
1954
|
+
const models = await fetchAvailableModels4(provider, baseUrl, apiKey);
|
|
1819
1955
|
const list = models.length > 0 ? models.join(", ") : "none found";
|
|
1820
1956
|
return new Error(
|
|
1821
1957
|
`${provider} embedding failed: ${originalError}. Available embedding models: ${list}`
|
|
@@ -1829,7 +1965,11 @@ async function buildModelError4(provider, baseUrl, apiKey, originalError) {
|
|
|
1829
1965
|
function createOpenAICompatibleEmbedder(provider, defaultBaseUrl) {
|
|
1830
1966
|
return function embedder(config) {
|
|
1831
1967
|
if (!config.model) {
|
|
1832
|
-
throw new
|
|
1968
|
+
throw new core.ConfigError({
|
|
1969
|
+
code: core.ErrorCodes.AK_CONFIG_INVALID,
|
|
1970
|
+
message: `Model is required for ${provider}. Pass { model: "<model-name>" }.`,
|
|
1971
|
+
hint: `${provider} does not infer a default; pick a recent embedding model and pass it explicitly.`
|
|
1972
|
+
});
|
|
1833
1973
|
}
|
|
1834
1974
|
const { apiKey, model, baseUrl = defaultBaseUrl } = config;
|
|
1835
1975
|
return async (text) => {
|
|
@@ -1860,8 +2000,95 @@ var grokEmbedder = createOpenAICompatibleEmbedder("Grok", "https://api.x.ai");
|
|
|
1860
2000
|
|
|
1861
2001
|
// src/embedders/kimi.ts
|
|
1862
2002
|
var kimiEmbedder = createOpenAICompatibleEmbedder("Kimi", "https://api.moonshot.ai");
|
|
2003
|
+
var DEFAULT_DEPRECATION_TABLE = [
|
|
2004
|
+
// OpenAI
|
|
2005
|
+
{ provider: "openai", model: "gpt-3.5-turbo-0301", successor: "gpt-4o-mini", sunsetOn: "2024-09-13" },
|
|
2006
|
+
{ provider: "openai", model: "gpt-3.5-turbo-0613", successor: "gpt-4o-mini", sunsetOn: "2024-09-13" },
|
|
2007
|
+
{ provider: "openai", model: "gpt-4-0314", successor: "gpt-4o", sunsetOn: "2024-06-13" },
|
|
2008
|
+
{ provider: "openai", model: "gpt-4-32k", successor: "gpt-4o", sunsetOn: "2024-06-06" },
|
|
2009
|
+
{ provider: "openai", model: "text-davinci-003", successor: "gpt-4o-mini", sunsetOn: "2024-01-04" },
|
|
2010
|
+
// Anthropic
|
|
2011
|
+
{ provider: "anthropic", model: "claude-2.0", successor: "claude-3-5-sonnet-latest", sunsetOn: "2025-07-21" },
|
|
2012
|
+
{ provider: "anthropic", model: "claude-2.1", successor: "claude-3-5-sonnet-latest", sunsetOn: "2025-07-21" },
|
|
2013
|
+
{ provider: "anthropic", model: "claude-instant-1.2", successor: "claude-3-5-haiku-latest", sunsetOn: "2024-07-22" },
|
|
2014
|
+
{ provider: "anthropic", model: "claude-3-sonnet-20240229", successor: "claude-3-5-sonnet-latest", sunsetOn: "2025-07-21" },
|
|
2015
|
+
// Google
|
|
2016
|
+
{ provider: "google", model: "gemini-1.0-pro", successor: "gemini-1.5-pro", sunsetOn: "2025-02-15" },
|
|
2017
|
+
{ provider: "google", model: "gemini-pro-vision", successor: "gemini-1.5-pro", sunsetOn: "2024-07-12" }
|
|
2018
|
+
];
|
|
2019
|
+
function resolveModel(input, policy) {
|
|
2020
|
+
const table = policy.table ?? DEFAULT_DEPRECATION_TABLE;
|
|
2021
|
+
const hit = table.find((d) => d.provider === input.provider && d.model === input.model);
|
|
2022
|
+
if (!hit) return { model: input.model, remapped: false };
|
|
2023
|
+
const log = policy.logger ?? ((msg) => console.warn(msg));
|
|
2024
|
+
const sunset = hit.sunsetOn ? ` (sunset ${hit.sunsetOn})` : "";
|
|
2025
|
+
const successor = hit.successor ? ` Suggested successor: ${hit.successor}.` : "";
|
|
2026
|
+
const base = `[agentskit] Model "${input.provider}:${input.model}" is deprecated${sunset}.${successor}`;
|
|
2027
|
+
switch (policy.onDeprecation) {
|
|
2028
|
+
case "fail":
|
|
2029
|
+
throw new core.ConfigError({
|
|
2030
|
+
code: core.ErrorCodes.AK_CONFIG_INVALID,
|
|
2031
|
+
message: base,
|
|
2032
|
+
hint: hit.successor ? `Set model to "${hit.successor}".` : "Pick a supported model from the provider."
|
|
2033
|
+
});
|
|
2034
|
+
case "remap": {
|
|
2035
|
+
if (!hit.successor) {
|
|
2036
|
+
throw new core.ConfigError({
|
|
2037
|
+
code: core.ErrorCodes.AK_CONFIG_INVALID,
|
|
2038
|
+
message: `${base} No successor available \u2014 cannot remap.`
|
|
2039
|
+
});
|
|
2040
|
+
}
|
|
2041
|
+
log(`${base} Auto-remapping to "${hit.successor}".`);
|
|
2042
|
+
return { model: hit.successor, remapped: true, deprecation: hit };
|
|
2043
|
+
}
|
|
2044
|
+
case "warn":
|
|
2045
|
+
default:
|
|
2046
|
+
log(base);
|
|
2047
|
+
return { model: input.model, remapped: false, deprecation: hit };
|
|
2048
|
+
}
|
|
2049
|
+
}
|
|
2050
|
+
function withDeprecationPolicy(factory, options) {
|
|
2051
|
+
resolveModel({ provider: options.provider, model: options.model }, options);
|
|
2052
|
+
return factory;
|
|
2053
|
+
}
|
|
2054
|
+
|
|
2055
|
+
// src/credential-rotation.ts
|
|
2056
|
+
function createRotatingCredentials(initial, options) {
|
|
2057
|
+
let value = initial;
|
|
2058
|
+
const handlers = /* @__PURE__ */ new Set();
|
|
2059
|
+
return {
|
|
2060
|
+
current: () => value,
|
|
2061
|
+
rotate: async (next) => {
|
|
2062
|
+
value = next;
|
|
2063
|
+
const event = {
|
|
2064
|
+
rotatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2065
|
+
id: options.id,
|
|
2066
|
+
fingerprint: next.slice(-4)
|
|
2067
|
+
};
|
|
2068
|
+
for (const h of handlers) h(event);
|
|
2069
|
+
return next;
|
|
2070
|
+
},
|
|
2071
|
+
onRotate: (handler) => {
|
|
2072
|
+
handlers.add(handler);
|
|
2073
|
+
return () => handlers.delete(handler);
|
|
2074
|
+
}
|
|
2075
|
+
};
|
|
2076
|
+
}
|
|
2077
|
+
async function refreshCredentials(adapter, next, options) {
|
|
2078
|
+
const log = options?.logger ?? ((msg) => console.log(msg));
|
|
2079
|
+
if (adapter && typeof adapter === "object" && "refreshCredentials" in adapter && typeof adapter.refreshCredentials === "function") {
|
|
2080
|
+
await adapter.refreshCredentials(next);
|
|
2081
|
+
log(`[agentskit] credentials refreshed${options?.id ? ` (${options.id})` : ""}`);
|
|
2082
|
+
return true;
|
|
2083
|
+
}
|
|
2084
|
+
log(`[agentskit] adapter does not support credential rotation; restart required${options?.id ? ` (${options.id})` : ""}`);
|
|
2085
|
+
return false;
|
|
2086
|
+
}
|
|
1863
2087
|
|
|
2088
|
+
exports.DEFAULT_CARBON_TABLE = DEFAULT_CARBON_TABLE;
|
|
2089
|
+
exports.DEFAULT_DEPRECATION_TABLE = DEFAULT_DEPRECATION_TABLE;
|
|
1864
2090
|
exports.anthropic = anthropic;
|
|
2091
|
+
exports.applyCarbonTable = applyCarbonTable;
|
|
1865
2092
|
exports.azureOpenAI = azureOpenAI;
|
|
1866
2093
|
exports.azureOpenAIAdapter = azureOpenAIAdapter;
|
|
1867
2094
|
exports.bail = bail;
|
|
@@ -1877,9 +2104,11 @@ exports.createAdapter = createAdapter;
|
|
|
1877
2104
|
exports.createEnsembleAdapter = createEnsembleAdapter;
|
|
1878
2105
|
exports.createFallbackAdapter = createFallbackAdapter;
|
|
1879
2106
|
exports.createOpenAICompatibleEmbedder = createOpenAICompatibleEmbedder;
|
|
2107
|
+
exports.createRotatingCredentials = createRotatingCredentials;
|
|
1880
2108
|
exports.createRouter = createRouter;
|
|
1881
2109
|
exports.deepseek = deepseek;
|
|
1882
2110
|
exports.deepseekEmbedder = deepseekEmbedder;
|
|
2111
|
+
exports.estimateCO2Grams = estimateCO2Grams;
|
|
1883
2112
|
exports.fetchWithRetry = fetchWithRetry;
|
|
1884
2113
|
exports.fireworks = fireworks;
|
|
1885
2114
|
exports.gemini = gemini;
|
|
@@ -1906,9 +2135,11 @@ exports.openaiEmbedder = openaiEmbedder;
|
|
|
1906
2135
|
exports.openrouter = openrouter;
|
|
1907
2136
|
exports.qwen = qwen;
|
|
1908
2137
|
exports.recordingAdapter = recordingAdapter;
|
|
2138
|
+
exports.refreshCredentials = refreshCredentials;
|
|
1909
2139
|
exports.replayAdapter = replayAdapter;
|
|
1910
2140
|
exports.replicate = replicate;
|
|
1911
2141
|
exports.replicateAdapter = replicateAdapter;
|
|
2142
|
+
exports.resolveModel = resolveModel;
|
|
1912
2143
|
exports.simulateStream = simulateStream;
|
|
1913
2144
|
exports.together = together;
|
|
1914
2145
|
exports.vercelAI = vercelAI;
|
|
@@ -1917,5 +2148,6 @@ exports.vertexAdapter = vertexAdapter;
|
|
|
1917
2148
|
exports.vllm = vllm;
|
|
1918
2149
|
exports.webllm = webllm;
|
|
1919
2150
|
exports.webllmAdapter = webllmAdapter;
|
|
2151
|
+
exports.withDeprecationPolicy = withDeprecationPolicy;
|
|
1920
2152
|
//# sourceMappingURL=index.cjs.map
|
|
1921
2153
|
//# sourceMappingURL=index.cjs.map
|