@wrongstack/providers 0.1.3 → 0.1.7

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.js CHANGED
@@ -1,4 +1,5 @@
1
- import { safeParse, ProviderError, sanitizeJsonString } from '@wrongstack/core';
1
+ import { ProviderError, safeParse, sanitizeJsonString } from '@wrongstack/core';
2
+ import { randomUUID } from 'crypto';
2
3
 
3
4
  var __defProp = Object.defineProperty;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -9,6 +10,20 @@ var __export = (target, all) => {
9
10
  for (var name in all)
10
11
  __defProp(target, name, { get: all[name], enumerable: true });
11
12
  };
13
+ function parseToolInput(raw) {
14
+ if (!raw) return {};
15
+ const parsed = safeParse(raw);
16
+ if (!parsed.ok) return { __raw: raw };
17
+ const v = parsed.value;
18
+ if (v && typeof v === "object" && !Array.isArray(v)) {
19
+ return v;
20
+ }
21
+ return { __raw: v ?? raw };
22
+ }
23
+ var init_tool_input = __esm({
24
+ "src/_tool-input.ts"() {
25
+ }
26
+ });
12
27
 
13
28
  // src/aggregate.ts
14
29
  var aggregate_exports = {};
@@ -50,13 +65,14 @@ async function aggregateStream(stream, onEvent) {
50
65
  case "tool_use_stop": {
51
66
  const b = toolBuffers.get(ev.id);
52
67
  if (b) {
53
- if (ev.input !== void 0) {
68
+ if (ev.input === void 0) {
69
+ b.input = parseToolInput(b.partial);
70
+ } else if (typeof ev.input === "string") {
71
+ b.input = parseToolInput(ev.input);
72
+ } else if (ev.input && typeof ev.input === "object" && !Array.isArray(ev.input)) {
54
73
  b.input = ev.input;
55
- } else if (b.partial) {
56
- const parsed = safeParse(b.partial);
57
- b.input = parsed.ok ? parsed.value : { _raw: b.partial };
58
74
  } else {
59
- b.input = {};
75
+ b.input = { __raw: ev.input };
60
76
  }
61
77
  }
62
78
  currentTextIndex = -1;
@@ -80,7 +96,7 @@ async function aggregateStream(stream, onEvent) {
80
96
  type: "tool_use",
81
97
  id: b.id,
82
98
  name: tb.name,
83
- input: tb.input ?? {}
99
+ input: tb.input && typeof tb.input === "object" && !Array.isArray(tb.input) ? tb.input : {}
84
100
  });
85
101
  }
86
102
  }
@@ -90,6 +106,7 @@ async function aggregateStream(stream, onEvent) {
90
106
  }
91
107
  var init_aggregate = __esm({
92
108
  "src/aggregate.ts"() {
109
+ init_tool_input();
93
110
  }
94
111
  });
95
112
  function parseProviderHttpError(providerId, status, rawText) {
@@ -98,9 +115,10 @@ function parseProviderHttpError(providerId, status, rawText) {
98
115
  const message = `${providerId} HTTP ${status}`;
99
116
  return new ProviderError(message, status, retryable, providerId, { body });
100
117
  }
118
+ var RAW_TRUNCATE_AT = 2e3;
101
119
  function parseBody(rawText) {
102
- const raw = rawText.slice(0, 2e3);
103
- const body = { raw };
120
+ const raw = rawText.slice(0, RAW_TRUNCATE_AT);
121
+ const body = rawText.length > RAW_TRUNCATE_AT ? { raw, truncated: true, rawLength: rawText.length } : { raw };
104
122
  if (!rawText.trim()) return body;
105
123
  let parsed;
106
124
  try {
@@ -144,6 +162,9 @@ function stringOf(v) {
144
162
  return typeof v === "string" && v.length > 0 ? v : void 0;
145
163
  }
146
164
 
165
+ // src/anthropic.ts
166
+ init_tool_input();
167
+
147
168
  // src/tool-format/to-anthropic.ts
148
169
  function toolsToAnthropic(tools) {
149
170
  return tools.map((t) => ({
@@ -209,6 +230,7 @@ function normalizeGemini(stop) {
209
230
  }
210
231
 
211
232
  // src/sse.ts
233
+ var MAX_BUFFER_BYTES = 256 * 1024;
212
234
  async function* parseSSE(body) {
213
235
  if (!body) return;
214
236
  const decoder = new TextDecoder("utf-8");
@@ -241,12 +263,23 @@ async function* parseSSE(body) {
241
263
  else if (field === "data") dataLines.push(value);
242
264
  return void 0;
243
265
  };
266
+ const appendChunk = (chunkStr) => {
267
+ if (chunkStr.length === 0) return;
268
+ buffer += chunkStr;
269
+ if (buffer.length > MAX_BUFFER_BYTES) {
270
+ throw new Error(
271
+ `SSE: pending line exceeds ${MAX_BUFFER_BYTES} bytes \u2014 upstream is not framing events`
272
+ );
273
+ }
274
+ };
244
275
  if (isNodeReadable(body)) {
245
276
  for await (const chunk of body) {
246
- buffer += typeof chunk === "string" ? chunk : decoder.decode(chunk, { stream: true });
247
- const lines = splitBuffer(buffer);
248
- buffer = lines.tail;
249
- for (const line of lines.lines) {
277
+ appendChunk(
278
+ typeof chunk === "string" ? chunk : decoder.decode(chunk, { stream: true })
279
+ );
280
+ const split = splitBuffer(buffer);
281
+ buffer = split.tail;
282
+ for (const line of split.lines) {
250
283
  const msg = processLine(line);
251
284
  if (msg) yield msg;
252
285
  }
@@ -257,10 +290,10 @@ async function* parseSSE(body) {
257
290
  for (; ; ) {
258
291
  const { done, value } = await reader.read();
259
292
  if (done) break;
260
- buffer += decoder.decode(value, { stream: true });
261
- const lines = splitBuffer(buffer);
262
- buffer = lines.tail;
263
- for (const line of lines.lines) {
293
+ appendChunk(decoder.decode(value, { stream: true }));
294
+ const split = splitBuffer(buffer);
295
+ buffer = split.tail;
296
+ for (const line of split.lines) {
264
297
  const msg = processLine(line);
265
298
  if (msg) yield msg;
266
299
  }
@@ -270,17 +303,17 @@ async function* parseSSE(body) {
270
303
  }
271
304
  }
272
305
  if (buffer.length > 0) {
273
- const msg = processLine(buffer);
306
+ const msg = processLine(buffer.replace(/\r$/, ""));
274
307
  if (msg) yield msg;
275
308
  }
276
309
  const final = flush();
277
310
  if (final) yield final;
278
311
  }
279
312
  function splitBuffer(buf) {
280
- const norm = buf.replace(/\r\n/g, "\n");
281
- const parts = norm.split("\n");
313
+ const parts = buf.split("\n");
282
314
  const tail = parts.pop() ?? "";
283
- return { lines: parts, tail };
315
+ const lines = parts.map((p) => p.endsWith("\r") ? p.slice(0, -1) : p);
316
+ return { lines, tail };
284
317
  }
285
318
  function isNodeReadable(b) {
286
319
  return !!b && typeof b === "object" && typeof b.pipe === "function" && typeof b.on === "function";
@@ -347,12 +380,9 @@ var WireAdapter = class {
347
380
  }
348
381
  };
349
382
 
350
- // src/anthropic.ts
351
- var DEFAULT_BASE = "https://api.anthropic.com";
352
- var DEFAULT_VERSION = "2023-06-01";
353
- var AnthropicProvider = class extends WireAdapter {
354
- id = "anthropic";
355
- capabilities = {
383
+ // src/family-capabilities.ts
384
+ var CAPABILITIES_BY_FAMILY = {
385
+ anthropic: {
356
386
  tools: true,
357
387
  parallelTools: true,
358
388
  vision: true,
@@ -362,7 +392,65 @@ var AnthropicProvider = class extends WireAdapter {
362
392
  jsonMode: false,
363
393
  maxContext: 2e5,
364
394
  cacheControl: "native"
395
+ },
396
+ openai: {
397
+ tools: true,
398
+ parallelTools: true,
399
+ vision: true,
400
+ streaming: true,
401
+ promptCache: false,
402
+ systemPrompt: true,
403
+ jsonMode: true,
404
+ maxContext: 128e3,
405
+ cacheControl: "auto"
406
+ },
407
+ "openai-compatible": {
408
+ tools: true,
409
+ parallelTools: true,
410
+ vision: false,
411
+ streaming: true,
412
+ promptCache: false,
413
+ systemPrompt: true,
414
+ jsonMode: false,
415
+ maxContext: 32e3,
416
+ cacheControl: "none"
417
+ },
418
+ google: {
419
+ tools: true,
420
+ parallelTools: true,
421
+ vision: true,
422
+ streaming: true,
423
+ promptCache: false,
424
+ systemPrompt: true,
425
+ jsonMode: true,
426
+ maxContext: 1e6,
427
+ cacheControl: "none"
428
+ },
429
+ unsupported: {
430
+ tools: false,
431
+ parallelTools: false,
432
+ vision: false,
433
+ streaming: false,
434
+ promptCache: false,
435
+ systemPrompt: false,
436
+ jsonMode: false,
437
+ maxContext: 0,
438
+ cacheControl: "none"
439
+ }
440
+ };
441
+ function capabilitiesForFamily(family, overrides = {}) {
442
+ return {
443
+ ...CAPABILITIES_BY_FAMILY[family] ?? CAPABILITIES_BY_FAMILY.unsupported,
444
+ ...overrides
365
445
  };
446
+ }
447
+
448
+ // src/anthropic.ts
449
+ var DEFAULT_BASE = "https://api.anthropic.com";
450
+ var DEFAULT_VERSION = "2023-06-01";
451
+ var AnthropicProvider = class extends WireAdapter {
452
+ id = "anthropic";
453
+ capabilities = capabilitiesForFamily("anthropic");
366
454
  opts;
367
455
  constructor(opts) {
368
456
  super(opts.apiKey, opts.baseUrl ?? DEFAULT_BASE, opts.fetchImpl);
@@ -475,7 +563,7 @@ async function* parseAnthropicStream(body, fallbackModel) {
475
563
  const index = Number(ev["index"] ?? 0);
476
564
  const block = blocks.get(index);
477
565
  if (block?.kind === "tool_use" && block.id) {
478
- const input = block.partial ? safeParse(block.partial).value ?? {} : {};
566
+ const input = parseToolInput(block.partial);
479
567
  yield { type: "tool_use_stop", id: block.id, input };
480
568
  }
481
569
  break;
@@ -508,6 +596,7 @@ async function* parseAnthropicStream(body, fallbackModel) {
508
596
  yield { type: "message_stop", stopReason, usage };
509
597
  }
510
598
  }
599
+ init_tool_input();
511
600
 
512
601
  // src/tool-format/to-openai.ts
513
602
  function toolsToOpenAI(tools) {
@@ -613,18 +702,11 @@ var OpenAIProvider = class extends WireAdapter {
613
702
  super(opts.apiKey, opts.baseUrl ?? DEFAULT_BASE2, opts.fetchImpl);
614
703
  this.opts = opts;
615
704
  this.id = opts.id ?? "openai";
616
- this.capabilities = {
617
- tools: true,
705
+ this.capabilities = capabilitiesForFamily("openai", {
618
706
  parallelTools: !opts.quirks?.parallelToolsDisabled,
619
- vision: true,
620
- streaming: true,
621
- promptCache: false,
622
707
  systemPrompt: !opts.quirks?.systemAsMessage,
623
- jsonMode: true,
624
- maxContext: 128e3,
625
- cacheControl: "auto",
626
708
  ...opts.capabilities
627
- };
709
+ });
628
710
  }
629
711
  buildUrl(_req) {
630
712
  const base = this.baseUrl.replace(/\/+$/, "");
@@ -737,7 +819,7 @@ async function* parseOpenAIStream(body, fallbackModel) {
737
819
  }
738
820
  }
739
821
  for (const entry of toolByIndex.values()) {
740
- const input = entry.argBuf ? safeParse(entry.argBuf).value ?? { _raw: entry.argBuf } : {};
822
+ const input = parseToolInput(entry.argBuf);
741
823
  yield { type: "tool_use_stop", id: entry.id, input };
742
824
  }
743
825
  if (started) {
@@ -755,12 +837,12 @@ var OpenAICompatibleProvider = class extends OpenAIProvider {
755
837
  baseUrl: opts.baseUrl,
756
838
  fetchImpl: opts.fetchImpl,
757
839
  id: opts.id,
758
- capabilities: opts.capabilities,
759
- quirks: {
760
- ...opts.quirks,
761
- parallelToolsDisabled: opts.quirks?.parallelToolsDisabled,
762
- jsonArgumentsBuggy: opts.quirks?.jsonArgumentsBuggy
763
- }
840
+ capabilities: capabilitiesForFamily("openai-compatible", {
841
+ parallelTools: !opts.quirks?.parallelToolsDisabled,
842
+ systemPrompt: !opts.quirks?.systemAsMessage,
843
+ ...opts.capabilities
844
+ }),
845
+ quirks: opts.quirks
764
846
  });
765
847
  this.extraHeaders = opts.headers;
766
848
  this.urlOverride = opts.urlOverride;
@@ -787,18 +869,9 @@ var GoogleProvider = class extends WireAdapter {
787
869
  super(opts.apiKey, opts.baseUrl ?? DEFAULT_BASE3, opts.fetchImpl);
788
870
  this.opts = opts;
789
871
  this.id = opts.id ?? "google";
790
- this.capabilities = {
791
- tools: true,
792
- parallelTools: true,
793
- vision: true,
794
- streaming: true,
795
- promptCache: false,
796
- systemPrompt: true,
797
- jsonMode: true,
798
- maxContext: 1e6,
799
- cacheControl: "none",
872
+ this.capabilities = capabilitiesForFamily("google", {
800
873
  ...opts.capabilities
801
- };
874
+ });
802
875
  }
803
876
  buildUrl(req) {
804
877
  return `${this.baseUrl}/models/${encodeURIComponent(req.model)}:streamGenerateContent?alt=sse`;
@@ -945,8 +1018,9 @@ function messagesToGemini(messages) {
945
1018
  });
946
1019
  }
947
1020
  }
948
- if (textParts.length > 0) out.push({ role: "user", parts: textParts });
949
- if (functionParts.length > 0) out.push({ role: "function", parts: functionParts });
1021
+ const userParts = [...textParts];
1022
+ if (functionParts.length > 0) userParts.push(...functionParts);
1023
+ if (userParts.length > 0) out.push({ role: "user", parts: userParts });
950
1024
  }
951
1025
  return out;
952
1026
  }
@@ -972,7 +1046,7 @@ async function* parseGoogleStream(body, fallbackModel) {
972
1046
  yield { type: "text_delta", text: part.text };
973
1047
  } else if (part.functionCall) {
974
1048
  sawFunctionCall = true;
975
- const id = `${part.functionCall.name}_${Math.random().toString(36).slice(2, 10)}`;
1049
+ const id = randomUUID();
976
1050
  yield { type: "tool_use_start", id, name: part.functionCall.name };
977
1051
  const providerMeta = typeof part.thoughtSignature === "string" ? { "google.thoughtSignature": part.thoughtSignature } : void 0;
978
1052
  yield {
@@ -1064,20 +1138,16 @@ function createWireFormatFactory(cfg, opts = {}) {
1064
1138
  }
1065
1139
  };
1066
1140
  }
1141
+
1142
+ // src/presets/mistral.ts
1143
+ init_tool_input();
1067
1144
  var mistralWireFormat = defineWireFormat({
1068
1145
  id: "mistral",
1069
1146
  family: "openai-compatible",
1070
- capabilities: {
1071
- tools: true,
1072
- parallelTools: true,
1073
- vision: false,
1074
- streaming: true,
1075
- promptCache: false,
1076
- systemPrompt: true,
1147
+ capabilities: capabilitiesForFamily("openai-compatible", {
1077
1148
  jsonMode: true,
1078
- maxContext: 128e3,
1079
- cacheControl: "none"
1080
- },
1149
+ maxContext: 128e3
1150
+ }),
1081
1151
  defaultBaseUrl: "https://api.mistral.ai/v1",
1082
1152
  buildUrl: (base) => `${base.replace(/\/+$/, "")}/chat/completions`,
1083
1153
  buildHeaders: (apiKey) => ({ authorization: `Bearer ${apiKey}` }),
@@ -1133,11 +1203,10 @@ var mistralWireFormat = defineWireFormat({
1133
1203
  if (choice?.finish_reason) {
1134
1204
  for (const block of state.toolCalls.values()) {
1135
1205
  if (block.id) {
1136
- const parsedInput = safeParse(block.partial || "{}");
1137
1206
  out.push({
1138
1207
  type: "tool_use_stop",
1139
1208
  id: block.id,
1140
- input: parsedInput.ok ? parsedInput.value : {}
1209
+ input: parseToolInput(block.partial)
1141
1210
  });
1142
1211
  }
1143
1212
  }
@@ -1165,21 +1234,14 @@ function mapStopReason(reason) {
1165
1234
  return "end_turn";
1166
1235
  }
1167
1236
  }
1237
+
1238
+ // src/presets/anthropic.ts
1239
+ init_tool_input();
1168
1240
  var DEFAULT_VERSION2 = "2023-06-01";
1169
1241
  var anthropicWireFormat = defineWireFormat({
1170
1242
  id: "anthropic",
1171
1243
  family: "anthropic",
1172
- capabilities: {
1173
- tools: true,
1174
- parallelTools: true,
1175
- vision: true,
1176
- streaming: true,
1177
- promptCache: true,
1178
- systemPrompt: true,
1179
- jsonMode: false,
1180
- maxContext: 2e5,
1181
- cacheControl: "native"
1182
- },
1244
+ capabilities: capabilitiesForFamily("anthropic"),
1183
1245
  defaultBaseUrl: "https://api.anthropic.com",
1184
1246
  buildUrl: (base) => {
1185
1247
  const b = base.replace(/\/+$/, "");
@@ -1273,7 +1335,7 @@ var anthropicWireFormat = defineWireFormat({
1273
1335
  const index = Number(ev["index"] ?? 0);
1274
1336
  const block = state.blocks.get(index);
1275
1337
  if (block?.kind === "tool_use" && block.id) {
1276
- const input = block.partial ? safeParse(block.partial).value ?? {} : {};
1338
+ const input = parseToolInput(block.partial);
1277
1339
  out.push({ type: "tool_use_stop", id: block.id, input });
1278
1340
  }
1279
1341
  break;
@@ -1312,20 +1374,13 @@ var anthropicWireFormat = defineWireFormat({
1312
1374
  return [];
1313
1375
  }
1314
1376
  });
1377
+
1378
+ // src/presets/openai.ts
1379
+ init_tool_input();
1315
1380
  var openaiWireFormat = defineWireFormat({
1316
1381
  id: "openai",
1317
1382
  family: "openai",
1318
- capabilities: {
1319
- tools: true,
1320
- parallelTools: true,
1321
- vision: true,
1322
- streaming: true,
1323
- promptCache: false,
1324
- systemPrompt: true,
1325
- jsonMode: true,
1326
- maxContext: 128e3,
1327
- cacheControl: "auto"
1328
- },
1383
+ capabilities: capabilitiesForFamily("openai"),
1329
1384
  defaultBaseUrl: "https://api.openai.com/v1",
1330
1385
  buildUrl: (base) => {
1331
1386
  const b = base.replace(/\/+$/, "");
@@ -1424,7 +1479,7 @@ var openaiWireFormat = defineWireFormat({
1424
1479
  state.finalEmitted = true;
1425
1480
  const out = [];
1426
1481
  for (const entry of state.toolByIndex.values()) {
1427
- const input = entry.argBuf ? safeParse(entry.argBuf).value ?? { _raw: entry.argBuf } : {};
1482
+ const input = parseToolInput(entry.argBuf);
1428
1483
  out.push({ type: "tool_use_stop", id: entry.id, input });
1429
1484
  }
1430
1485
  if (state.started) {
@@ -1443,17 +1498,7 @@ function stripCacheControl(system) {
1443
1498
  var googleWireFormat = defineWireFormat({
1444
1499
  id: "google",
1445
1500
  family: "google",
1446
- capabilities: {
1447
- tools: true,
1448
- parallelTools: true,
1449
- vision: true,
1450
- streaming: true,
1451
- promptCache: false,
1452
- systemPrompt: true,
1453
- jsonMode: true,
1454
- maxContext: 1e6,
1455
- cacheControl: "none"
1456
- },
1501
+ capabilities: capabilitiesForFamily("google"),
1457
1502
  defaultBaseUrl: "https://generativelanguage.googleapis.com/v1beta",
1458
1503
  buildUrl: (base, req) => `${base}/models/${encodeURIComponent(req.model)}:streamGenerateContent?alt=sse`,
1459
1504
  buildHeaders: (apiKey) => ({ "x-goog-api-key": apiKey }),
@@ -1650,74 +1695,15 @@ function messagesToGemini2(messages) {
1650
1695
  }
1651
1696
 
1652
1697
  // src/capabilities.ts
1653
- var BASE_BY_FAMILY = {
1654
- anthropic: {
1655
- tools: true,
1656
- parallelTools: true,
1657
- vision: true,
1658
- streaming: true,
1659
- promptCache: true,
1660
- systemPrompt: true,
1661
- jsonMode: false,
1662
- maxContext: 2e5,
1663
- cacheControl: "native"
1664
- },
1665
- openai: {
1666
- tools: true,
1667
- parallelTools: true,
1668
- vision: true,
1669
- streaming: true,
1670
- promptCache: false,
1671
- systemPrompt: true,
1672
- jsonMode: true,
1673
- maxContext: 128e3,
1674
- cacheControl: "auto"
1675
- },
1676
- "openai-compatible": {
1677
- tools: true,
1678
- parallelTools: true,
1679
- vision: false,
1680
- streaming: true,
1681
- promptCache: false,
1682
- systemPrompt: true,
1683
- jsonMode: false,
1684
- maxContext: 32e3,
1685
- cacheControl: "none"
1686
- },
1687
- google: {
1688
- tools: true,
1689
- parallelTools: true,
1690
- vision: true,
1691
- streaming: true,
1692
- promptCache: false,
1693
- systemPrompt: true,
1694
- jsonMode: true,
1695
- maxContext: 1e6,
1696
- cacheControl: "none"
1697
- },
1698
- unsupported: {
1699
- tools: false,
1700
- parallelTools: false,
1701
- vision: false,
1702
- streaming: false,
1703
- promptCache: false,
1704
- systemPrompt: false,
1705
- jsonMode: false,
1706
- maxContext: 0,
1707
- cacheControl: "none"
1708
- }
1709
- };
1710
- function baseFor(family) {
1711
- return BASE_BY_FAMILY[family] ?? BASE_BY_FAMILY.unsupported;
1712
- }
1713
1698
  async function capabilitiesFor(registry, providerId, modelId) {
1714
1699
  const provider = await registry.getProvider(providerId);
1715
- const base = baseFor(provider?.family ?? "unsupported");
1700
+ const base = capabilitiesForFamily(provider?.family ?? "unsupported");
1716
1701
  const model = await registry.getModel(providerId, modelId);
1717
1702
  if (!model) return { ...base };
1718
1703
  return {
1719
1704
  ...base,
1720
1705
  tools: model.capabilities.tools && base.tools,
1706
+ parallelTools: model.capabilities.tools && base.parallelTools,
1721
1707
  vision: model.capabilities.vision && base.vision,
1722
1708
  maxContext: model.capabilities.maxContext || base.maxContext
1723
1709
  };
@@ -1800,12 +1786,15 @@ function parseToolArguments(raw, toolName, toolCallId, opts) {
1800
1786
  opts.onParseFailure?.({ toolName, toolCallId, raw });
1801
1787
  return { __raw_arguments: raw };
1802
1788
  } catch {
1803
- try {
1804
- const sanitized = JSON.parse(sanitizeJsonString(raw));
1805
- if (sanitized && typeof sanitized === "object" && !Array.isArray(sanitized)) {
1806
- return sanitized;
1789
+ const sanitized = sanitizeJsonString(raw);
1790
+ if (sanitized !== null) {
1791
+ try {
1792
+ const parsed = JSON.parse(sanitized);
1793
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
1794
+ return parsed;
1795
+ }
1796
+ } catch {
1807
1797
  }
1808
- } catch {
1809
1798
  }
1810
1799
  opts.onParseFailure?.({ toolName, toolCallId, raw });
1811
1800
  return { __raw_arguments: raw };
@@ -1916,6 +1905,6 @@ function requireKey(cfg) {
1916
1905
  throw new Error("Provider config requires apiKey (or set the corresponding env var).");
1917
1906
  }
1918
1907
 
1919
- export { AnthropicProvider, GoogleProvider, OpenAICompatibleProvider, OpenAIProvider, WireAdapter, WireFormatProvider, anthropicWireFormat, buildProviderFactoriesFromRegistry, capabilitiesFor, contentFromAnthropic, contentFromOpenAI, createWireFormatFactory, defineWireFormat, googleWireFormat, makeProviderFromConfig, messagesToOpenAI, mistralWireFormat, normalizeAnthropic, normalizeOpenAI, openaiWireFormat, parseProviderHttpError, toolsToAnthropic, toolsToOpenAI };
1908
+ export { AnthropicProvider, CAPABILITIES_BY_FAMILY, GoogleProvider, OpenAICompatibleProvider, OpenAIProvider, WireAdapter, WireFormatProvider, anthropicWireFormat, buildProviderFactoriesFromRegistry, capabilitiesFor, capabilitiesForFamily, contentFromAnthropic, contentFromOpenAI, createWireFormatFactory, defineWireFormat, googleWireFormat, makeProviderFromConfig, messagesToOpenAI, mistralWireFormat, normalizeAnthropic, normalizeOpenAI, openaiWireFormat, parseProviderHttpError, toolsToAnthropic, toolsToOpenAI };
1920
1909
  //# sourceMappingURL=index.js.map
1921
1910
  //# sourceMappingURL=index.js.map