@agentskit/adapters 0.11.0 → 0.12.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.
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 {
@@ -1096,8 +1098,6 @@ function vertex(config) {
1096
1098
  };
1097
1099
  }
1098
1100
  var vertexAdapter = vertex;
1099
-
1100
- // src/bedrock.ts
1101
1101
  var cachedSdk = null;
1102
1102
  async function loadSdk() {
1103
1103
  if (!cachedSdk) {
@@ -1109,9 +1109,11 @@ async function loadSdk() {
1109
1109
  moduleId
1110
1110
  );
1111
1111
  } catch {
1112
- throw new Error(
1113
- "Install @aws-sdk/client-bedrock-runtime to use the bedrock adapter: npm install @aws-sdk/client-bedrock-runtime"
1114
- );
1112
+ throw new core.AdapterError({
1113
+ code: core.ErrorCodes.AK_ADAPTER_MISSING,
1114
+ message: "Install @aws-sdk/client-bedrock-runtime to use the bedrock adapter: npm install @aws-sdk/client-bedrock-runtime",
1115
+ hint: "bedrock depends on the optional peer @aws-sdk/client-bedrock-runtime."
1116
+ });
1115
1117
  }
1116
1118
  })();
1117
1119
  }
@@ -1212,9 +1214,11 @@ async function* parseAnthropicBedrockEvents(events) {
1212
1214
  function bedrock(config) {
1213
1215
  const { model, region, maxTokens = 4096 } = config;
1214
1216
  if (!isAnthropicModel(model)) {
1215
- throw new Error(
1216
- `bedrock: model "${model}" is not supported in v1. Only anthropic.* models are wired up; Titan + others are tracked as a follow-up.`
1217
- );
1217
+ throw new core.ConfigError({
1218
+ code: core.ErrorCodes.AK_CONFIG_INVALID,
1219
+ message: `bedrock: model "${model}" is not supported in v1. Only anthropic.* models are wired up; Titan + others are tracked as a follow-up.`,
1220
+ hint: 'Pass an anthropic.* model id like "anthropic.claude-3-5-sonnet-20241022-v2:0".'
1221
+ });
1218
1222
  }
1219
1223
  let clientPromise = null;
1220
1224
  const getClient = async () => {
@@ -1273,8 +1277,6 @@ function bedrock(config) {
1273
1277
  };
1274
1278
  }
1275
1279
  var bedrockAdapter = bedrock;
1276
-
1277
- // src/webllm.ts
1278
1280
  var cachedSdk2 = null;
1279
1281
  async function loadSdk2() {
1280
1282
  if (!cachedSdk2) {
@@ -1286,7 +1288,11 @@ async function loadSdk2() {
1286
1288
  moduleId
1287
1289
  );
1288
1290
  } catch {
1289
- throw new Error("Install @mlc-ai/web-llm to use the webllm adapter: npm install @mlc-ai/web-llm");
1291
+ throw new core.AdapterError({
1292
+ code: core.ErrorCodes.AK_ADAPTER_MISSING,
1293
+ message: "Install @mlc-ai/web-llm to use the webllm adapter: npm install @mlc-ai/web-llm",
1294
+ hint: "webllm is browser-only and depends on the optional peer @mlc-ai/web-llm."
1295
+ });
1290
1296
  }
1291
1297
  })();
1292
1298
  }
@@ -1336,8 +1342,6 @@ function webllm(config) {
1336
1342
  };
1337
1343
  }
1338
1344
  var webllmAdapter = webllm;
1339
-
1340
- // src/router.ts
1341
1345
  function requireCapabilities(request) {
1342
1346
  const needs = {};
1343
1347
  if (request.context?.tools && request.context.tools.length > 0) needs.tools = true;
@@ -1364,7 +1368,13 @@ function pickSyncPolicy(pool, policy) {
1364
1368
  }
1365
1369
  function createRouter(options) {
1366
1370
  const { candidates } = options;
1367
- if (candidates.length === 0) throw new Error("createRouter requires at least one candidate");
1371
+ if (candidates.length === 0) {
1372
+ throw new core.ConfigError({
1373
+ code: core.ErrorCodes.AK_CONFIG_INVALID,
1374
+ message: "createRouter requires at least one candidate",
1375
+ hint: "Pass at least one candidate, e.g. createRouter({ candidates: [{ id, adapter, capabilities }] })."
1376
+ });
1377
+ }
1368
1378
  const policy = options.policy ?? "cheapest";
1369
1379
  return {
1370
1380
  createSource: (request) => {
@@ -1387,7 +1397,13 @@ function createRouter(options) {
1387
1397
  pickedBy = "classify:tags";
1388
1398
  }
1389
1399
  }
1390
- if (pool.length === 0) throw new Error("no candidate satisfies the request");
1400
+ if (pool.length === 0) {
1401
+ throw new core.AdapterError({
1402
+ code: core.ErrorCodes.AK_ADAPTER_STREAM_FAILED,
1403
+ message: "no candidate satisfies the request",
1404
+ hint: "Ensure at least one candidate declares the required capabilities (tools, json, etc.)."
1405
+ });
1406
+ }
1391
1407
  if (typeof policy === "function") {
1392
1408
  const maybe = policy({ request, candidates: pool });
1393
1409
  if (maybe instanceof Promise) {
@@ -1397,14 +1413,26 @@ function createRouter(options) {
1397
1413
  stream: async function* () {
1398
1414
  const id = await maybe;
1399
1415
  const c3 = pool.find((x) => x.id === id);
1400
- if (!c3) throw new Error(`policy returned unknown id: ${id}`);
1416
+ if (!c3) {
1417
+ throw new core.ConfigError({
1418
+ code: core.ErrorCodes.AK_CONFIG_INVALID,
1419
+ message: `policy returned unknown id: ${id}`,
1420
+ hint: "Custom policy functions must return one of the candidate ids."
1421
+ });
1422
+ }
1401
1423
  options.onRoute?.({ id: c3.id, reason: pickedBy ?? "custom policy", request });
1402
1424
  for await (const chunk of c3.adapter.createSource(request).stream()) yield chunk;
1403
1425
  }
1404
1426
  };
1405
1427
  }
1406
1428
  const c2 = pool.find((x) => x.id === maybe);
1407
- if (!c2) throw new Error(`policy returned unknown id: ${maybe}`);
1429
+ if (!c2) {
1430
+ throw new core.ConfigError({
1431
+ code: core.ErrorCodes.AK_CONFIG_INVALID,
1432
+ message: `policy returned unknown id: ${maybe}`,
1433
+ hint: "Custom policy functions must return one of the candidate ids."
1434
+ });
1435
+ }
1408
1436
  options.onRoute?.({ id: c2.id, reason: pickedBy ?? "custom policy", request });
1409
1437
  return c2.adapter.createSource(request);
1410
1438
  }
@@ -1414,8 +1442,6 @@ function createRouter(options) {
1414
1442
  }
1415
1443
  };
1416
1444
  }
1417
-
1418
- // src/ensemble.ts
1419
1445
  async function drain(source, timeoutMs) {
1420
1446
  const chunks = [];
1421
1447
  let text = "";
@@ -1460,7 +1486,11 @@ function majorityVote(branches, candidates) {
1460
1486
  }
1461
1487
  function createEnsembleAdapter(options) {
1462
1488
  if (options.candidates.length === 0) {
1463
- throw new Error("createEnsembleAdapter requires at least one candidate");
1489
+ throw new core.ConfigError({
1490
+ code: core.ErrorCodes.AK_CONFIG_INVALID,
1491
+ message: "createEnsembleAdapter requires at least one candidate",
1492
+ hint: "Pass at least one candidate, e.g. createEnsembleAdapter({ candidates: [{ id, adapter }] })."
1493
+ });
1464
1494
  }
1465
1495
  const aggregate = options.aggregate ?? "majority-vote";
1466
1496
  return {
@@ -1500,7 +1530,14 @@ function createEnsembleAdapter(options) {
1500
1530
  if (aborted) return;
1501
1531
  const text = await finalText(branches);
1502
1532
  if (!text && branches.every((b) => b.error)) {
1503
- throw new Error("all ensemble branches failed");
1533
+ const summary = branches.map((b) => `${b.id}: ${b.error?.message ?? "unknown"}`).join("; ");
1534
+ const err = new core.AdapterError({
1535
+ code: core.ErrorCodes.AK_ADAPTER_STREAM_FAILED,
1536
+ message: `all ensemble branches failed (${summary})`,
1537
+ hint: "Inspect each branch error via options.onBranches or the err.branchErrors field."
1538
+ });
1539
+ err.branchErrors = branches.map((b) => ({ id: b.id, error: b.error }));
1540
+ throw err;
1504
1541
  }
1505
1542
  yield { type: "text", content: text, metadata: { ensemble: branches.map((b) => ({ id: b.id, bytes: b.text.length, error: b.error?.message })) } };
1506
1543
  yield { type: "done" };
@@ -1509,11 +1546,13 @@ function createEnsembleAdapter(options) {
1509
1546
  }
1510
1547
  };
1511
1548
  }
1512
-
1513
- // src/fallback.ts
1514
1549
  function createFallbackAdapter(candidates, options = {}) {
1515
1550
  if (candidates.length === 0) {
1516
- throw new Error("createFallbackAdapter requires at least one candidate");
1551
+ throw new core.ConfigError({
1552
+ code: core.ErrorCodes.AK_CONFIG_INVALID,
1553
+ message: "createFallbackAdapter requires at least one candidate",
1554
+ hint: 'Pass at least one candidate, e.g. createFallbackAdapter([{ id: "primary", adapter }]).'
1555
+ });
1517
1556
  }
1518
1557
  return {
1519
1558
  createSource: (request) => {
@@ -1568,14 +1607,16 @@ function createFallbackAdapter(candidates, options = {}) {
1568
1607
  }
1569
1608
  }
1570
1609
  const summary = errors.map((e) => `${e.id}: ${e.error.message}`).join("; ");
1571
- throw new Error(`all fallback candidates failed (${summary})`);
1610
+ throw new core.AdapterError({
1611
+ code: core.ErrorCodes.AK_ADAPTER_STREAM_FAILED,
1612
+ message: `all fallback candidates failed (${summary})`,
1613
+ hint: "Check each candidate adapter's configuration and provider keys."
1614
+ });
1572
1615
  }
1573
1616
  };
1574
1617
  }
1575
1618
  };
1576
1619
  }
1577
-
1578
- // src/mock.ts
1579
1620
  function mockAdapter(options) {
1580
1621
  const { response, delayMs = 0, history } = options;
1581
1622
  let callIndex = 0;
@@ -1660,7 +1701,11 @@ function inMemorySink() {
1660
1701
  }
1661
1702
  function replayAdapter(fixture) {
1662
1703
  if (fixture.length === 0) {
1663
- throw new Error("replayAdapter: fixture is empty");
1704
+ throw new core.ConfigError({
1705
+ code: core.ErrorCodes.AK_CONFIG_INVALID,
1706
+ message: "replayAdapter: fixture is empty",
1707
+ hint: "Pass a non-empty fixture; record one with recordingAdapter() first."
1708
+ });
1664
1709
  }
1665
1710
  return mockAdapter({
1666
1711
  response: fixture.map((turn) => turn.chunks)
@@ -1669,11 +1714,13 @@ function replayAdapter(fixture) {
1669
1714
 
1670
1715
  // src/embedders/openai.ts
1671
1716
  async function fetchAvailableModels(baseUrl, apiKey) {
1672
- const response = await fetch(`${baseUrl}/v1/models`, {
1717
+ const url = `${baseUrl}/v1/models`;
1718
+ const response = await fetch(url, {
1673
1719
  headers: { "Authorization": `Bearer ${apiKey}` }
1674
1720
  });
1675
1721
  if (!response.ok) {
1676
- throw new Error(`HTTP ${response.status}`);
1722
+ const body = await response.text().catch(() => "");
1723
+ throw new Error(`HTTP ${response.status} from ${url}: ${body.slice(0, 200)}`);
1677
1724
  }
1678
1725
  const data = await response.json();
1679
1726
  return data.data.map((m) => m.id).filter((id) => id.includes("embed")).sort();
@@ -1714,9 +1761,11 @@ function openaiEmbedder(config) {
1714
1761
 
1715
1762
  // src/embedders/gemini.ts
1716
1763
  async function fetchAvailableModels2(baseUrl, apiKey) {
1717
- const response = await fetch(`${baseUrl}/v1beta/models?key=${apiKey}`);
1764
+ const url = `${baseUrl}/v1beta/models?key=${apiKey}`;
1765
+ const response = await fetch(url);
1718
1766
  if (!response.ok) {
1719
- throw new Error(`HTTP ${response.status}`);
1767
+ const body = await response.text().catch(() => "");
1768
+ throw new Error(`HTTP ${response.status} from gemini ${baseUrl}/v1beta/models: ${body.slice(0, 200)}`);
1720
1769
  }
1721
1770
  const data = await response.json();
1722
1771
  return data.models.filter((m) => m.supportedGenerationMethods.includes("embedContent")).map((m) => m.name.replace("models/", "")).sort();
@@ -1764,9 +1813,11 @@ function geminiEmbedder(config) {
1764
1813
 
1765
1814
  // src/embedders/ollama.ts
1766
1815
  async function fetchAvailableModels3(baseUrl) {
1767
- const response = await fetch(`${baseUrl}/api/tags`);
1816
+ const url = `${baseUrl}/api/tags`;
1817
+ const response = await fetch(url);
1768
1818
  if (!response.ok) {
1769
- throw new Error(`HTTP ${response.status}`);
1819
+ const body = await response.text().catch(() => "");
1820
+ throw new Error(`HTTP ${response.status} from ollama ${url}: ${body.slice(0, 200)}`);
1770
1821
  }
1771
1822
  const data = await response.json();
1772
1823
  return data.models.map((m) => m.name).filter((name) => name.includes("embed")).sort();
@@ -1801,14 +1852,14 @@ function ollamaEmbedder(config) {
1801
1852
  return data.embeddings[0];
1802
1853
  };
1803
1854
  }
1804
-
1805
- // src/embedders/openai-compatible.ts
1806
1855
  async function fetchAvailableModels4(baseUrl, apiKey) {
1807
- const response = await fetch(`${baseUrl}/v1/models`, {
1856
+ const url = `${baseUrl}/v1/models`;
1857
+ const response = await fetch(url, {
1808
1858
  headers: { "Authorization": `Bearer ${apiKey}` }
1809
1859
  });
1810
1860
  if (!response.ok) {
1811
- throw new Error(`HTTP ${response.status}`);
1861
+ const body = await response.text().catch(() => "");
1862
+ throw new Error(`HTTP ${response.status} from ${url}: ${body.slice(0, 200)}`);
1812
1863
  }
1813
1864
  const data = await response.json();
1814
1865
  return data.data.map((m) => m.id).filter((id) => id.includes("embed")).sort();
@@ -1829,7 +1880,11 @@ async function buildModelError4(provider, baseUrl, apiKey, originalError) {
1829
1880
  function createOpenAICompatibleEmbedder(provider, defaultBaseUrl) {
1830
1881
  return function embedder(config) {
1831
1882
  if (!config.model) {
1832
- throw new Error(`Model is required for ${provider}. Pass { model: "<model-name>" }.`);
1883
+ throw new core.ConfigError({
1884
+ code: core.ErrorCodes.AK_CONFIG_INVALID,
1885
+ message: `Model is required for ${provider}. Pass { model: "<model-name>" }.`,
1886
+ hint: `${provider} does not infer a default; pick a recent embedding model and pass it explicitly.`
1887
+ });
1833
1888
  }
1834
1889
  const { apiKey, model, baseUrl = defaultBaseUrl } = config;
1835
1890
  return async (text) => {