@agentskit/adapters 0.12.2 → 0.13.2

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/createAdapter.ts"],"names":[],"mappings":";;;AAGO,SAAS,cAAc,MAAA,EAA6C;AACzE,EAAA,OAAO;AAAA,IACL,YAAA,EAAc,CAAC,OAAA,MAA2C;AAAA,MACxD,QAAQ,mBAAuD;AAC7D,QAAA,IAAI;AACF,UAAA,MAAM,MAAA,GAAS,MAAM,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA;AACxC,UAAA,MAAM,MAAA,GAAS,MAAA,YAAkB,QAAA,GAC7B,MAAA,CAAO,IAAA,GACP,MAAA;AACJ,UAAA,OAAO,MAAA,CAAO,MAAM,MAAM,CAAA;AAAA,QAC5B,SAAS,GAAA,EAAK;AACZ,UAAA,MAAM;AAAA,YACJ,IAAA,EAAM,OAAA;AAAA,YACN,SAAS,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG;AAAA,WAC1D;AAAA,QACF;AAAA,MACF,CAAA;AAAA,MACA,OAAO,MAAM;AACX,QAAA,MAAA,CAAO,KAAA,IAAQ;AAAA,MACjB;AAAA,KACF;AAAA,GACF;AACF","file":"createAdapter.cjs","sourcesContent":["import type { AdapterFactory, AdapterRequest, StreamChunk, StreamSource } from '@agentskit/core'\nimport type { CreateAdapterConfig } from './types'\n\nexport function createAdapter(config: CreateAdapterConfig): AdapterFactory {\n return {\n createSource: (request: AdapterRequest): StreamSource => ({\n stream: async function* (): AsyncIterableIterator<StreamChunk> {\n try {\n const result = await config.send(request)\n const stream = result instanceof Response\n ? result.body!\n : result\n yield* config.parse(stream)\n } catch (err) {\n yield {\n type: 'error',\n content: err instanceof Error ? err.message : String(err),\n }\n }\n },\n abort: () => {\n config.abort?.()\n },\n }),\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import '@agentskit/core';
2
+ export { c as createAdapter } from './createAdapter-Dfnf3Iio.cjs';
@@ -0,0 +1,2 @@
1
+ import '@agentskit/core';
2
+ export { c as createAdapter } from './createAdapter-Dfnf3Iio.js';
@@ -0,0 +1,3 @@
1
+ export { createAdapter } from './chunk-6FPLWOVE.js';
2
+ //# sourceMappingURL=createAdapter.js.map
3
+ //# sourceMappingURL=createAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"createAdapter.js"}
package/dist/index.cjs CHANGED
@@ -401,8 +401,10 @@ function createStreamSource(doFetch, parse, errorLabel, retry) {
401
401
  let abortController = new AbortController();
402
402
  return {
403
403
  stream: async function* () {
404
+ const controller = abortController;
405
+ if (!controller) return;
404
406
  try {
405
- const response = await fetchWithRetry(doFetch, abortController.signal, retry ?? {});
407
+ const response = await fetchWithRetry(doFetch, controller.signal, retry ?? {});
406
408
  if (!response.ok || !response.body) {
407
409
  yield { type: "error", content: `${errorLabel} error: ${response.status}` };
408
410
  return;
@@ -442,8 +444,10 @@ function simulateStream(doFetch, extractText, errorLabel, options = {}) {
442
444
  let abortController = new AbortController();
443
445
  return {
444
446
  stream: async function* () {
447
+ const controller = abortController;
448
+ if (!controller) return;
445
449
  try {
446
- const response = await fetchWithRetry(doFetch, abortController.signal, retry ?? {});
450
+ const response = await fetchWithRetry(doFetch, controller.signal, retry ?? {});
447
451
  if (!response.ok) {
448
452
  yield { type: "error", content: `${errorLabel} error: ${response.status}` };
449
453
  return;
@@ -455,7 +459,7 @@ function simulateStream(doFetch, extractText, errorLabel, options = {}) {
455
459
  if (delayMs > 0) {
456
460
  await new Promise((resolve2, reject) => {
457
461
  const timer = setTimeout(resolve2, delayMs);
458
- abortController?.signal.addEventListener(
462
+ controller.signal.addEventListener(
459
463
  "abort",
460
464
  () => {
461
465
  clearTimeout(timer);
@@ -529,7 +533,15 @@ function anthropic(config) {
529
533
  // src/openai.ts
530
534
  function openai(config) {
531
535
  const { apiKey, model, baseUrl = "https://api.openai.com", retry } = config;
532
- const includeUsage = config.includeUsage ?? baseUrl.startsWith("https://api.openai.com");
536
+ const apiRoot = baseUrl.replace(/\/v1\/?$/, "");
537
+ const isCanonicalOpenAI = (() => {
538
+ try {
539
+ return new URL(baseUrl).host === "api.openai.com";
540
+ } catch {
541
+ return false;
542
+ }
543
+ })();
544
+ const includeUsage = config.includeUsage ?? isCanonicalOpenAI;
533
545
  return {
534
546
  capabilities: {
535
547
  streaming: true,
@@ -558,7 +570,7 @@ function openai(config) {
558
570
  };
559
571
  if (includeUsage) body.stream_options = { include_usage: true };
560
572
  return createStreamSource(
561
- (signal) => fetch(`${baseUrl}/v1/chat/completions`, {
573
+ (signal) => fetch(`${apiRoot}/v1/chat/completions`, {
562
574
  method: "POST",
563
575
  headers: {
564
576
  "Content-Type": "application/json",
@@ -586,15 +598,13 @@ function gemini(config) {
586
598
  usage: true
587
599
  },
588
600
  createSource: (request) => {
601
+ const systemMessage = request.messages.find((message) => message.role === "system");
589
602
  const body = {
590
603
  contents: request.messages.filter((message) => message.role !== "system").map((message) => ({
591
604
  role: message.role === "assistant" ? "model" : "user",
592
605
  parts: [{ text: message.content }]
593
606
  })),
594
- systemInstruction: request.messages.find((message) => message.role === "system") ? {
595
- role: "system",
596
- parts: [{ text: request.messages.find((message) => message.role === "system").content }]
597
- } : void 0
607
+ systemInstruction: systemMessage ? { role: "system", parts: [{ text: systemMessage.content }] } : void 0
598
608
  };
599
609
  return createStreamSource(
600
610
  (signal) => fetch(
@@ -1060,15 +1070,13 @@ function vertex(config) {
1060
1070
  reasoning: model.includes("pro")
1061
1071
  },
1062
1072
  createSource: (request) => {
1073
+ const systemMessage = request.messages.find((message) => message.role === "system");
1063
1074
  const body = {
1064
1075
  contents: request.messages.filter((message) => message.role !== "system").map((message) => ({
1065
1076
  role: message.role === "assistant" ? "model" : "user",
1066
1077
  parts: [{ text: message.content }]
1067
1078
  })),
1068
- systemInstruction: request.messages.find((message) => message.role === "system") ? {
1069
- role: "system",
1070
- parts: [{ text: request.messages.find((message) => message.role === "system").content }]
1071
- } : void 0,
1079
+ systemInstruction: systemMessage ? { role: "system", parts: [{ text: systemMessage.content }] } : void 0,
1072
1080
  tools: request.context?.tools && request.context.tools.length > 0 ? [{
1073
1081
  functionDeclarations: request.context.tools.map((tool) => ({
1074
1082
  name: tool.name,
@@ -1364,8 +1372,28 @@ function pickSyncPolicy(pool, policy) {
1364
1372
  const c = pool.reduce((best, x) => (x.latencyMs ?? Infinity) < (best.latencyMs ?? Infinity) ? x : best, pool[0]);
1365
1373
  return { c, reason: "fastest" };
1366
1374
  }
1375
+ if (policy === "greenest") {
1376
+ const c = pool.reduce((best, x) => (x.gCO2PerKtok ?? Infinity) < (best.gCO2PerKtok ?? Infinity) ? x : best, pool[0]);
1377
+ return { c, reason: "greenest" };
1378
+ }
1379
+ if (policy === "green-cost") {
1380
+ const carbonValues = pool.map((p) => p.gCO2PerKtok).filter((v) => v != null);
1381
+ const costValues = pool.map((p) => p.cost).filter((v) => v != null);
1382
+ const maxC = Math.max(1, ...carbonValues);
1383
+ const maxCost = Math.max(1, ...costValues);
1384
+ const score = (x) => {
1385
+ const carbon = (x.gCO2PerKtok ?? maxC / 2) / maxC;
1386
+ const cost = (x.cost ?? maxCost / 2) / maxCost;
1387
+ return carbon + cost;
1388
+ };
1389
+ const c = pool.reduce((best, x) => score(x) < score(best) ? x : best, pool[0]);
1390
+ return { c, reason: "green-cost" };
1391
+ }
1367
1392
  return { c: pool[0], reason: "capability-match" };
1368
1393
  }
1394
+ function matchesRegion(candidate, region) {
1395
+ return region === void 0 || candidate.region === region;
1396
+ }
1369
1397
  function createRouter(options) {
1370
1398
  const { candidates } = options;
1371
1399
  if (candidates.length === 0) {
@@ -1379,22 +1407,31 @@ function createRouter(options) {
1379
1407
  return {
1380
1408
  createSource: (request) => {
1381
1409
  const need = requireCapabilities(request);
1410
+ const region = options.regionOf?.(request) ?? options.region;
1382
1411
  const capable = candidates.filter((c2) => matchesCapabilities(need, c2.capabilities ?? c2.adapter.capabilities));
1412
+ const eligible = capable.filter((c2) => matchesRegion(c2, region));
1413
+ if (capable.length > 0 && eligible.length === 0 && region !== void 0) {
1414
+ throw new core.ConfigError({
1415
+ code: core.ErrorCodes.AK_CONFIG_INVALID,
1416
+ message: `no candidate satisfies required region: ${region}`,
1417
+ hint: "Set candidate.region to the requested data-residency region, or remove the router region requirement."
1418
+ });
1419
+ }
1383
1420
  const classified = options.classify?.(request);
1384
1421
  if (typeof classified === "string") {
1385
- const c2 = capable.find((x) => x.id === classified);
1422
+ const c2 = eligible.find((x) => x.id === classified);
1386
1423
  if (c2) {
1387
- options.onRoute?.({ id: c2.id, reason: "classify:id", request });
1424
+ options.onRoute?.({ id: c2.id, reason: region ? `classify:id:${region}` : "classify:id", request });
1388
1425
  return c2.adapter.createSource(request);
1389
1426
  }
1390
1427
  }
1391
- let pool = capable;
1428
+ let pool = eligible;
1392
1429
  let pickedBy;
1393
1430
  if (Array.isArray(classified) && classified.length > 0) {
1394
- const filtered = capable.filter((c2) => c2.tags && classified.every((t) => c2.tags.includes(t)));
1431
+ const filtered = eligible.filter((c2) => c2.tags && classified.every((t) => c2.tags.includes(t)));
1395
1432
  if (filtered.length > 0) {
1396
1433
  pool = filtered;
1397
- pickedBy = "classify:tags";
1434
+ pickedBy = region ? `classify:tags:${region}` : "classify:tags";
1398
1435
  }
1399
1436
  }
1400
1437
  if (pool.length === 0) {
@@ -1442,6 +1479,57 @@ function createRouter(options) {
1442
1479
  }
1443
1480
  };
1444
1481
  }
1482
+
1483
+ // src/carbon.ts
1484
+ var DEFAULT_CARBON_TABLE = {
1485
+ // Anthropic — primarily AWS us-east-* / eu-west-* via Bedrock-style fronts.
1486
+ "anthropic:us-east-1": 0.42,
1487
+ "anthropic:us-west-2": 0.18,
1488
+ "anthropic:eu-central-1": 0.32,
1489
+ "anthropic:eu-west-1": 0.27,
1490
+ // OpenAI — Azure East US / West Europe / Sweden Central.
1491
+ "openai:eastus": 0.4,
1492
+ "openai:westus3": 0.19,
1493
+ "openai:swedencentral": 0.04,
1494
+ "openai:westeurope": 0.28,
1495
+ // Google (Vertex / Gemini) — typically reports lowest PUE.
1496
+ "google:us-central1": 0.34,
1497
+ "google:us-west1": 0.16,
1498
+ "google:europe-west1": 0.21,
1499
+ "google:europe-north1": 0.05,
1500
+ // AWS Bedrock direct.
1501
+ "aws:us-east-1": 0.42,
1502
+ "aws:us-west-2": 0.18,
1503
+ "aws:eu-west-1": 0.27,
1504
+ // Local / on-device — only the device's grid matters.
1505
+ "ollama:local": 0.3,
1506
+ "webllm:browser": 0.3,
1507
+ "lmstudio:local": 0.3,
1508
+ // Self-hosted / community.
1509
+ "groq:us-east-1": 0.4,
1510
+ "fireworks:us-west-2": 0.18,
1511
+ "together:us-east-1": 0.42,
1512
+ "cerebras:us-west-2": 0.18
1513
+ };
1514
+ function defaultKey(candidate) {
1515
+ if (!candidate.region) return void 0;
1516
+ const provider = candidate.id.split(/[-:]/)[0];
1517
+ return `${provider}:${candidate.region}`;
1518
+ }
1519
+ function applyCarbonTable(candidates, options = {}) {
1520
+ const table = options.table ?? DEFAULT_CARBON_TABLE;
1521
+ const keyFor = options.keyFor ?? defaultKey;
1522
+ return candidates.map((c) => {
1523
+ if (c.gCO2PerKtok != null) return c;
1524
+ const key = keyFor(c);
1525
+ const value = key ? table[key] : void 0;
1526
+ return { ...c, gCO2PerKtok: value ?? options.fallback };
1527
+ });
1528
+ }
1529
+ function estimateCO2Grams(gCO2PerKtok, tokens) {
1530
+ if (gCO2PerKtok == null) return 0;
1531
+ return tokens / 1e3 * gCO2PerKtok;
1532
+ }
1445
1533
  async function drain(source, timeoutMs) {
1446
1534
  const chunks = [];
1447
1535
  let text = "";
@@ -1580,26 +1668,36 @@ function createFallbackAdapter(candidates, options = {}) {
1580
1668
  }
1581
1669
  active = source;
1582
1670
  const iter = source.stream()[Symbol.asyncIterator]();
1583
- let first;
1671
+ let firstReal;
1672
+ let branchError;
1584
1673
  try {
1585
- first = await iter.next();
1674
+ while (true) {
1675
+ const r = await iter.next();
1676
+ if (r.done) {
1677
+ branchError = new Error(`candidate ${candidate.id} emitted no chunks`);
1678
+ break;
1679
+ }
1680
+ if (r.value.type === "error") {
1681
+ branchError = new Error(
1682
+ `candidate ${candidate.id}: ${r.value.content ?? "stream error"}`
1683
+ );
1684
+ break;
1685
+ }
1686
+ firstReal = r.value;
1687
+ break;
1688
+ }
1586
1689
  } catch (err) {
1587
- const error = err instanceof Error ? err : new Error(String(err));
1588
- errors.push({ id: candidate.id, error });
1589
- options.onFallback?.({ id: candidate.id, index: i, error });
1590
- if (options.shouldRetry && !options.shouldRetry(error, i)) throw error;
1591
- active = void 0;
1592
- continue;
1690
+ branchError = err instanceof Error ? err : new Error(String(err));
1593
1691
  }
1594
- if (first.done) {
1595
- const error = new Error(`candidate ${candidate.id} emitted no chunks`);
1692
+ if (branchError || !firstReal) {
1693
+ const error = branchError ?? new Error(`candidate ${candidate.id} emitted no chunks`);
1596
1694
  errors.push({ id: candidate.id, error });
1597
1695
  options.onFallback?.({ id: candidate.id, index: i, error });
1598
1696
  if (options.shouldRetry && !options.shouldRetry(error, i)) throw error;
1599
1697
  active = void 0;
1600
1698
  continue;
1601
1699
  }
1602
- yield first.value;
1700
+ yield firstReal;
1603
1701
  while (true) {
1604
1702
  const next = await iter.next();
1605
1703
  if (next.done) return;
@@ -1712,16 +1810,23 @@ function replayAdapter(fixture) {
1712
1810
  });
1713
1811
  }
1714
1812
 
1813
+ // src/embedders/shared.ts
1814
+ var ERROR_BODY_PREVIEW_CHARS = 200;
1815
+ async function throwIfNotOk(response, label, url) {
1816
+ if (response.ok) return;
1817
+ const body = await response.text().catch(() => "");
1818
+ throw new Error(
1819
+ `HTTP ${response.status} from ${label} ${url}: ${body.slice(0, ERROR_BODY_PREVIEW_CHARS)}`
1820
+ );
1821
+ }
1822
+
1715
1823
  // src/embedders/openai.ts
1716
1824
  async function fetchAvailableModels(baseUrl, apiKey) {
1717
1825
  const url = `${baseUrl}/v1/models`;
1718
1826
  const response = await fetch(url, {
1719
1827
  headers: { "Authorization": `Bearer ${apiKey}` }
1720
1828
  });
1721
- if (!response.ok) {
1722
- const body = await response.text().catch(() => "");
1723
- throw new Error(`HTTP ${response.status} from ${url}: ${body.slice(0, 200)}`);
1724
- }
1829
+ await throwIfNotOk(response, "openai", url);
1725
1830
  const data = await response.json();
1726
1831
  return data.data.map((m) => m.id).filter((id) => id.includes("embed")).sort();
1727
1832
  }
@@ -1763,10 +1868,7 @@ function openaiEmbedder(config) {
1763
1868
  async function fetchAvailableModels2(baseUrl, apiKey) {
1764
1869
  const url = `${baseUrl}/v1beta/models?key=${apiKey}`;
1765
1870
  const response = await fetch(url);
1766
- if (!response.ok) {
1767
- const body = await response.text().catch(() => "");
1768
- throw new Error(`HTTP ${response.status} from gemini ${baseUrl}/v1beta/models: ${body.slice(0, 200)}`);
1769
- }
1871
+ await throwIfNotOk(response, "gemini", `${baseUrl}/v1beta/models`);
1770
1872
  const data = await response.json();
1771
1873
  return data.models.filter((m) => m.supportedGenerationMethods.includes("embedContent")).map((m) => m.name.replace("models/", "")).sort();
1772
1874
  }
@@ -1815,10 +1917,7 @@ function geminiEmbedder(config) {
1815
1917
  async function fetchAvailableModels3(baseUrl) {
1816
1918
  const url = `${baseUrl}/api/tags`;
1817
1919
  const response = await fetch(url);
1818
- if (!response.ok) {
1819
- const body = await response.text().catch(() => "");
1820
- throw new Error(`HTTP ${response.status} from ollama ${url}: ${body.slice(0, 200)}`);
1821
- }
1920
+ await throwIfNotOk(response, "ollama", url);
1822
1921
  const data = await response.json();
1823
1922
  return data.models.map((m) => m.name).filter((name) => name.includes("embed")).sort();
1824
1923
  }
@@ -1852,21 +1951,18 @@ function ollamaEmbedder(config) {
1852
1951
  return data.embeddings[0];
1853
1952
  };
1854
1953
  }
1855
- async function fetchAvailableModels4(baseUrl, apiKey) {
1954
+ async function fetchAvailableModels4(provider, baseUrl, apiKey) {
1856
1955
  const url = `${baseUrl}/v1/models`;
1857
1956
  const response = await fetch(url, {
1858
1957
  headers: { "Authorization": `Bearer ${apiKey}` }
1859
1958
  });
1860
- if (!response.ok) {
1861
- const body = await response.text().catch(() => "");
1862
- throw new Error(`HTTP ${response.status} from ${url}: ${body.slice(0, 200)}`);
1863
- }
1959
+ await throwIfNotOk(response, provider, url);
1864
1960
  const data = await response.json();
1865
1961
  return data.data.map((m) => m.id).filter((id) => id.includes("embed")).sort();
1866
1962
  }
1867
1963
  async function buildModelError4(provider, baseUrl, apiKey, originalError) {
1868
1964
  try {
1869
- const models = await fetchAvailableModels4(baseUrl, apiKey);
1965
+ const models = await fetchAvailableModels4(provider, baseUrl, apiKey);
1870
1966
  const list = models.length > 0 ? models.join(", ") : "none found";
1871
1967
  return new Error(
1872
1968
  `${provider} embedding failed: ${originalError}. Available embedding models: ${list}`
@@ -1915,8 +2011,95 @@ var grokEmbedder = createOpenAICompatibleEmbedder("Grok", "https://api.x.ai");
1915
2011
 
1916
2012
  // src/embedders/kimi.ts
1917
2013
  var kimiEmbedder = createOpenAICompatibleEmbedder("Kimi", "https://api.moonshot.ai");
2014
+ var DEFAULT_DEPRECATION_TABLE = [
2015
+ // OpenAI
2016
+ { provider: "openai", model: "gpt-3.5-turbo-0301", successor: "gpt-4o-mini", sunsetOn: "2024-09-13" },
2017
+ { provider: "openai", model: "gpt-3.5-turbo-0613", successor: "gpt-4o-mini", sunsetOn: "2024-09-13" },
2018
+ { provider: "openai", model: "gpt-4-0314", successor: "gpt-4o", sunsetOn: "2024-06-13" },
2019
+ { provider: "openai", model: "gpt-4-32k", successor: "gpt-4o", sunsetOn: "2024-06-06" },
2020
+ { provider: "openai", model: "text-davinci-003", successor: "gpt-4o-mini", sunsetOn: "2024-01-04" },
2021
+ // Anthropic
2022
+ { provider: "anthropic", model: "claude-2.0", successor: "claude-3-5-sonnet-latest", sunsetOn: "2025-07-21" },
2023
+ { provider: "anthropic", model: "claude-2.1", successor: "claude-3-5-sonnet-latest", sunsetOn: "2025-07-21" },
2024
+ { provider: "anthropic", model: "claude-instant-1.2", successor: "claude-3-5-haiku-latest", sunsetOn: "2024-07-22" },
2025
+ { provider: "anthropic", model: "claude-3-sonnet-20240229", successor: "claude-3-5-sonnet-latest", sunsetOn: "2025-07-21" },
2026
+ // Google
2027
+ { provider: "google", model: "gemini-1.0-pro", successor: "gemini-1.5-pro", sunsetOn: "2025-02-15" },
2028
+ { provider: "google", model: "gemini-pro-vision", successor: "gemini-1.5-pro", sunsetOn: "2024-07-12" }
2029
+ ];
2030
+ function resolveModel(input, policy) {
2031
+ const table = policy.table ?? DEFAULT_DEPRECATION_TABLE;
2032
+ const hit = table.find((d) => d.provider === input.provider && d.model === input.model);
2033
+ if (!hit) return { model: input.model, remapped: false };
2034
+ const log = policy.logger ?? ((msg) => console.warn(msg));
2035
+ const sunset = hit.sunsetOn ? ` (sunset ${hit.sunsetOn})` : "";
2036
+ const successor = hit.successor ? ` Suggested successor: ${hit.successor}.` : "";
2037
+ const base = `[agentskit] Model "${input.provider}:${input.model}" is deprecated${sunset}.${successor}`;
2038
+ switch (policy.onDeprecation) {
2039
+ case "fail":
2040
+ throw new core.ConfigError({
2041
+ code: core.ErrorCodes.AK_CONFIG_INVALID,
2042
+ message: base,
2043
+ hint: hit.successor ? `Set model to "${hit.successor}".` : "Pick a supported model from the provider."
2044
+ });
2045
+ case "remap": {
2046
+ if (!hit.successor) {
2047
+ throw new core.ConfigError({
2048
+ code: core.ErrorCodes.AK_CONFIG_INVALID,
2049
+ message: `${base} No successor available \u2014 cannot remap.`
2050
+ });
2051
+ }
2052
+ log(`${base} Auto-remapping to "${hit.successor}".`);
2053
+ return { model: hit.successor, remapped: true, deprecation: hit };
2054
+ }
2055
+ case "warn":
2056
+ default:
2057
+ log(base);
2058
+ return { model: input.model, remapped: false, deprecation: hit };
2059
+ }
2060
+ }
2061
+ function withDeprecationPolicy(factory, options) {
2062
+ resolveModel({ provider: options.provider, model: options.model }, options);
2063
+ return factory;
2064
+ }
2065
+
2066
+ // src/credential-rotation.ts
2067
+ function createRotatingCredentials(initial, options) {
2068
+ let value = initial;
2069
+ const handlers = /* @__PURE__ */ new Set();
2070
+ return {
2071
+ current: () => value,
2072
+ rotate: async (next) => {
2073
+ value = next;
2074
+ const event = {
2075
+ rotatedAt: (/* @__PURE__ */ new Date()).toISOString(),
2076
+ id: options.id,
2077
+ fingerprint: next.slice(-4)
2078
+ };
2079
+ for (const h of handlers) h(event);
2080
+ return next;
2081
+ },
2082
+ onRotate: (handler) => {
2083
+ handlers.add(handler);
2084
+ return () => handlers.delete(handler);
2085
+ }
2086
+ };
2087
+ }
2088
+ async function refreshCredentials(adapter, next, options) {
2089
+ const log = options?.logger ?? ((msg) => console.log(msg));
2090
+ if (adapter && typeof adapter === "object" && "refreshCredentials" in adapter && typeof adapter.refreshCredentials === "function") {
2091
+ await adapter.refreshCredentials(next);
2092
+ log(`[agentskit] credentials refreshed${options?.id ? ` (${options.id})` : ""}`);
2093
+ return true;
2094
+ }
2095
+ log(`[agentskit] adapter does not support credential rotation; restart required${options?.id ? ` (${options.id})` : ""}`);
2096
+ return false;
2097
+ }
1918
2098
 
2099
+ exports.DEFAULT_CARBON_TABLE = DEFAULT_CARBON_TABLE;
2100
+ exports.DEFAULT_DEPRECATION_TABLE = DEFAULT_DEPRECATION_TABLE;
1919
2101
  exports.anthropic = anthropic;
2102
+ exports.applyCarbonTable = applyCarbonTable;
1920
2103
  exports.azureOpenAI = azureOpenAI;
1921
2104
  exports.azureOpenAIAdapter = azureOpenAIAdapter;
1922
2105
  exports.bail = bail;
@@ -1932,9 +2115,11 @@ exports.createAdapter = createAdapter;
1932
2115
  exports.createEnsembleAdapter = createEnsembleAdapter;
1933
2116
  exports.createFallbackAdapter = createFallbackAdapter;
1934
2117
  exports.createOpenAICompatibleEmbedder = createOpenAICompatibleEmbedder;
2118
+ exports.createRotatingCredentials = createRotatingCredentials;
1935
2119
  exports.createRouter = createRouter;
1936
2120
  exports.deepseek = deepseek;
1937
2121
  exports.deepseekEmbedder = deepseekEmbedder;
2122
+ exports.estimateCO2Grams = estimateCO2Grams;
1938
2123
  exports.fetchWithRetry = fetchWithRetry;
1939
2124
  exports.fireworks = fireworks;
1940
2125
  exports.gemini = gemini;
@@ -1961,9 +2146,11 @@ exports.openaiEmbedder = openaiEmbedder;
1961
2146
  exports.openrouter = openrouter;
1962
2147
  exports.qwen = qwen;
1963
2148
  exports.recordingAdapter = recordingAdapter;
2149
+ exports.refreshCredentials = refreshCredentials;
1964
2150
  exports.replayAdapter = replayAdapter;
1965
2151
  exports.replicate = replicate;
1966
2152
  exports.replicateAdapter = replicateAdapter;
2153
+ exports.resolveModel = resolveModel;
1967
2154
  exports.simulateStream = simulateStream;
1968
2155
  exports.together = together;
1969
2156
  exports.vercelAI = vercelAI;
@@ -1972,5 +2159,6 @@ exports.vertexAdapter = vertexAdapter;
1972
2159
  exports.vllm = vllm;
1973
2160
  exports.webllm = webllm;
1974
2161
  exports.webllmAdapter = webllmAdapter;
2162
+ exports.withDeprecationPolicy = withDeprecationPolicy;
1975
2163
  //# sourceMappingURL=index.cjs.map
1976
2164
  //# sourceMappingURL=index.cjs.map