@agentskit/adapters 0.4.2 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _agentskit_core from '@agentskit/core';
2
- import { AdapterRequest, StreamChunk, AdapterFactory, EmbedFn } from '@agentskit/core';
2
+ import { AdapterRequest, StreamChunk, AdapterFactory, StreamSource, EmbedFn } from '@agentskit/core';
3
3
 
4
4
  interface CreateAdapterConfig {
5
5
  send: (request: AdapterRequest) => Promise<ReadableStream | Response>;
@@ -14,11 +14,75 @@ declare function createAdapter(config: CreateAdapterConfig): AdapterFactory;
14
14
 
15
15
  declare function generic(config: GenericAdapterConfig): AdapterFactory;
16
16
 
17
+ /**
18
+ * Retry knobs for adapter fetches. Tunable per call to createStreamSource.
19
+ *
20
+ * Default behavior:
21
+ * - 3 attempts total (1 initial + 2 retries)
22
+ * - exponential backoff: 500ms, 1000ms, 2000ms ... (capped at maxDelayMs)
23
+ * - full jitter on each delay
24
+ * - retry on HTTP 408, 429, 500, 502, 503, 504
25
+ * - retry on network errors (fetch throws)
26
+ * - DO NOT retry on 4xx other than 408/429 (those are bad requests / auth)
27
+ * - retries only the initial fetch — never mid-stream
28
+ * - respects Retry-After header when present
29
+ */
30
+ interface RetryOptions {
31
+ maxAttempts?: number;
32
+ baseDelayMs?: number;
33
+ maxDelayMs?: number;
34
+ jitter?: boolean;
35
+ retryOn?: (info: {
36
+ error?: unknown;
37
+ response?: Response;
38
+ attempt: number;
39
+ }) => boolean;
40
+ /** Hook for tests + logging. Called after every failed attempt. */
41
+ onRetry?: (info: {
42
+ attempt: number;
43
+ delayMs: number;
44
+ reason: string;
45
+ }) => void;
46
+ /** Sleep override for tests. Defaults to setTimeout. */
47
+ sleep?: (ms: number) => Promise<void>;
48
+ }
49
+ /**
50
+ * Run a fetch with retries on transient failures. Returns the final
51
+ * Response (whether successful or not — caller decides), or throws if
52
+ * the AbortSignal fires or all attempts fail with a thrown error.
53
+ */
54
+ declare function fetchWithRetry(doFetch: (signal: AbortSignal) => Promise<Response>, signal: AbortSignal, retryOpt?: RetryOptions): Promise<Response>;
55
+ /**
56
+ * Chunk-splitter that turns one large string into N streamable text chunks.
57
+ * Useful when a provider returns the full response in one shot and you
58
+ * want to feed it to a UI that expects streaming.
59
+ *
60
+ * Default splits by whitespace boundaries with a target chunk size of ~32
61
+ * characters.
62
+ */
63
+ declare function chunkText(text: string, targetSize?: number): string[];
64
+ /**
65
+ * Build a StreamSource from a non-streaming fetch. The adapter is
66
+ * auto-completing: it fetches once, then yields the text as a sequence
67
+ * of chunks so UIs see the same streaming shape they'd see from a
68
+ * native streaming provider.
69
+ *
70
+ * Use this when you're wiring a provider that only has a non-streaming
71
+ * endpoint but you want consumers (useChat, the runtime) to get
72
+ * identical ergonomics.
73
+ */
74
+ declare function simulateStream(doFetch: (signal: AbortSignal) => Promise<Response>, extractText: (response: Response) => Promise<string>, errorLabel: string, options?: {
75
+ chunkSize?: number;
76
+ delayMs?: number;
77
+ retry?: RetryOptions;
78
+ }): StreamSource;
79
+
17
80
  interface AnthropicConfig {
18
81
  apiKey: string;
19
82
  model: string;
20
83
  baseUrl?: string;
21
84
  maxTokens?: number;
85
+ retry?: RetryOptions;
22
86
  }
23
87
  declare function anthropic(config: AnthropicConfig): AdapterFactory;
24
88
 
@@ -26,6 +90,7 @@ interface OpenAIConfig {
26
90
  apiKey: string;
27
91
  model: string;
28
92
  baseUrl?: string;
93
+ retry?: RetryOptions;
29
94
  }
30
95
  declare function openai(config: OpenAIConfig): AdapterFactory;
31
96
 
@@ -33,6 +98,7 @@ interface GeminiConfig {
33
98
  apiKey: string;
34
99
  model: string;
35
100
  baseUrl?: string;
101
+ retry?: RetryOptions;
36
102
  }
37
103
  declare function gemini(config: GeminiConfig): AdapterFactory;
38
104
 
@@ -46,6 +112,7 @@ declare const grok: (config: OpenAICompatibleConfig) => _agentskit_core.AdapterF
46
112
  interface OllamaConfig {
47
113
  model: string;
48
114
  baseUrl?: string;
115
+ retry?: RetryOptions;
49
116
  }
50
117
  declare function ollama(config: OllamaConfig): AdapterFactory;
51
118
 
@@ -74,9 +141,90 @@ declare function langgraph(config: LangGraphConfig): AdapterFactory;
74
141
  interface VercelAIConfig {
75
142
  api: string;
76
143
  headers?: Record<string, string>;
144
+ retry?: RetryOptions;
77
145
  }
78
146
  declare function vercelAI(config: VercelAIConfig): AdapterFactory;
79
147
 
148
+ type MockResponse = StreamChunk[] | ((request: AdapterRequest) => StreamChunk[]);
149
+ interface MockAdapterOptions {
150
+ /**
151
+ * Static chunks, a request-aware function, or a sequence of responses
152
+ * (the i-th call returns the i-th item, looping when exhausted).
153
+ */
154
+ response: MockResponse | MockResponse[];
155
+ /** ms between yielded chunks. Default 0 (synchronous). */
156
+ delayMs?: number;
157
+ /** Track every request the adapter received. Useful for assertions. */
158
+ history?: AdapterRequest[];
159
+ }
160
+ /**
161
+ * A deterministic adapter for tests, demos, and dry-run experiments.
162
+ *
163
+ * Conforms to ADR 0001 — Adapter contract:
164
+ * - createSource is pure (A1) — no work until stream() runs
165
+ * - Always emits a terminal chunk (A3)
166
+ * - abort() is safe (A6)
167
+ * - Does not mutate input messages (A7)
168
+ *
169
+ * Examples:
170
+ *
171
+ * // Static
172
+ * const adapter = mockAdapter({
173
+ * response: [
174
+ * { type: 'text', content: 'Hello!' },
175
+ * { type: 'done' },
176
+ * ],
177
+ * })
178
+ *
179
+ * // Request-aware
180
+ * const adapter = mockAdapter({
181
+ * response: req => {
182
+ * const last = req.messages[req.messages.length - 1]?.content ?? ''
183
+ * return [
184
+ * { type: 'text', content: 'Echo: ' + last },
185
+ * { type: 'done' },
186
+ * ]
187
+ * },
188
+ * })
189
+ *
190
+ * // Sequenced — different output each call
191
+ * const adapter = mockAdapter({
192
+ * response: [
193
+ * [{ type: 'text', content: 'first' }, { type: 'done' }],
194
+ * [{ type: 'text', content: 'second' }, { type: 'done' }],
195
+ * ],
196
+ * })
197
+ */
198
+ declare function mockAdapter(options: MockAdapterOptions): AdapterFactory;
199
+ interface RecordedTurn {
200
+ /** ISO timestamp when this turn was recorded. */
201
+ recordedAt: string;
202
+ /** The request that produced this turn. */
203
+ request: AdapterRequest;
204
+ /** Every chunk yielded by the wrapped adapter. */
205
+ chunks: StreamChunk[];
206
+ }
207
+ type RecordingFixture = RecordedTurn[];
208
+ interface RecordingSink {
209
+ push(turn: RecordedTurn): void | Promise<void>;
210
+ }
211
+ /**
212
+ * Wrap a real adapter so every turn is captured to a sink. Use this in
213
+ * dev to build up a fixture, then replay with replayAdapter() in tests.
214
+ */
215
+ declare function recordingAdapter(inner: AdapterFactory, sink: RecordingSink): AdapterFactory;
216
+ /**
217
+ * In-memory recording sink — useful for tests and ephemeral capture.
218
+ */
219
+ declare function inMemorySink(): RecordingSink & {
220
+ fixture: RecordingFixture;
221
+ };
222
+ /**
223
+ * Replay an adapter from a recorded fixture. Each turn maps 1:1 to a
224
+ * recorded entry by index — call N replays fixture[N % fixture.length].
225
+ */
226
+ declare function replayAdapter(fixture: RecordingFixture): AdapterFactory;
227
+
80
228
  interface OpenAIEmbedderConfig {
81
229
  apiKey: string;
82
230
  model?: string;
@@ -116,4 +264,4 @@ interface KimiEmbedderConfig extends OpenAICompatibleEmbedderConfig {
116
264
  }
117
265
  declare const kimiEmbedder: (config: OpenAICompatibleEmbedderConfig) => _agentskit_core.EmbedFn;
118
266
 
119
- export { type AnthropicConfig, type CreateAdapterConfig, type DeepSeekConfig, type DeepSeekEmbedderConfig, type GeminiConfig, type GeminiEmbedderConfig, type GenericAdapterConfig, type GrokConfig, type GrokEmbedderConfig, type KimiConfig, type KimiEmbedderConfig, type LangChainConfig, type LangGraphConfig, type OllamaConfig, type OllamaEmbedderConfig, type OpenAICompatibleEmbedderConfig, type OpenAIConfig, type OpenAIEmbedderConfig, type VercelAIConfig, anthropic, createAdapter, createOpenAICompatibleEmbedder, deepseek, deepseekEmbedder, gemini, geminiEmbedder, generic, grok, grokEmbedder, kimi, kimiEmbedder, langchain, langgraph, ollama, ollamaEmbedder, openai, openaiEmbedder, vercelAI };
267
+ export { type AnthropicConfig, type CreateAdapterConfig, type DeepSeekConfig, type DeepSeekEmbedderConfig, type GeminiConfig, type GeminiEmbedderConfig, type GenericAdapterConfig, type GrokConfig, type GrokEmbedderConfig, type KimiConfig, type KimiEmbedderConfig, type LangChainConfig, type LangGraphConfig, type MockAdapterOptions, type MockResponse, type OllamaConfig, type OllamaEmbedderConfig, type OpenAICompatibleEmbedderConfig, type OpenAIConfig, type OpenAIEmbedderConfig, type RecordedTurn, type RecordingFixture, type RecordingSink, type RetryOptions, type VercelAIConfig, anthropic, chunkText, createAdapter, createOpenAICompatibleEmbedder, deepseek, deepseekEmbedder, fetchWithRetry, gemini, geminiEmbedder, generic, grok, grokEmbedder, inMemorySink, kimi, kimiEmbedder, langchain, langgraph, mockAdapter, ollama, ollamaEmbedder, openai, openaiEmbedder, recordingAdapter, replayAdapter, simulateStream, vercelAI };
package/dist/index.js CHANGED
@@ -253,12 +253,73 @@ async function* parseOllamaStream(stream) {
253
253
  }
254
254
  yield { type: "done" };
255
255
  }
256
- function createStreamSource(doFetch, parse, errorLabel) {
256
+ var DEFAULT_RETRY = {
257
+ maxAttempts: 3,
258
+ baseDelayMs: 500,
259
+ maxDelayMs: 8e3,
260
+ jitter: true,
261
+ retryOn: ({ error, response }) => {
262
+ if (response) {
263
+ return [408, 429, 500, 502, 503, 504].includes(response.status);
264
+ }
265
+ if (error instanceof DOMException && error.name === "AbortError") return false;
266
+ return true;
267
+ }
268
+ };
269
+ function defaultSleep(ms) {
270
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
271
+ }
272
+ function computeDelay(attempt, opts) {
273
+ const exp = Math.min(opts.maxDelayMs, opts.baseDelayMs * Math.pow(2, attempt - 1));
274
+ if (!opts.jitter) return exp;
275
+ return Math.floor(Math.random() * exp);
276
+ }
277
+ function parseRetryAfter(value) {
278
+ if (!value) return void 0;
279
+ const n = Number(value);
280
+ if (!Number.isNaN(n)) return n * 1e3;
281
+ const date = Date.parse(value);
282
+ if (!Number.isNaN(date)) return Math.max(0, date - Date.now());
283
+ return void 0;
284
+ }
285
+ async function fetchWithRetry(doFetch, signal, retryOpt = {}) {
286
+ const opts = {
287
+ ...DEFAULT_RETRY,
288
+ ...retryOpt
289
+ };
290
+ const sleep = retryOpt.sleep ?? defaultSleep;
291
+ let lastError;
292
+ for (let attempt = 1; attempt <= opts.maxAttempts; attempt++) {
293
+ if (signal.aborted) throw new DOMException("Aborted", "AbortError");
294
+ try {
295
+ const response = await doFetch(signal);
296
+ if (response.ok) return response;
297
+ if (attempt >= opts.maxAttempts || !opts.retryOn({ response, attempt })) {
298
+ return response;
299
+ }
300
+ const retryAfterMs = parseRetryAfter(response.headers.get("retry-after"));
301
+ const delay = retryAfterMs ?? computeDelay(attempt, opts);
302
+ retryOpt.onRetry?.({ attempt, delayMs: delay, reason: `HTTP ${response.status}` });
303
+ await sleep(delay);
304
+ response.body?.cancel().catch(() => {
305
+ });
306
+ } catch (err) {
307
+ lastError = err;
308
+ if (err instanceof DOMException && err.name === "AbortError") throw err;
309
+ if (attempt >= opts.maxAttempts || !opts.retryOn({ error: err, attempt })) throw err;
310
+ const delay = computeDelay(attempt, opts);
311
+ retryOpt.onRetry?.({ attempt, delayMs: delay, reason: err.message });
312
+ await sleep(delay);
313
+ }
314
+ }
315
+ throw lastError ?? new Error("fetchWithRetry: exhausted attempts");
316
+ }
317
+ function createStreamSource(doFetch, parse, errorLabel, retry) {
257
318
  let abortController = new AbortController();
258
319
  return {
259
320
  stream: async function* () {
260
321
  try {
261
- const response = await doFetch(abortController.signal);
322
+ const response = await fetchWithRetry(doFetch, abortController.signal, retry ?? {});
262
323
  if (!response.ok || !response.body) {
263
324
  yield { type: "error", content: `${errorLabel} error: ${response.status}` };
264
325
  return;
@@ -278,11 +339,78 @@ function createStreamSource(doFetch, parse, errorLabel) {
278
339
  }
279
340
  };
280
341
  }
342
+ function chunkText(text, targetSize = 32) {
343
+ if (text.length <= targetSize) return [text];
344
+ const out = [];
345
+ let i = 0;
346
+ while (i < text.length) {
347
+ let end = Math.min(text.length, i + targetSize);
348
+ if (end < text.length) {
349
+ const nextSpace = text.indexOf(" ", end);
350
+ if (nextSpace !== -1 && nextSpace - end <= 8) end = nextSpace + 1;
351
+ }
352
+ out.push(text.slice(i, end));
353
+ i = end;
354
+ }
355
+ return out;
356
+ }
357
+ function simulateStream(doFetch, extractText, errorLabel, options = {}) {
358
+ const { chunkSize = 32, delayMs = 8, retry } = options;
359
+ let abortController = new AbortController();
360
+ return {
361
+ stream: async function* () {
362
+ try {
363
+ const response = await fetchWithRetry(doFetch, abortController.signal, retry ?? {});
364
+ if (!response.ok) {
365
+ yield { type: "error", content: `${errorLabel} error: ${response.status}` };
366
+ return;
367
+ }
368
+ const text = await extractText(response);
369
+ const chunks = chunkText(text, chunkSize);
370
+ for (const chunk of chunks) {
371
+ if (abortController === null) return;
372
+ if (delayMs > 0) {
373
+ await new Promise((resolve2, reject) => {
374
+ const timer = setTimeout(resolve2, delayMs);
375
+ abortController?.signal.addEventListener(
376
+ "abort",
377
+ () => {
378
+ clearTimeout(timer);
379
+ reject(new DOMException("Aborted", "AbortError"));
380
+ },
381
+ { once: true }
382
+ );
383
+ });
384
+ }
385
+ yield { type: "text", content: chunk };
386
+ }
387
+ yield { type: "done" };
388
+ } catch (err) {
389
+ if (err instanceof DOMException && err.name === "AbortError") return;
390
+ yield {
391
+ type: "error",
392
+ content: err instanceof Error ? err.message : String(err)
393
+ };
394
+ }
395
+ },
396
+ abort: () => {
397
+ abortController?.abort();
398
+ abortController = null;
399
+ }
400
+ };
401
+ }
281
402
 
282
403
  // src/anthropic.ts
283
404
  function anthropic(config) {
284
- const { apiKey, model, baseUrl = "https://api.anthropic.com", maxTokens = 4096 } = config;
405
+ const { apiKey, model, baseUrl = "https://api.anthropic.com", maxTokens = 4096, retry } = config;
285
406
  return {
407
+ capabilities: {
408
+ streaming: true,
409
+ tools: true,
410
+ reasoning: model.includes("sonnet") || model.includes("opus"),
411
+ multiModal: true,
412
+ usage: true
413
+ },
286
414
  createSource: (request) => {
287
415
  const body = {
288
416
  model,
@@ -308,7 +436,8 @@ function anthropic(config) {
308
436
  signal
309
437
  }),
310
438
  parseAnthropicStream,
311
- "Anthropic API"
439
+ "Anthropic API",
440
+ retry
312
441
  );
313
442
  }
314
443
  };
@@ -316,8 +445,17 @@ function anthropic(config) {
316
445
 
317
446
  // src/openai.ts
318
447
  function openai(config) {
319
- const { apiKey, model, baseUrl = "https://api.openai.com" } = config;
448
+ const { apiKey, model, baseUrl = "https://api.openai.com", retry } = config;
320
449
  return {
450
+ capabilities: {
451
+ streaming: true,
452
+ tools: true,
453
+ // o1 / o3 models emit reasoning; older models don't. Accurate per-model
454
+ // detection would need a model registry; 'true' is the safer default here.
455
+ reasoning: model.startsWith("o1") || model.startsWith("o3"),
456
+ multiModal: model.startsWith("gpt-4") || model.startsWith("o"),
457
+ usage: true
458
+ },
321
459
  createSource: (request) => {
322
460
  const body = {
323
461
  model,
@@ -345,7 +483,8 @@ function openai(config) {
345
483
  signal
346
484
  }),
347
485
  parseOpenAIStream,
348
- "OpenAI API"
486
+ "OpenAI API",
487
+ retry
349
488
  );
350
489
  }
351
490
  };
@@ -353,8 +492,14 @@ function openai(config) {
353
492
 
354
493
  // src/gemini.ts
355
494
  function gemini(config) {
356
- const { apiKey, model, baseUrl = "https://generativelanguage.googleapis.com" } = config;
495
+ const { apiKey, model, baseUrl = "https://generativelanguage.googleapis.com", retry } = config;
357
496
  return {
497
+ capabilities: {
498
+ streaming: true,
499
+ tools: true,
500
+ multiModal: true,
501
+ usage: true
502
+ },
358
503
  createSource: (request) => {
359
504
  const body = {
360
505
  contents: request.messages.filter((message) => message.role !== "system").map((message) => ({
@@ -377,7 +522,8 @@ function gemini(config) {
377
522
  }
378
523
  ),
379
524
  parseGeminiStream,
380
- "Gemini API"
525
+ "Gemini API",
526
+ retry
381
527
  );
382
528
  }
383
529
  };
@@ -398,8 +544,14 @@ var grok = createOpenAICompatibleAdapter("https://api.x.ai");
398
544
 
399
545
  // src/ollama.ts
400
546
  function ollama(config) {
401
- const { model, baseUrl = "http://localhost:11434" } = config;
547
+ const { model, baseUrl = "http://localhost:11434", retry } = config;
402
548
  return {
549
+ capabilities: {
550
+ streaming: true,
551
+ tools: false,
552
+ // varies by model; default 'false' — enable via capabilities.extensions if your model supports it
553
+ multiModal: model.includes("llava") || model.includes("vision")
554
+ },
403
555
  createSource: (request) => {
404
556
  const body = {
405
557
  model,
@@ -417,7 +569,8 @@ function ollama(config) {
417
569
  signal
418
570
  }),
419
571
  parseOllamaStream,
420
- "Ollama API"
572
+ "Ollama API",
573
+ retry
421
574
  );
422
575
  }
423
576
  };
@@ -514,8 +667,12 @@ async function* parseVercelStream(stream) {
514
667
  yield { type: "done" };
515
668
  }
516
669
  function vercelAI(config) {
517
- const { api, headers = {} } = config;
670
+ const { api, headers = {}, retry } = config;
518
671
  return {
672
+ capabilities: {
673
+ // Vercel AI routes can do any of these — whether they do depends on
674
+ // your route handler. Omit the field instead of lying.
675
+ },
519
676
  createSource: (request) => {
520
677
  const body = {
521
678
  messages: request.messages.map((message) => ({ role: message.role, content: message.content })),
@@ -530,12 +687,105 @@ function vercelAI(config) {
530
687
  signal
531
688
  }),
532
689
  parseVercelStream,
533
- "API"
690
+ "API",
691
+ retry
534
692
  );
535
693
  }
536
694
  };
537
695
  }
538
696
 
697
+ // src/mock.ts
698
+ function mockAdapter(options) {
699
+ const { response, delayMs = 0, history } = options;
700
+ let callIndex = 0;
701
+ return {
702
+ capabilities: {
703
+ streaming: true,
704
+ tools: true,
705
+ reasoning: true,
706
+ multiModal: true,
707
+ usage: true
708
+ },
709
+ createSource: (request) => {
710
+ history?.push(request);
711
+ const myCall = callIndex++;
712
+ let cancelled = false;
713
+ return {
714
+ stream: async function* () {
715
+ const chunks = resolve(response, myCall, request);
716
+ let endedExplicitly = false;
717
+ for (const chunk of chunks) {
718
+ if (cancelled) return;
719
+ if (delayMs > 0) await new Promise((r) => setTimeout(r, delayMs));
720
+ yield chunk;
721
+ if (chunk.type === "done" || chunk.type === "error") {
722
+ endedExplicitly = true;
723
+ }
724
+ }
725
+ if (!endedExplicitly) yield { type: "done" };
726
+ },
727
+ abort: () => {
728
+ cancelled = true;
729
+ }
730
+ };
731
+ }
732
+ };
733
+ }
734
+ function resolve(response, callIndex, request) {
735
+ if (Array.isArray(response) && response.length > 0 && Array.isArray(response[0])) {
736
+ const sequence = response;
737
+ const item = sequence[callIndex % sequence.length];
738
+ return item;
739
+ }
740
+ if (Array.isArray(response) && response.length > 0 && typeof response[0] === "function") {
741
+ const sequence = response;
742
+ return sequence[callIndex % sequence.length](request);
743
+ }
744
+ if (typeof response === "function") {
745
+ return response(request);
746
+ }
747
+ return response;
748
+ }
749
+ function recordingAdapter(inner, sink) {
750
+ return {
751
+ createSource: (request) => {
752
+ const innerSource = inner.createSource(request);
753
+ const captured = [];
754
+ const recordedAt = (/* @__PURE__ */ new Date()).toISOString();
755
+ return {
756
+ stream: async function* () {
757
+ try {
758
+ for await (const chunk of innerSource.stream()) {
759
+ captured.push(chunk);
760
+ yield chunk;
761
+ }
762
+ } finally {
763
+ await sink.push({ recordedAt, request, chunks: captured });
764
+ }
765
+ },
766
+ abort: () => innerSource.abort()
767
+ };
768
+ }
769
+ };
770
+ }
771
+ function inMemorySink() {
772
+ const fixture = [];
773
+ return {
774
+ fixture,
775
+ push(turn) {
776
+ fixture.push(turn);
777
+ }
778
+ };
779
+ }
780
+ function replayAdapter(fixture) {
781
+ if (fixture.length === 0) {
782
+ throw new Error("replayAdapter: fixture is empty");
783
+ }
784
+ return mockAdapter({
785
+ response: fixture.map((turn) => turn.chunks)
786
+ });
787
+ }
788
+
539
789
  // src/embedders/openai.ts
540
790
  async function fetchAvailableModels(baseUrl, apiKey) {
541
791
  const response = await fetch(`${baseUrl}/v1/models`, {
@@ -730,6 +980,6 @@ var grokEmbedder = createOpenAICompatibleEmbedder("Grok", "https://api.x.ai");
730
980
  // src/embedders/kimi.ts
731
981
  var kimiEmbedder = createOpenAICompatibleEmbedder("Kimi", "https://api.moonshot.ai");
732
982
 
733
- export { anthropic, createAdapter, createOpenAICompatibleEmbedder, deepseek, deepseekEmbedder, gemini, geminiEmbedder, generic, grok, grokEmbedder, kimi, kimiEmbedder, langchain, langgraph, ollama, ollamaEmbedder, openai, openaiEmbedder, vercelAI };
983
+ export { anthropic, chunkText, createAdapter, createOpenAICompatibleEmbedder, deepseek, deepseekEmbedder, fetchWithRetry, gemini, geminiEmbedder, generic, grok, grokEmbedder, inMemorySink, kimi, kimiEmbedder, langchain, langgraph, mockAdapter, ollama, ollamaEmbedder, openai, openaiEmbedder, recordingAdapter, replayAdapter, simulateStream, vercelAI };
734
984
  //# sourceMappingURL=index.js.map
735
985
  //# sourceMappingURL=index.js.map