@agentskit/adapters 0.17.4 → 0.18.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.
@@ -1,6 +1,6 @@
1
1
  import { JSONSchema7 } from 'json-schema';
2
2
  import { AdapterFactory } from '@agentskit/core';
3
- import { R as RetryOptions } from '../utils-ddwu4MN4.cjs';
3
+ import { R as RetryOptions } from '../retry-Bc6xtQCm.cjs';
4
4
 
5
5
  /**
6
6
  * AgentsKit provider/model catalog — normalized metadata adapted from the
@@ -1,6 +1,6 @@
1
1
  import { JSONSchema7 } from 'json-schema';
2
2
  import { AdapterFactory } from '@agentskit/core';
3
- import { R as RetryOptions } from '../utils-ddwu4MN4.js';
3
+ import { R as RetryOptions } from '../retry-Bc6xtQCm.js';
4
4
 
5
5
  /**
6
6
  * AgentsKit provider/model catalog — normalized metadata adapted from the
@@ -1,4 +1,4 @@
1
- import { openai } from '../chunk-ICIKG7XA.js';
1
+ import { openai } from '../chunk-MJDQXBVD.js';
2
2
  import '../chunk-6CIB2QCH.js';
3
3
 
4
4
  // src/catalog/schema.ts
@@ -1,25 +1,76 @@
1
- import { adapterErrorChunk, parseCompleteToolArgs, cancelBody, abortableSleep, isAbortError } from './chunk-6CIB2QCH.js';
1
+ import { cancelBody, abortableSleep, isAbortError, adapterErrorChunk, parseCompleteToolArgs } from './chunk-6CIB2QCH.js';
2
+ import { AdapterError, ErrorCodes } from '@agentskit/core';
3
+ import { retry, parseRetryAfter, sleep, parseSSE } from '@agentskit/net';
2
4
 
3
- // src/stream-lines.ts
4
- async function* readSSELines(stream) {
5
- const reader = stream.getReader();
6
- const decoder = new TextDecoder();
7
- let buffer = "";
5
+ var DEFAULT_RETRY = {
6
+ maxAttempts: 3,
7
+ baseDelayMs: 500,
8
+ maxDelayMs: 8e3,
9
+ jitter: true,
10
+ retryOn: ({ error, response }) => {
11
+ if (response) return [408, 429, 500, 502, 503, 504].includes(response.status);
12
+ if (isAbortError(error)) return false;
13
+ return true;
14
+ }
15
+ };
16
+ var RetryableResponse = class extends Error {
17
+ constructor(response, retryAfterMs) {
18
+ super(`HTTP ${response.status}`);
19
+ this.response = response;
20
+ this.retryAfterMs = retryAfterMs;
21
+ }
22
+ };
23
+ async function fetchWithRetry(doFetch, signal, retryOpt = {}) {
24
+ const opts = { ...DEFAULT_RETRY, ...retryOpt };
25
+ const maxAttempts = Math.floor(opts.maxAttempts);
26
+ if (!Number.isFinite(maxAttempts) || maxAttempts < 1) {
27
+ throw new AdapterError({
28
+ code: ErrorCodes.AK_CONFIG_INVALID,
29
+ message: "Retry maxAttempts must be finite and at least 1 after flooring"
30
+ });
31
+ }
32
+ if (signal.aborted) throw new DOMException("Aborted", "AbortError");
8
33
  try {
9
- while (true) {
10
- const { done, value } = await reader.read();
11
- if (done) break;
12
- buffer += decoder.decode(value, { stream: true });
13
- const lines = buffer.split("\n");
14
- buffer = lines.pop() ?? "";
15
- for (const line of lines) {
16
- if (!line.startsWith("data: ")) continue;
17
- const data = line.slice(6).trim();
18
- if (data) yield data;
34
+ return await retry(async ({ attempt }) => {
35
+ let response;
36
+ try {
37
+ response = await doFetch(signal);
38
+ } catch (error) {
39
+ if (signal.aborted) throw new DOMException("Aborted", "AbortError");
40
+ throw error;
19
41
  }
20
- }
21
- } finally {
22
- reader.releaseLock();
42
+ if (response.ok || attempt >= maxAttempts || !opts.retryOn({ response, attempt })) return response;
43
+ const retryAfter = parseRetryAfter(response.headers.get("retry-after"));
44
+ await cancelBody(response.body);
45
+ throw new RetryableResponse(
46
+ response,
47
+ retryAfter === void 0 ? void 0 : Math.min(retryAfter, opts.maxDelayMs)
48
+ );
49
+ }, {
50
+ retries: maxAttempts - 1,
51
+ minDelayMs: opts.baseDelayMs,
52
+ maxDelayMs: opts.maxDelayMs,
53
+ jitter: opts.jitter ? "full" : "none",
54
+ shouldRetry: (error, attempt) => {
55
+ if (error instanceof RetryableResponse) return true;
56
+ if (isAbortError(error)) return false;
57
+ return opts.retryOn({ error, attempt });
58
+ },
59
+ delayFor: (error) => error instanceof RetryableResponse ? error.retryAfterMs : void 0,
60
+ onRetry: ({ error, attempt, delayMs }) => {
61
+ retryOpt.onRetry?.({
62
+ attempt,
63
+ delayMs,
64
+ reason: error instanceof Error ? error.message : String(error)
65
+ });
66
+ },
67
+ sleep: retryOpt.sleep ? (ms, retrySignal) => abortableSleep(ms, retrySignal ?? signal, retryOpt.sleep) : sleep,
68
+ signal
69
+ });
70
+ } catch (error) {
71
+ if (signal.aborted) throw new DOMException("Aborted", "AbortError");
72
+ if (error instanceof RetryableResponse) return error.response;
73
+ throw error;
23
74
  }
24
75
  }
25
76
  async function* readNDJSONLines(stream) {
@@ -29,8 +80,12 @@ async function* readNDJSONLines(stream) {
29
80
  try {
30
81
  while (true) {
31
82
  const { done, value } = await reader.read();
32
- if (done) break;
33
- buffer += decoder.decode(value, { stream: true });
83
+ buffer += done ? decoder.decode() : decoder.decode(value, { stream: true });
84
+ if (done) {
85
+ const trimmed = buffer.trim();
86
+ if (trimmed) yield trimmed;
87
+ break;
88
+ }
34
89
  const lines = buffer.split("\n");
35
90
  buffer = lines.pop() ?? "";
36
91
  for (const line of lines) {
@@ -42,8 +97,6 @@ async function* readNDJSONLines(stream) {
42
97
  reader.releaseLock();
43
98
  }
44
99
  }
45
-
46
- // src/openai-stream.ts
47
100
  var SUCCESS_FINISH_REASONS = /* @__PURE__ */ new Set(["stop", "tool_calls", "function_call"]);
48
101
  async function* parseOpenAIStream(stream) {
49
102
  const pendingToolCalls = /* @__PURE__ */ new Map();
@@ -75,7 +128,7 @@ async function* parseOpenAIStream(stream) {
75
128
  pendingToolCalls.clear();
76
129
  return true;
77
130
  };
78
- for await (const data of readSSELines(stream)) {
131
+ for await (const { data } of parseSSE(stream)) {
79
132
  if (data === "[DONE]") {
80
133
  if (finishReason !== void 0 && !SUCCESS_FINISH_REASONS.has(finishReason)) {
81
134
  pendingToolCalls.clear();
@@ -197,7 +250,7 @@ async function* parseAnthropicStream(stream) {
197
250
  };
198
251
  return true;
199
252
  };
200
- for await (const data of readSSELines(stream)) {
253
+ for await (const { data } of parseSSE(stream)) {
201
254
  if (data === "[DONE]") continue;
202
255
  try {
203
256
  const event = JSON.parse(data);
@@ -278,7 +331,7 @@ var GEMINI_SUCCESS_FINISH = /* @__PURE__ */ new Set([
278
331
  ]);
279
332
  async function* parseGeminiStream(stream) {
280
333
  let finishReason;
281
- for await (const data of readSSELines(stream)) {
334
+ for await (const { data } of parseSSE(stream)) {
282
335
  try {
283
336
  const event = JSON.parse(data);
284
337
  if (event.usageMetadata) {
@@ -395,70 +448,6 @@ async function* parseOllamaStream(stream) {
395
448
  }
396
449
  yield { type: "done" };
397
450
  }
398
- var DEFAULT_RETRY = {
399
- maxAttempts: 3,
400
- baseDelayMs: 500,
401
- maxDelayMs: 8e3,
402
- jitter: true,
403
- retryOn: ({ error, response }) => {
404
- if (response) {
405
- return [408, 429, 500, 502, 503, 504].includes(response.status);
406
- }
407
- if (isAbortError(error)) return false;
408
- return true;
409
- }
410
- };
411
- function defaultSleep(ms) {
412
- return new Promise((resolve) => setTimeout(resolve, ms));
413
- }
414
- function computeDelay(attempt, opts) {
415
- const exp = Math.min(opts.maxDelayMs, opts.baseDelayMs * Math.pow(2, attempt - 1));
416
- if (!opts.jitter) return exp;
417
- return Math.floor(Math.random() * exp);
418
- }
419
- function parseRetryAfter(value, maxDelayMs) {
420
- if (!value) return void 0;
421
- const n = Number(value);
422
- if (Number.isFinite(n) && n >= 0) return Math.min(n * 1e3, maxDelayMs);
423
- const date = Date.parse(value);
424
- if (!Number.isNaN(date)) return Math.min(maxDelayMs, Math.max(0, date - Date.now()));
425
- return void 0;
426
- }
427
- async function fetchWithRetry(doFetch, signal, retryOpt = {}) {
428
- const opts = {
429
- ...DEFAULT_RETRY,
430
- ...retryOpt
431
- };
432
- const sleep = retryOpt.sleep ?? defaultSleep;
433
- let lastError;
434
- for (let attempt = 1; attempt <= opts.maxAttempts; attempt++) {
435
- if (signal.aborted) throw new DOMException("Aborted", "AbortError");
436
- try {
437
- const response = await doFetch(signal);
438
- if (response.ok) return response;
439
- if (attempt >= opts.maxAttempts || !opts.retryOn({ response, attempt })) {
440
- return response;
441
- }
442
- const retryAfterMs = parseRetryAfter(response.headers.get("retry-after"), opts.maxDelayMs);
443
- const delay = retryAfterMs ?? computeDelay(attempt, opts);
444
- retryOpt.onRetry?.({ attempt, delayMs: delay, reason: `HTTP ${response.status}` });
445
- await cancelBody(response.body);
446
- await abortableSleep(delay, signal, sleep);
447
- } catch (err) {
448
- lastError = err;
449
- if (isAbortError(err)) throw err;
450
- if (attempt >= opts.maxAttempts || !opts.retryOn({ error: err, attempt })) throw err;
451
- const delay = computeDelay(attempt, opts);
452
- retryOpt.onRetry?.({
453
- attempt,
454
- delayMs: delay,
455
- reason: err instanceof Error ? err.message : String(err)
456
- });
457
- await abortableSleep(delay, signal, sleep);
458
- }
459
- }
460
- throw lastError ?? new Error("fetchWithRetry: exhausted attempts");
461
- }
462
451
  function chunkText(text, targetSize = 32) {
463
452
  if (text.length <= targetSize) return [text];
464
453
  const out = [];
@@ -475,14 +464,14 @@ function chunkText(text, targetSize = 32) {
475
464
  return out;
476
465
  }
477
466
  function simulateStream(doFetch, extractText, errorLabel, options = {}) {
478
- const { chunkSize = 32, delayMs = 8, retry } = options;
467
+ const { chunkSize = 32, delayMs = 8, retry: retry2 } = options;
479
468
  let abortController = new AbortController();
480
469
  return {
481
470
  stream: async function* () {
482
471
  const controller = abortController;
483
472
  if (!controller) return;
484
473
  try {
485
- const response = await fetchWithRetry(doFetch, controller.signal, retry ?? {});
474
+ const response = await fetchWithRetry(doFetch, controller.signal, retry2 ?? {});
486
475
  if (!response.ok) {
487
476
  await cancelBody(response.body);
488
477
  yield adapterErrorChunk(`${errorLabel} error: ${response.status}`);
@@ -502,7 +491,7 @@ function simulateStream(doFetch, extractText, errorLabel, options = {}) {
502
491
  for (const chunk of chunks) {
503
492
  if (abortController === null || controller.signal.aborted) return;
504
493
  if (delayMs > 0) {
505
- await abortableSleep(delayMs, controller.signal, defaultSleep);
494
+ await abortableSleep(delayMs, controller.signal, sleep);
506
495
  }
507
496
  yield { type: "text", content: chunk };
508
497
  }
@@ -521,14 +510,14 @@ function simulateStream(doFetch, extractText, errorLabel, options = {}) {
521
510
  }
522
511
 
523
512
  // src/stream-source.ts
524
- function createStreamSource(doFetch, parse, errorLabel, retry) {
513
+ function createStreamSource(doFetch, parse, errorLabel, retry2) {
525
514
  let abortController = new AbortController();
526
515
  return {
527
516
  stream: async function* () {
528
517
  const controller = abortController;
529
518
  if (!controller) return;
530
519
  try {
531
- const response = await fetchWithRetry(doFetch, controller.signal, retry ?? {});
520
+ const response = await fetchWithRetry(doFetch, controller.signal, retry2 ?? {});
532
521
  if (!response.ok) {
533
522
  await cancelBody(response.body);
534
523
  yield adapterErrorChunk(`${errorLabel} error: ${response.status}`);
@@ -557,7 +546,7 @@ function createStreamSource(doFetch, parse, errorLabel, retry) {
557
546
 
558
547
  // src/openai.ts
559
548
  function openai(config) {
560
- const { apiKey, model, baseUrl = "https://api.openai.com", retry } = config;
549
+ const { apiKey, model, baseUrl = "https://api.openai.com", retry: retry2 } = config;
561
550
  const apiRoot = baseUrl.replace(/\/v1\/?$/, "");
562
551
  const isCanonicalOpenAI = (() => {
563
552
  try {
@@ -607,12 +596,12 @@ function openai(config) {
607
596
  }),
608
597
  parseOpenAIStream,
609
598
  "OpenAI API",
610
- retry
599
+ retry2
611
600
  );
612
601
  }
613
602
  };
614
603
  }
615
604
 
616
- export { chunkText, createStreamSource, fetchWithRetry, openai, parseAnthropicStream, parseGeminiStream, parseOllamaStream, parseOpenAIStream, readSSELines, simulateStream, toProviderMessages };
617
- //# sourceMappingURL=chunk-ICIKG7XA.js.map
618
- //# sourceMappingURL=chunk-ICIKG7XA.js.map
605
+ export { chunkText, createStreamSource, fetchWithRetry, openai, parseAnthropicStream, parseGeminiStream, parseOllamaStream, parseOpenAIStream, simulateStream, toProviderMessages };
606
+ //# sourceMappingURL=chunk-MJDQXBVD.js.map
607
+ //# sourceMappingURL=chunk-MJDQXBVD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/retry.ts","../src/stream-lines.ts","../src/openai-stream.ts","../src/utils.ts","../src/stream-source.ts","../src/openai.ts"],"names":["netSleep","parseSSE","retry"],"mappings":"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","file":"chunk-MJDQXBVD.js","sourcesContent":["import { AdapterError, ErrorCodes } from '@agentskit/core'\nimport { parseRetryAfter, retry, sleep as netSleep } from '@agentskit/net'\nimport { abortableSleep, cancelBody, isAbortError } from './stream-errors'\n\n/**\n * Retry policy for adapter fetches only: 3 total attempts, 500 ms base, 8000 ms\n * cap, full jitter, statuses 408/429/500/502/503/504, and non-abort transport\n * errors. Positive fractional attempts floor; invalid values reject with\n * `AK_CONFIG_INVALID` without making a request.\n * @example `const retry: RetryOptions = { maxAttempts: 4, retryOn: ({ response }) => response?.status === 429 }`\n */\nexport interface RetryOptions {\n /** Total fetch attempts, including the first. Default 3. */\n maxAttempts?: number\n /** First retry delay before jitter. Default 500 ms. */\n baseDelayMs?: number\n /** Maximum backoff and Retry-After delay. Default 8000 ms. */\n maxDelayMs?: number\n /** Enable full jitter. Default true. */\n jitter?: boolean\n /** Select failed responses or errors to retry. */\n retryOn?: (info: { error?: unknown; response?: Response; attempt: number }) => boolean\n /** Called immediately before a retry wait; thrown errors fail the retry operation. */\n onRetry?: (info: { attempt: number; delayMs: number; reason: string }) => void\n /** One-argument wait override. Default uses `@agentskit/net`'s abortable sleep. */\n sleep?: (ms: number) => Promise<void>\n}\n\nconst DEFAULT_RETRY: Required<Omit<RetryOptions, 'onRetry' | 'sleep' | 'retryOn'>> & {\n retryOn: NonNullable<RetryOptions['retryOn']>\n} = {\n maxAttempts: 3,\n baseDelayMs: 500,\n maxDelayMs: 8000,\n jitter: true,\n retryOn: ({ error, response }) => {\n if (response) return [408, 429, 500, 502, 503, 504].includes(response.status)\n if (isAbortError(error)) return false\n return true\n },\n}\n\nclass RetryableResponse extends Error {\n constructor(\n readonly response: Response,\n readonly retryAfterMs?: number,\n ) {\n super(`HTTP ${response.status}`)\n }\n}\n\n/**\n * Run `doFetch` with retries; return the final response on status exhaustion\n * and propagate the final transport error. Only the initial fetch retries;\n * errors from `onRetry` or custom `sleep` stop the operation.\n * @deprecated Use `retry` from `@agentskit/net`; keep this wrapper through at\n * least adapters 0.20.0 or 90 days after deprecation, whichever is later.\n * @param doFetch Called once per attempt with the caller's abort signal.\n * @param signal Caller-owned; abort rejects with `AbortError`.\n * @param retryOpt Defaults to 3 attempts, 500/8000 ms, full jitter, and\n * statuses 408/429/500/502/503/504.\n * @returns The successful or final response.\n * @throws {Error} The final transport error or `AbortError`.\n * @throws {AdapterError} `AK_CONFIG_INVALID` for invalid `maxAttempts`.\n * @example `const response = await fetchWithRetry(signal => fetch(url, { signal }), controller.signal)`\n */\nexport async function fetchWithRetry(\n doFetch: (signal: AbortSignal) => Promise<Response>,\n signal: AbortSignal,\n retryOpt: RetryOptions = {},\n): Promise<Response> {\n const opts = { ...DEFAULT_RETRY, ...retryOpt }\n const maxAttempts = Math.floor(opts.maxAttempts)\n if (!Number.isFinite(maxAttempts) || maxAttempts < 1) {\n throw new AdapterError({\n code: ErrorCodes.AK_CONFIG_INVALID,\n message: 'Retry maxAttempts must be finite and at least 1 after flooring',\n })\n }\n if (signal.aborted) throw new DOMException('Aborted', 'AbortError')\n\n try {\n return await retry(async ({ attempt }) => {\n let response: Response\n try {\n response = await doFetch(signal)\n } catch (error) {\n if (signal.aborted) throw new DOMException('Aborted', 'AbortError')\n throw error\n }\n\n if (response.ok || attempt >= maxAttempts || !opts.retryOn({ response, attempt })) return response\n\n const retryAfter = parseRetryAfter(response.headers.get('retry-after'))\n await cancelBody(response.body)\n throw new RetryableResponse(\n response,\n retryAfter === undefined ? undefined : Math.min(retryAfter, opts.maxDelayMs),\n )\n }, {\n retries: maxAttempts - 1,\n minDelayMs: opts.baseDelayMs,\n maxDelayMs: opts.maxDelayMs,\n jitter: opts.jitter ? 'full' : 'none',\n shouldRetry: (error, attempt) => {\n if (error instanceof RetryableResponse) return true\n if (isAbortError(error)) return false\n return opts.retryOn({ error, attempt })\n },\n delayFor: error => error instanceof RetryableResponse ? error.retryAfterMs : undefined,\n onRetry: ({ error, attempt, delayMs }) => {\n retryOpt.onRetry?.({\n attempt,\n delayMs,\n reason: error instanceof Error ? error.message : String(error),\n })\n },\n sleep: retryOpt.sleep\n ? (ms, retrySignal) => abortableSleep(ms, retrySignal ?? signal, retryOpt.sleep!)\n : netSleep,\n signal,\n })\n } catch (error) {\n if (signal.aborted) throw new DOMException('Aborted', 'AbortError')\n if (error instanceof RetryableResponse) return error.response\n throw error\n }\n}\n","import { parseSSE } from '@agentskit/net'\n\n/** Read data strings from Server-Sent Events through the shared network parser.\n *\n * @deprecated Use `parseSSE` from `@agentskit/net` and read each event's\n * `data` field. Removal is no earlier than adapters 0.20.0 and 90 days after\n * this deprecation, whichever is later.\n *\n * @param stream Byte stream containing Server-Sent Events.\n * @returns Event data strings; multiline data fields are joined with `\\n`.\n * @throws {NetError} With code AK_NET_SSE_PARSE_FAILED when the shared parser rejects an event.\n * @example\n * ```ts\n * for await (const data of readSSELines(response.body!)) console.log(data)\n * ```\n */\nexport async function* readSSELines(stream: ReadableStream): AsyncIterableIterator<string> {\n for await (const event of parseSSE(stream)) yield event.data\n}\n\n/**\n * Read non-empty, trimmed NDJSON lines from a UTF-8 byte stream. Flushes any\n * buffered UTF-8 bytes and yields a final line even when it has no newline.\n *\n * @param stream Byte stream containing one JSON value per line.\n * @returns Non-empty trimmed JSON line strings.\n * @example\n * ```ts\n * for await (const line of readNDJSONLines(response.body!)) console.log(JSON.parse(line))\n * ```\n */\nexport async function* readNDJSONLines(stream: ReadableStream): AsyncIterableIterator<string> {\n const reader = stream.getReader()\n const decoder = new TextDecoder()\n let buffer = ''\n\n try {\n while (true) {\n const { done, value } = await reader.read()\n buffer += done ? decoder.decode() : decoder.decode(value, { stream: true })\n if (done) {\n const trimmed = buffer.trim()\n if (trimmed) yield trimmed\n break\n }\n\n const lines = buffer.split('\\n')\n buffer = lines.pop() ?? ''\n\n for (const line of lines) {\n const trimmed = line.trim()\n if (trimmed) yield trimmed\n }\n }\n } finally {\n reader.releaseLock()\n }\n}\n","import type { StreamChunk } from '@agentskit/core'\nimport { parseSSE } from '@agentskit/net'\nimport { adapterErrorChunk, parseCompleteToolArgs } from './stream-errors'\n\nconst SUCCESS_FINISH_REASONS = new Set(['stop', 'tool_calls', 'function_call'])\n\nexport async function* parseOpenAIStream(stream: ReadableStream): AsyncIterableIterator<StreamChunk> {\n const pendingToolCalls = new Map<number, { id: string; name: string; args: string }>()\n let finishReason: string | undefined\n\n const terminalError = (message: string, extra?: Record<string, unknown>): StreamChunk => {\n const chunk = adapterErrorChunk(message)\n return {\n ...chunk,\n metadata: { ...chunk.metadata, ...extra, finishReason },\n }\n }\n\n const flushToolCalls = function* (): Generator<StreamChunk, boolean> {\n for (const [, toolCall] of pendingToolCalls) {\n const parsed = parseCompleteToolArgs(toolCall.args)\n if (!parsed.ok) {\n pendingToolCalls.clear()\n yield {\n type: 'error',\n content: parsed.error.message,\n metadata: { error: parsed.error, finishReason },\n }\n return false\n }\n yield {\n type: 'tool_call',\n toolCall: { id: toolCall.id, name: toolCall.name, args: parsed.args },\n }\n }\n pendingToolCalls.clear()\n return true\n }\n\n for await (const { data } of parseSSE(stream)) {\n if (data === '[DONE]') {\n if (finishReason !== undefined && !SUCCESS_FINISH_REASONS.has(finishReason)) {\n pendingToolCalls.clear()\n yield terminalError(\n `OpenAI stream ended with non-success finish reason \"${finishReason}\".`,\n { finishReason },\n )\n return\n }\n if (!(yield* flushToolCalls())) return\n yield { type: 'done' }\n return\n }\n\n try {\n const event = JSON.parse(data) as {\n choices?: Array<{\n delta?: {\n content?: string\n tool_calls?: Array<{\n index?: number\n id?: string\n function?: { name?: string; arguments?: string }\n }>\n }\n finish_reason?: string\n }>\n usage?: {\n prompt_tokens?: number\n completion_tokens?: number\n total_tokens?: number\n }\n }\n const delta = event.choices?.[0]?.delta\n const candidateFinishReason = event.choices?.find(\n choice => typeof choice.finish_reason === 'string',\n )?.finish_reason\n if (typeof candidateFinishReason === 'string') finishReason = candidateFinishReason\n\n if (typeof delta?.content === 'string') yield { type: 'text', content: delta.content }\n\n if (Array.isArray(delta?.tool_calls)) {\n for (const toolCall of delta.tool_calls) {\n const index: number = toolCall.index ?? 0\n const existing = pendingToolCalls.get(index)\n if (toolCall?.function?.name) {\n pendingToolCalls.set(index, {\n id: toolCall.id ?? existing?.id ?? `tool-${index}-${Date.now()}`,\n name: toolCall.function.name,\n args: (existing?.args ?? '') + (toolCall.function.arguments ?? ''),\n })\n } else if (existing && toolCall?.function?.arguments) {\n existing.args += toolCall.function.arguments\n }\n }\n }\n\n if (event.usage) {\n yield {\n type: 'usage',\n usage: {\n promptTokens: event.usage.prompt_tokens ?? 0,\n completionTokens: event.usage.completion_tokens ?? 0,\n totalTokens: event.usage.total_tokens ?? 0,\n },\n } as StreamChunk\n }\n } catch {\n // Ignore malformed events.\n }\n }\n\n if (finishReason !== undefined && !SUCCESS_FINISH_REASONS.has(finishReason)) {\n pendingToolCalls.clear()\n yield terminalError(\n `OpenAI stream ended with non-success finish reason \"${finishReason}\".`,\n { finishReason },\n )\n return\n }\n if (!finishReason) {\n pendingToolCalls.clear()\n yield terminalError('OpenAI stream ended before a terminal marker.')\n return\n }\n\n if (!(yield* flushToolCalls())) return\n yield { type: 'done' }\n}\n","import { type Message, type StreamChunk, type StreamSource } from '@agentskit/core'\nimport { parseSSE, sleep as netSleep } from '@agentskit/net'\nimport { fetchWithRetry, type RetryOptions } from './retry'\nimport { readNDJSONLines } from './stream-lines'\nimport {\n abortableSleep,\n adapterErrorChunk,\n cancelBody,\n isAbortError,\n parseCompleteToolArgs,\n} from './stream-errors'\n\nexport { fetchWithRetry }\nexport type { RetryOptions }\nexport { parseOpenAIStream } from './openai-stream'\nexport { readNDJSONLines, readSSELines } from './stream-lines'\nexport type { StreamParser } from './stream-types'\n\nexport function toProviderMessages(messages: Message[]) {\n // Track which tool_call ids were declared by preceding assistant turns so\n // we can drop orphan tool messages — the OpenAI Chat Completions API\n // rejects a tool message whose tool_call_id isn't bound to a previous\n // assistant message.\n const knownToolCallIds = new Set<string>()\n const output: Array<Record<string, unknown>> = []\n\n for (const message of messages) {\n if (message.role === 'tool') {\n const id = message.toolCallId\n // Orphan (no id, or id not declared) — skip; it would 400 the API.\n if (!id || !knownToolCallIds.has(id)) continue\n output.push({\n role: 'tool' as const,\n content: message.content,\n tool_call_id: id,\n })\n continue\n }\n\n if (message.role === 'assistant' && message.toolCalls && message.toolCalls.length > 0) {\n for (const tc of message.toolCalls) knownToolCallIds.add(tc.id)\n output.push({\n role: 'assistant' as const,\n content: message.content || null,\n tool_calls: message.toolCalls.map(tc => ({\n id: tc.id,\n type: 'function' as const,\n function: {\n name: tc.name,\n arguments: typeof tc.args === 'string' ? tc.args : JSON.stringify(tc.args ?? {}),\n },\n })),\n })\n continue\n }\n\n // Skip assistant messages with no content AND no tool calls. These\n // happen when a turn was interrupted (Ctrl+C, crashed adapter, etc.)\n // and the placeholder assistant message never received content —\n // sending `{role:'assistant', content:''}` back to the provider either\n // 400s or confuses the model into silence on the next turn.\n if (message.role === 'assistant' && !message.content) continue\n\n output.push({ role: message.role, content: message.content })\n }\n\n return output\n}\nexport async function* parseAnthropicStream(stream: ReadableStream): AsyncIterableIterator<StreamChunk> {\n const pendingToolCalls = new Map<number, { id: string; name: string; args: string }>()\n let sawMessageStop = false\n\n const emitToolCall = function* (\n tc: { id: string; name: string; args: string },\n ): Generator<StreamChunk, boolean> {\n const parsed = parseCompleteToolArgs(tc.args)\n if (!parsed.ok) {\n yield {\n type: 'error',\n content: parsed.error.message,\n metadata: { error: parsed.error },\n }\n return false\n }\n yield {\n type: 'tool_call',\n toolCall: { id: tc.id, name: tc.name, args: parsed.args },\n }\n return true\n }\n\n for await (const { data } of parseSSE(stream)) {\n if (data === '[DONE]') continue\n\n try {\n const event = JSON.parse(data) as {\n type?: string\n index?: number\n delta?: { type?: string; text?: string; partial_json?: string }\n content_block?: { type?: string; id?: string; name?: string }\n usage?: { input_tokens?: number; output_tokens?: number }\n message?: { usage?: { input_tokens?: number } }\n error?: { type?: string; message?: string }\n }\n\n if (event.type === 'error') {\n const msg =\n event.error?.message ??\n event.error?.type ??\n 'Anthropic stream error'\n yield adapterErrorChunk(String(msg))\n return\n }\n\n if (event.type === 'content_block_delta' && event.delta?.type === 'text_delta' && event.delta?.text) {\n yield { type: 'text', content: event.delta.text }\n } else if (event.type === 'content_block_delta' && event.delta?.type === 'input_json_delta') {\n const index: number = event.index ?? 0\n const existing = pendingToolCalls.get(index)\n if (existing) {\n existing.args += event.delta.partial_json ?? ''\n }\n } else if (event.type === 'content_block_start' && event.content_block?.type === 'tool_use') {\n const index: number = event.index ?? 0\n pendingToolCalls.set(index, {\n id: event.content_block.id ?? `tool-${index}`,\n name: event.content_block.name ?? 'unknown',\n args: '',\n })\n } else if (event.type === 'content_block_stop') {\n const index: number = event.index ?? 0\n const tc = pendingToolCalls.get(index)\n if (tc) {\n if (!(yield* emitToolCall(tc))) {\n pendingToolCalls.clear()\n return\n }\n pendingToolCalls.delete(index)\n }\n } else if (event.type === 'message_delta' && event.usage) {\n yield {\n type: 'usage',\n usage: {\n promptTokens: event.usage.input_tokens ?? 0,\n completionTokens: event.usage.output_tokens ?? 0,\n totalTokens: (event.usage.input_tokens ?? 0) + (event.usage.output_tokens ?? 0),\n },\n } as StreamChunk\n } else if (event.type === 'message_start' && event.message?.usage) {\n yield {\n type: 'usage',\n usage: {\n promptTokens: event.message.usage.input_tokens ?? 0,\n completionTokens: 0,\n totalTokens: event.message.usage.input_tokens ?? 0,\n },\n } as StreamChunk\n } else if (event.type === 'message_stop') {\n sawMessageStop = true\n for (const [, tc] of pendingToolCalls) {\n if (!(yield* emitToolCall(tc))) {\n pendingToolCalls.clear()\n return\n }\n }\n pendingToolCalls.clear()\n yield { type: 'done' }\n return\n }\n } catch {\n // Ignore malformed events.\n }\n }\n\n pendingToolCalls.clear()\n if (!sawMessageStop) {\n yield adapterErrorChunk('Anthropic stream ended before message_stop')\n return\n }\n yield { type: 'done' }\n}\n\nconst GEMINI_SUCCESS_FINISH = new Set([\n 'STOP',\n 'stop',\n 'FINISH_REASON_STOP',\n])\n\nexport async function* parseGeminiStream(stream: ReadableStream): AsyncIterableIterator<StreamChunk> {\n let finishReason: string | undefined\n\n for await (const { data } of parseSSE(stream)) {\n try {\n const event = JSON.parse(data) as {\n usageMetadata?: {\n promptTokenCount?: number\n candidatesTokenCount?: number\n totalTokenCount?: number\n }\n candidates?: Array<{\n finishReason?: string\n content?: {\n parts?: Array<{\n text?: string\n functionCall?: { id?: string; name?: string; args?: unknown }\n }>\n }\n }>\n }\n\n if (event.usageMetadata) {\n yield {\n type: 'usage',\n usage: {\n promptTokens: event.usageMetadata.promptTokenCount ?? 0,\n completionTokens: event.usageMetadata.candidatesTokenCount ?? 0,\n totalTokens: event.usageMetadata.totalTokenCount ?? 0,\n },\n } as StreamChunk\n }\n\n const candidate = event.candidates?.[0]\n if (typeof candidate?.finishReason === 'string') {\n finishReason = candidate.finishReason\n }\n\n const parts = candidate?.content?.parts\n if (!Array.isArray(parts)) continue\n\n for (const part of parts) {\n if (typeof part.text === 'string' && part.text) {\n yield { type: 'text', content: part.text }\n } else if (part.functionCall) {\n const fc = part.functionCall\n const args =\n typeof fc.args === 'string' ? fc.args : JSON.stringify(fc.args ?? {})\n const parsed = parseCompleteToolArgs(args)\n if (!parsed.ok) {\n yield {\n type: 'error',\n content: parsed.error.message,\n metadata: { error: parsed.error },\n }\n return\n }\n yield {\n type: 'tool_call',\n toolCall: {\n id: fc.id ?? `${fc.name}-${Date.now()}`,\n name: fc.name ?? 'unknown',\n args: parsed.args,\n },\n }\n }\n }\n } catch {\n // Ignore malformed events.\n }\n }\n\n if (!finishReason || !GEMINI_SUCCESS_FINISH.has(finishReason)) {\n if (finishReason && !GEMINI_SUCCESS_FINISH.has(finishReason)) {\n yield adapterErrorChunk(\n `Gemini stream ended with non-success finish reason \"${finishReason}\"`,\n )\n return\n }\n yield adapterErrorChunk('Gemini stream ended without a successful finishReason')\n return\n }\n\n yield { type: 'done' }\n}\n\nexport async function* parseOllamaStream(stream: ReadableStream): AsyncIterableIterator<StreamChunk> {\n let sawDone = false\n\n for await (const data of readNDJSONLines(stream)) {\n try {\n const event = JSON.parse(data) as {\n message?: {\n content?: string\n tool_calls?: Array<{\n id?: string\n function?: { name?: string; arguments?: unknown }\n }>\n }\n done?: boolean\n prompt_eval_count?: number\n eval_count?: number\n }\n if (event.message?.content) {\n yield { type: 'text', content: event.message.content }\n }\n if (Array.isArray(event.message?.tool_calls)) {\n for (const tc of event.message.tool_calls) {\n if (tc?.function?.name) {\n const args =\n typeof tc.function.arguments === 'string'\n ? tc.function.arguments\n : JSON.stringify(tc.function.arguments ?? {})\n const parsed = parseCompleteToolArgs(args)\n if (!parsed.ok) {\n yield {\n type: 'error',\n content: parsed.error.message,\n metadata: { error: parsed.error },\n }\n return\n }\n yield {\n type: 'tool_call',\n toolCall: {\n id: tc.id ?? `${tc.function.name}-${Date.now()}`,\n name: tc.function.name,\n args: parsed.args,\n },\n }\n }\n }\n }\n if (event.done) {\n sawDone = true\n if (typeof event.prompt_eval_count === 'number' || typeof event.eval_count === 'number') {\n const promptTokens = event.prompt_eval_count ?? 0\n const completionTokens = event.eval_count ?? 0\n yield {\n type: 'usage',\n usage: {\n promptTokens,\n completionTokens,\n totalTokens: promptTokens + completionTokens,\n },\n } as StreamChunk\n }\n yield { type: 'done' }\n return\n }\n } catch {\n // Ignore malformed events.\n }\n }\n\n if (!sawDone) {\n yield adapterErrorChunk('Ollama stream ended without done:true')\n return\n }\n yield { type: 'done' }\n}\n\n/**\n * Chunk-splitter that turns one large string into N streamable text chunks.\n * Useful when a provider returns the full response in one shot and you\n * want to feed it to a UI that expects streaming.\n *\n * Default splits by whitespace boundaries with a target chunk size of ~32\n * characters.\n */\nexport function chunkText(text: string, targetSize = 32): string[] {\n if (text.length <= targetSize) return [text]\n const out: string[] = []\n let i = 0\n while (i < text.length) {\n let end = Math.min(text.length, i + targetSize)\n // Prefer to cut on whitespace within the next few chars\n if (end < text.length) {\n const nextSpace = text.indexOf(' ', end)\n if (nextSpace !== -1 && nextSpace - end <= 8) end = nextSpace + 1\n }\n out.push(text.slice(i, end))\n i = end\n }\n return out\n}\n\n/**\n * Build a StreamSource from a non-streaming fetch. The adapter is\n * auto-completing: it fetches once, then yields the text as a sequence\n * of chunks so UIs see the same streaming shape they'd see from a\n * native streaming provider.\n *\n * Use this when you're wiring a provider that only has a non-streaming\n * endpoint but you want consumers (useChat, the runtime) to get\n * identical ergonomics.\n */\nexport function simulateStream(\n doFetch: (signal: AbortSignal) => Promise<Response>,\n extractText: (response: Response) => Promise<string>,\n errorLabel: string,\n options: { chunkSize?: number; delayMs?: number; retry?: RetryOptions } = {},\n): StreamSource {\n const { chunkSize = 32, delayMs = 8, retry } = options\n let abortController: AbortController | null = new AbortController()\n\n return {\n stream: async function* (): AsyncIterableIterator<StreamChunk> {\n const controller = abortController\n if (!controller) return\n try {\n const response = await fetchWithRetry(doFetch, controller.signal, retry ?? {})\n\n if (!response.ok) {\n await cancelBody(response.body)\n yield adapterErrorChunk(`${errorLabel} error: ${response.status}`)\n return\n }\n\n let text: string\n try {\n text = await extractText(response)\n } catch (err) {\n await cancelBody(response.body)\n if (isAbortError(err)) return\n const message = err instanceof Error ? err.message : String(err)\n yield adapterErrorChunk(message, { cause: err })\n return\n }\n\n const chunks = chunkText(text, chunkSize)\n for (const chunk of chunks) {\n if (abortController === null || controller.signal.aborted) return\n if (delayMs > 0) {\n await abortableSleep(delayMs, controller.signal, netSleep)\n }\n yield { type: 'text', content: chunk }\n }\n yield { type: 'done' }\n } catch (err) {\n if (isAbortError(err)) return\n const message = err instanceof Error ? err.message : String(err)\n yield adapterErrorChunk(message, { cause: err })\n }\n },\n abort: () => {\n abortController?.abort()\n abortController = null\n },\n }\n}\n","import type { StreamChunk, StreamSource } from '@agentskit/core'\nimport { adapterErrorChunk, cancelBody, isAbortError } from './stream-errors'\nimport type { StreamParser } from './stream-types'\nimport { fetchWithRetry, type RetryOptions } from './utils'\n\nexport function createStreamSource(\n doFetch: (signal: AbortSignal) => Promise<Response>,\n parse: StreamParser,\n errorLabel: string,\n retry?: RetryOptions,\n): StreamSource {\n let abortController: AbortController | null = new AbortController()\n\n return {\n stream: async function* (): AsyncIterableIterator<StreamChunk> {\n const controller = abortController\n if (!controller) return\n try {\n const response = await fetchWithRetry(doFetch, controller.signal, retry ?? {})\n\n if (!response.ok) {\n await cancelBody(response.body)\n yield adapterErrorChunk(`${errorLabel} error: ${response.status}`)\n return\n }\n\n if (!response.body) {\n yield adapterErrorChunk(`${errorLabel} error: empty response body`)\n return\n }\n\n for await (const chunk of parse(response.body, response)) {\n if (controller.signal.aborted || abortController === null) return\n yield chunk\n }\n } catch (err) {\n if (isAbortError(err) || controller.signal.aborted || abortController === null) return\n const message = err instanceof Error ? err.message : String(err)\n yield adapterErrorChunk(message, { cause: err })\n }\n },\n abort: () => {\n abortController?.abort()\n abortController = null\n },\n }\n}\n","import type { AdapterCapabilities, AdapterFactory, AdapterRequest, StreamSource } from '@agentskit/core'\nimport { parseOpenAIStream, toProviderMessages, type RetryOptions } from './utils'\nimport { createStreamSource } from './stream-source'\n\nexport interface OpenAIConfig {\n apiKey: string\n model: string\n baseUrl?: string\n retry?: RetryOptions\n /**\n * Ask the provider to include token usage in the final stream chunk via\n * `stream_options: { include_usage: true }`. Off by default because some\n * OpenAI-compatible providers (OpenRouter proxies to a long tail of\n * backends) reject unknown params with a 4xx and break the whole stream.\n * Turn this on for vanilla `api.openai.com`.\n */\n includeUsage?: boolean\n /** Explicit capability facts for OpenAI-compatible providers with custom models. */\n capabilities?: Partial<AdapterCapabilities>\n}\n\nexport function openai(config: OpenAIConfig): AdapterFactory {\n const { apiKey, model, baseUrl = 'https://api.openai.com', retry } = config\n // Normalize: many compatible endpoints are declared WITH a trailing `/v1`\n // (together, mistral, fireworks, openrouter `/api/v1`, …) while others are\n // declared without it. We always append `/v1/chat/completions`, so strip a\n // trailing `/v1` first to avoid a double `/v1/v1/...` (→ 404).\n const apiRoot = baseUrl.replace(/\\/v1\\/?$/, '')\n // Auto: on for canonical OpenAI, off for every other compatible endpoint\n // where the param is a known source of 4xx surprises.\n // Match the canonical OpenAI host exactly — a substring/prefix check\n // would also accept `https://api.openai.com.evil.test`.\n const isCanonicalOpenAI = (() => {\n try {\n return new URL(baseUrl).host === 'api.openai.com'\n } catch {\n return false\n }\n })()\n const includeUsage = config.includeUsage ?? isCanonicalOpenAI\n\n return {\n capabilities: {\n streaming: true,\n tools: config.capabilities?.tools ?? true,\n // o1 / o3 models emit reasoning; older models don't. Accurate per-model\n // detection would need a model registry; 'true' is the safer default here.\n reasoning: config.capabilities?.reasoning ?? (model.startsWith('o1') || model.startsWith('o3')),\n multiModal: config.capabilities?.multiModal ?? (model.startsWith('gpt-4') || model.startsWith('o')),\n usage: true,\n ...config.capabilities,\n },\n createSource: (request: AdapterRequest): StreamSource => {\n const body: Record<string, unknown> = {\n model,\n messages: toProviderMessages(request.messages),\n tools: request.context?.tools?.map(tool => ({\n type: 'function',\n function: {\n name: tool.name,\n description: tool.description,\n parameters: tool.schema,\n },\n })),\n temperature: request.context?.temperature,\n max_tokens: request.context?.maxTokens,\n stream: true,\n }\n if (includeUsage) body.stream_options = { include_usage: true }\n\n return createStreamSource(\n (signal) => fetch(`${apiRoot}/v1/chat/completions`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n },\n body: JSON.stringify(body),\n signal,\n }),\n parseOpenAIStream,\n 'OpenAI API',\n retry,\n )\n },\n }\n}\n"]}