@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.
- package/README.md +2 -0
- package/dist/catalog/index.cjs +78 -93
- package/dist/catalog/index.cjs.map +1 -1
- package/dist/catalog/index.d.cts +1 -1
- package/dist/catalog/index.d.ts +1 -1
- package/dist/catalog/index.js +1 -1
- package/dist/{chunk-ICIKG7XA.js → chunk-MJDQXBVD.js} +89 -100
- package/dist/chunk-MJDQXBVD.js.map +1 -0
- package/dist/index.cjs +97 -112
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -4
- package/dist/index.d.ts +29 -4
- package/dist/index.js +4 -5
- package/dist/index.js.map +1 -1
- package/dist/retry-Bc6xtQCm.d.cts +49 -0
- package/dist/retry-Bc6xtQCm.d.ts +49 -0
- package/package.json +6 -5
- package/dist/chunk-ICIKG7XA.js.map +0 -1
- package/dist/utils-ddwu4MN4.d.cts +0 -66
- package/dist/utils-ddwu4MN4.d.ts +0 -66
package/dist/catalog/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { JSONSchema7 } from 'json-schema';
|
|
2
2
|
import { AdapterFactory } from '@agentskit/core';
|
|
3
|
-
import { R as RetryOptions } from '../
|
|
3
|
+
import { R as RetryOptions } from '../retry-Bc6xtQCm.cjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* AgentsKit provider/model catalog — normalized metadata adapted from the
|
package/dist/catalog/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { JSONSchema7 } from 'json-schema';
|
|
2
2
|
import { AdapterFactory } from '@agentskit/core';
|
|
3
|
-
import { R as RetryOptions } from '../
|
|
3
|
+
import { R as RetryOptions } from '../retry-Bc6xtQCm.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* AgentsKit provider/model catalog — normalized metadata adapted from the
|
package/dist/catalog/index.js
CHANGED
|
@@ -1,25 +1,76 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
22
|
-
|
|
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
|
-
|
|
33
|
-
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
-
|
|
599
|
+
retry2
|
|
611
600
|
);
|
|
612
601
|
}
|
|
613
602
|
};
|
|
614
603
|
}
|
|
615
604
|
|
|
616
|
-
export { chunkText, createStreamSource, fetchWithRetry, openai, parseAnthropicStream, parseGeminiStream, parseOllamaStream, parseOpenAIStream,
|
|
617
|
-
//# sourceMappingURL=chunk-
|
|
618
|
-
//# sourceMappingURL=chunk-
|
|
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"]}
|