reasonix 0.0.4 → 0.0.5
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 +133 -58
- package/dist/cli/index.js +716 -54
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +96 -6
- package/dist/index.js +460 -20
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-Y7L6L5QS.js +0 -262
- package/dist/chunk-Y7L6L5QS.js.map +0 -1
- package/dist/cli/chunk-T2ODXAJP.js +0 -263
- package/dist/cli/chunk-T2ODXAJP.js.map +0 -1
- package/dist/cli/client-RIVGDOJP.js +0 -10
- package/dist/cli/client-RIVGDOJP.js.map +0 -1
- package/dist/client-KEA2D52Q.js +0 -9
- package/dist/client-KEA2D52Q.js.map +0 -1
package/dist/chunk-Y7L6L5QS.js
DELETED
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
// src/client.ts
|
|
2
|
-
import { createParser } from "eventsource-parser";
|
|
3
|
-
|
|
4
|
-
// src/retry.ts
|
|
5
|
-
var DEFAULT_RETRYABLE_STATUSES = [408, 429, 500, 502, 503, 504];
|
|
6
|
-
async function fetchWithRetry(fetchFn, url, init, opts = {}) {
|
|
7
|
-
const maxAttempts = opts.maxAttempts ?? 4;
|
|
8
|
-
const initial = opts.initialBackoffMs ?? 500;
|
|
9
|
-
const cap = opts.maxBackoffMs ?? 1e4;
|
|
10
|
-
const retryable = new Set(opts.retryableStatuses ?? DEFAULT_RETRYABLE_STATUSES);
|
|
11
|
-
let lastError;
|
|
12
|
-
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
13
|
-
if (opts.signal?.aborted) throw new Error("aborted");
|
|
14
|
-
try {
|
|
15
|
-
const resp = await fetchFn(url, init);
|
|
16
|
-
if (resp.ok || !retryable.has(resp.status)) return resp;
|
|
17
|
-
if (attempt === maxAttempts - 1) return resp;
|
|
18
|
-
await resp.text().catch(() => void 0);
|
|
19
|
-
const waitMs = computeWait(attempt, initial, cap, resp.headers.get("Retry-After"));
|
|
20
|
-
opts.onRetry?.({ attempt: attempt + 1, reason: `http ${resp.status}`, waitMs });
|
|
21
|
-
await sleep(waitMs, opts.signal);
|
|
22
|
-
} catch (err) {
|
|
23
|
-
lastError = err;
|
|
24
|
-
if (isAbortError(err) || opts.signal?.aborted) throw err;
|
|
25
|
-
if (attempt === maxAttempts - 1) throw err;
|
|
26
|
-
const waitMs = computeWait(attempt, initial, cap, null);
|
|
27
|
-
opts.onRetry?.({
|
|
28
|
-
attempt: attempt + 1,
|
|
29
|
-
reason: `network: ${messageOf(err)}`,
|
|
30
|
-
waitMs
|
|
31
|
-
});
|
|
32
|
-
await sleep(waitMs, opts.signal);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
throw lastError ?? new Error("fetchWithRetry: loop exited unexpectedly");
|
|
36
|
-
}
|
|
37
|
-
function computeWait(attempt, initial, cap, retryAfter) {
|
|
38
|
-
if (retryAfter) {
|
|
39
|
-
const seconds = Number.parseFloat(retryAfter);
|
|
40
|
-
if (Number.isFinite(seconds) && seconds > 0) {
|
|
41
|
-
return Math.min(seconds * 1e3, cap);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
const exp = initial * 2 ** attempt;
|
|
45
|
-
const jitter = exp * (0.75 + Math.random() * 0.5);
|
|
46
|
-
return Math.min(Math.max(jitter, 0), cap);
|
|
47
|
-
}
|
|
48
|
-
function sleep(ms, signal) {
|
|
49
|
-
if (ms <= 0) return Promise.resolve();
|
|
50
|
-
return new Promise((resolve, reject) => {
|
|
51
|
-
const timer = setTimeout(resolve, ms);
|
|
52
|
-
if (signal) {
|
|
53
|
-
const onAbort = () => {
|
|
54
|
-
clearTimeout(timer);
|
|
55
|
-
reject(new Error("aborted"));
|
|
56
|
-
};
|
|
57
|
-
if (signal.aborted) onAbort();
|
|
58
|
-
else signal.addEventListener("abort", onAbort, { once: true });
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
function isAbortError(err) {
|
|
63
|
-
if (!err || typeof err !== "object") return false;
|
|
64
|
-
const name = err.name;
|
|
65
|
-
return name === "AbortError";
|
|
66
|
-
}
|
|
67
|
-
function messageOf(err) {
|
|
68
|
-
if (err instanceof Error) return err.message;
|
|
69
|
-
try {
|
|
70
|
-
return String(err);
|
|
71
|
-
} catch {
|
|
72
|
-
return "unknown error";
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// src/client.ts
|
|
77
|
-
var Usage = class _Usage {
|
|
78
|
-
constructor(promptTokens = 0, completionTokens = 0, totalTokens = 0, promptCacheHitTokens = 0, promptCacheMissTokens = 0) {
|
|
79
|
-
this.promptTokens = promptTokens;
|
|
80
|
-
this.completionTokens = completionTokens;
|
|
81
|
-
this.totalTokens = totalTokens;
|
|
82
|
-
this.promptCacheHitTokens = promptCacheHitTokens;
|
|
83
|
-
this.promptCacheMissTokens = promptCacheMissTokens;
|
|
84
|
-
}
|
|
85
|
-
promptTokens;
|
|
86
|
-
completionTokens;
|
|
87
|
-
totalTokens;
|
|
88
|
-
promptCacheHitTokens;
|
|
89
|
-
promptCacheMissTokens;
|
|
90
|
-
get cacheHitRatio() {
|
|
91
|
-
const denom = this.promptCacheHitTokens + this.promptCacheMissTokens;
|
|
92
|
-
return denom > 0 ? this.promptCacheHitTokens / denom : 0;
|
|
93
|
-
}
|
|
94
|
-
static fromApi(raw) {
|
|
95
|
-
const u = raw ?? {};
|
|
96
|
-
return new _Usage(
|
|
97
|
-
u.prompt_tokens ?? 0,
|
|
98
|
-
u.completion_tokens ?? 0,
|
|
99
|
-
u.total_tokens ?? 0,
|
|
100
|
-
u.prompt_cache_hit_tokens ?? 0,
|
|
101
|
-
u.prompt_cache_miss_tokens ?? 0
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
var DeepSeekClient = class {
|
|
106
|
-
apiKey;
|
|
107
|
-
baseUrl;
|
|
108
|
-
timeoutMs;
|
|
109
|
-
retry;
|
|
110
|
-
_fetch;
|
|
111
|
-
constructor(opts = {}) {
|
|
112
|
-
const apiKey = opts.apiKey ?? process.env.DEEPSEEK_API_KEY;
|
|
113
|
-
if (!apiKey) {
|
|
114
|
-
throw new Error(
|
|
115
|
-
"DEEPSEEK_API_KEY is not set. Put it in .env or pass apiKey to DeepSeekClient."
|
|
116
|
-
);
|
|
117
|
-
}
|
|
118
|
-
this.apiKey = apiKey;
|
|
119
|
-
this.baseUrl = (opts.baseUrl ?? process.env.DEEPSEEK_BASE_URL ?? "https://api.deepseek.com").replace(/\/+$/, "");
|
|
120
|
-
this.timeoutMs = opts.timeoutMs ?? 12e4;
|
|
121
|
-
this._fetch = opts.fetch ?? globalThis.fetch.bind(globalThis);
|
|
122
|
-
this.retry = opts.retry ?? {};
|
|
123
|
-
}
|
|
124
|
-
buildPayload(opts, stream) {
|
|
125
|
-
const payload = {
|
|
126
|
-
model: opts.model,
|
|
127
|
-
messages: opts.messages,
|
|
128
|
-
stream
|
|
129
|
-
};
|
|
130
|
-
if (opts.tools?.length) payload.tools = opts.tools;
|
|
131
|
-
if (opts.temperature !== void 0) payload.temperature = opts.temperature;
|
|
132
|
-
if (opts.maxTokens !== void 0) payload.max_tokens = opts.maxTokens;
|
|
133
|
-
if (opts.responseFormat) payload.response_format = opts.responseFormat;
|
|
134
|
-
return payload;
|
|
135
|
-
}
|
|
136
|
-
async chat(opts) {
|
|
137
|
-
const ctrl = new AbortController();
|
|
138
|
-
const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);
|
|
139
|
-
const signal = opts.signal ?? ctrl.signal;
|
|
140
|
-
try {
|
|
141
|
-
const resp = await fetchWithRetry(
|
|
142
|
-
this._fetch,
|
|
143
|
-
`${this.baseUrl}/chat/completions`,
|
|
144
|
-
{
|
|
145
|
-
method: "POST",
|
|
146
|
-
headers: {
|
|
147
|
-
Authorization: `Bearer ${this.apiKey}`,
|
|
148
|
-
"Content-Type": "application/json"
|
|
149
|
-
},
|
|
150
|
-
body: JSON.stringify(this.buildPayload(opts, false)),
|
|
151
|
-
signal
|
|
152
|
-
},
|
|
153
|
-
{ ...this.retry, signal }
|
|
154
|
-
);
|
|
155
|
-
if (!resp.ok) {
|
|
156
|
-
throw new Error(`DeepSeek ${resp.status}: ${await resp.text()}`);
|
|
157
|
-
}
|
|
158
|
-
const data = await resp.json();
|
|
159
|
-
const choice = data.choices?.[0]?.message ?? {};
|
|
160
|
-
return {
|
|
161
|
-
content: choice.content ?? "",
|
|
162
|
-
reasoningContent: choice.reasoning_content ?? null,
|
|
163
|
-
toolCalls: choice.tool_calls ?? [],
|
|
164
|
-
usage: Usage.fromApi(data.usage),
|
|
165
|
-
raw: data
|
|
166
|
-
};
|
|
167
|
-
} finally {
|
|
168
|
-
clearTimeout(timer);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
async *stream(opts) {
|
|
172
|
-
const ctrl = new AbortController();
|
|
173
|
-
const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);
|
|
174
|
-
const signal = opts.signal ?? ctrl.signal;
|
|
175
|
-
let resp;
|
|
176
|
-
try {
|
|
177
|
-
resp = await fetchWithRetry(
|
|
178
|
-
this._fetch,
|
|
179
|
-
`${this.baseUrl}/chat/completions`,
|
|
180
|
-
{
|
|
181
|
-
method: "POST",
|
|
182
|
-
headers: {
|
|
183
|
-
Authorization: `Bearer ${this.apiKey}`,
|
|
184
|
-
"Content-Type": "application/json",
|
|
185
|
-
Accept: "text/event-stream"
|
|
186
|
-
},
|
|
187
|
-
body: JSON.stringify(this.buildPayload(opts, true)),
|
|
188
|
-
signal
|
|
189
|
-
},
|
|
190
|
-
{ ...this.retry, signal }
|
|
191
|
-
);
|
|
192
|
-
} catch (err) {
|
|
193
|
-
clearTimeout(timer);
|
|
194
|
-
throw err;
|
|
195
|
-
}
|
|
196
|
-
if (!resp.ok || !resp.body) {
|
|
197
|
-
clearTimeout(timer);
|
|
198
|
-
throw new Error(`DeepSeek ${resp.status}: ${await resp.text().catch(() => "")}`);
|
|
199
|
-
}
|
|
200
|
-
const queue = [];
|
|
201
|
-
let done = false;
|
|
202
|
-
const parser = createParser({
|
|
203
|
-
onEvent: (ev) => {
|
|
204
|
-
if (!ev.data || ev.data === "[DONE]") {
|
|
205
|
-
done = true;
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
try {
|
|
209
|
-
const json = JSON.parse(ev.data);
|
|
210
|
-
const delta = json.choices?.[0]?.delta ?? {};
|
|
211
|
-
const finishReason = json.choices?.[0]?.finish_reason ?? void 0;
|
|
212
|
-
const chunk = { raw: json, finishReason };
|
|
213
|
-
if (typeof delta.content === "string" && delta.content.length > 0) {
|
|
214
|
-
chunk.contentDelta = delta.content;
|
|
215
|
-
}
|
|
216
|
-
if (typeof delta.reasoning_content === "string" && delta.reasoning_content.length > 0) {
|
|
217
|
-
chunk.reasoningDelta = delta.reasoning_content;
|
|
218
|
-
}
|
|
219
|
-
if (Array.isArray(delta.tool_calls) && delta.tool_calls.length > 0) {
|
|
220
|
-
const tc = delta.tool_calls[0];
|
|
221
|
-
chunk.toolCallDelta = {
|
|
222
|
-
index: tc.index ?? 0,
|
|
223
|
-
id: tc.id,
|
|
224
|
-
name: tc.function?.name,
|
|
225
|
-
argumentsDelta: tc.function?.arguments
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
if (json.usage) {
|
|
229
|
-
chunk.usage = Usage.fromApi(json.usage);
|
|
230
|
-
}
|
|
231
|
-
queue.push(chunk);
|
|
232
|
-
} catch {
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
});
|
|
236
|
-
const reader = resp.body.getReader();
|
|
237
|
-
const decoder = new TextDecoder();
|
|
238
|
-
try {
|
|
239
|
-
while (true) {
|
|
240
|
-
if (queue.length > 0) {
|
|
241
|
-
yield queue.shift();
|
|
242
|
-
continue;
|
|
243
|
-
}
|
|
244
|
-
if (done) break;
|
|
245
|
-
const { value, done: streamDone } = await reader.read();
|
|
246
|
-
if (streamDone) break;
|
|
247
|
-
parser.feed(decoder.decode(value, { stream: true }));
|
|
248
|
-
}
|
|
249
|
-
while (queue.length > 0) yield queue.shift();
|
|
250
|
-
} finally {
|
|
251
|
-
clearTimeout(timer);
|
|
252
|
-
reader.releaseLock();
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
};
|
|
256
|
-
|
|
257
|
-
export {
|
|
258
|
-
fetchWithRetry,
|
|
259
|
-
Usage,
|
|
260
|
-
DeepSeekClient
|
|
261
|
-
};
|
|
262
|
-
//# sourceMappingURL=chunk-Y7L6L5QS.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts","../src/retry.ts"],"sourcesContent":["import { type EventSourceMessage, createParser } from \"eventsource-parser\";\nimport { type RetryOptions, fetchWithRetry } from \"./retry.js\";\nimport type { ChatMessage, ChatRequestOptions, RawUsage, ToolCall, ToolSpec } from \"./types.js\";\n\nexport class Usage {\n constructor(\n public promptTokens = 0,\n public completionTokens = 0,\n public totalTokens = 0,\n public promptCacheHitTokens = 0,\n public promptCacheMissTokens = 0,\n ) {}\n\n get cacheHitRatio(): number {\n const denom = this.promptCacheHitTokens + this.promptCacheMissTokens;\n return denom > 0 ? this.promptCacheHitTokens / denom : 0;\n }\n\n static fromApi(raw: RawUsage | undefined | null): Usage {\n const u = raw ?? {};\n return new Usage(\n u.prompt_tokens ?? 0,\n u.completion_tokens ?? 0,\n u.total_tokens ?? 0,\n u.prompt_cache_hit_tokens ?? 0,\n u.prompt_cache_miss_tokens ?? 0,\n );\n }\n}\n\nexport interface ChatResponse {\n content: string;\n reasoningContent: string | null;\n toolCalls: ToolCall[];\n usage: Usage;\n raw: unknown;\n}\n\nexport interface StreamChunk {\n contentDelta?: string;\n reasoningDelta?: string;\n toolCallDelta?: { index: number; id?: string; name?: string; argumentsDelta?: string };\n usage?: Usage;\n finishReason?: string;\n raw: any;\n}\n\nexport interface DeepSeekClientOptions {\n apiKey?: string;\n baseUrl?: string;\n timeoutMs?: number;\n fetch?: typeof fetch;\n /** Retry configuration. Pass `{ maxAttempts: 1 }` to disable retries. */\n retry?: RetryOptions;\n}\n\nexport class DeepSeekClient {\n readonly apiKey: string;\n readonly baseUrl: string;\n readonly timeoutMs: number;\n readonly retry: RetryOptions;\n private readonly _fetch: typeof fetch;\n\n constructor(opts: DeepSeekClientOptions = {}) {\n const apiKey = opts.apiKey ?? process.env.DEEPSEEK_API_KEY;\n if (!apiKey) {\n throw new Error(\n \"DEEPSEEK_API_KEY is not set. Put it in .env or pass apiKey to DeepSeekClient.\",\n );\n }\n this.apiKey = apiKey;\n this.baseUrl = (\n opts.baseUrl ??\n process.env.DEEPSEEK_BASE_URL ??\n \"https://api.deepseek.com\"\n ).replace(/\\/+$/, \"\");\n this.timeoutMs = opts.timeoutMs ?? 120_000;\n this._fetch = opts.fetch ?? globalThis.fetch.bind(globalThis);\n this.retry = opts.retry ?? {};\n }\n\n private buildPayload(opts: ChatRequestOptions, stream: boolean) {\n const payload: Record<string, unknown> = {\n model: opts.model,\n messages: opts.messages,\n stream,\n };\n if (opts.tools?.length) payload.tools = opts.tools;\n if (opts.temperature !== undefined) payload.temperature = opts.temperature;\n if (opts.maxTokens !== undefined) payload.max_tokens = opts.maxTokens;\n if (opts.responseFormat) payload.response_format = opts.responseFormat;\n return payload;\n }\n\n async chat(opts: ChatRequestOptions): Promise<ChatResponse> {\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\n const signal = opts.signal ?? ctrl.signal;\n\n try {\n const resp = await fetchWithRetry(\n this._fetch,\n `${this.baseUrl}/chat/completions`,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(this.buildPayload(opts, false)),\n signal,\n },\n { ...this.retry, signal },\n );\n if (!resp.ok) {\n throw new Error(`DeepSeek ${resp.status}: ${await resp.text()}`);\n }\n const data: any = await resp.json();\n const choice = data.choices?.[0]?.message ?? {};\n return {\n content: choice.content ?? \"\",\n reasoningContent: choice.reasoning_content ?? null,\n toolCalls: choice.tool_calls ?? [],\n usage: Usage.fromApi(data.usage),\n raw: data,\n };\n } finally {\n clearTimeout(timer);\n }\n }\n\n async *stream(opts: ChatRequestOptions): AsyncGenerator<StreamChunk> {\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\n const signal = opts.signal ?? ctrl.signal;\n\n let resp: Response;\n try {\n // Only the initial fetch is retried. Once the server has started sending\n // the stream body we do NOT retry — a mid-stream retry would re-bill and\n // desync the session context.\n resp = await fetchWithRetry(\n this._fetch,\n `${this.baseUrl}/chat/completions`,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n \"Content-Type\": \"application/json\",\n Accept: \"text/event-stream\",\n },\n body: JSON.stringify(this.buildPayload(opts, true)),\n signal,\n },\n { ...this.retry, signal },\n );\n } catch (err) {\n clearTimeout(timer);\n throw err;\n }\n if (!resp.ok || !resp.body) {\n clearTimeout(timer);\n throw new Error(`DeepSeek ${resp.status}: ${await resp.text().catch(() => \"\")}`);\n }\n\n const queue: StreamChunk[] = [];\n let done = false;\n const parser = createParser({\n onEvent: (ev: EventSourceMessage) => {\n if (!ev.data || ev.data === \"[DONE]\") {\n done = true;\n return;\n }\n try {\n const json = JSON.parse(ev.data);\n const delta = json.choices?.[0]?.delta ?? {};\n const finishReason = json.choices?.[0]?.finish_reason ?? undefined;\n const chunk: StreamChunk = { raw: json, finishReason };\n if (typeof delta.content === \"string\" && delta.content.length > 0) {\n chunk.contentDelta = delta.content;\n }\n if (typeof delta.reasoning_content === \"string\" && delta.reasoning_content.length > 0) {\n chunk.reasoningDelta = delta.reasoning_content;\n }\n if (Array.isArray(delta.tool_calls) && delta.tool_calls.length > 0) {\n const tc = delta.tool_calls[0];\n chunk.toolCallDelta = {\n index: tc.index ?? 0,\n id: tc.id,\n name: tc.function?.name,\n argumentsDelta: tc.function?.arguments,\n };\n }\n if (json.usage) {\n chunk.usage = Usage.fromApi(json.usage);\n }\n queue.push(chunk);\n } catch {\n /* skip malformed sse frame */\n }\n },\n });\n\n const reader = resp.body.getReader();\n const decoder = new TextDecoder();\n try {\n while (true) {\n if (queue.length > 0) {\n yield queue.shift()!;\n continue;\n }\n if (done) break;\n const { value, done: streamDone } = await reader.read();\n if (streamDone) break;\n parser.feed(decoder.decode(value, { stream: true }));\n }\n while (queue.length > 0) yield queue.shift()!;\n } finally {\n clearTimeout(timer);\n reader.releaseLock();\n }\n }\n}\n\nexport type { ChatMessage, ToolCall, ToolSpec };\n","/**\n * Retry layer for DeepSeek API calls.\n *\n * Wraps a `fetch` function so that transient failures (rate limiting, server\n * overload, network blips) don't kill an agent session. We explicitly DO NOT\n * retry:\n * - 4xx client errors other than 408 / 429 (bad key, bad request, ...)\n * - aborted requests (user cancelled)\n * - mid-stream body read errors (retrying costs money AND would desync)\n *\n * Retrying is controlled by attempt count + exponential backoff with jitter.\n * If the server sends a `Retry-After` header we honor it (capped by\n * `maxBackoffMs` so a misconfigured upstream can't park us forever).\n */\n\nexport interface RetryOptions {\n /** Maximum total attempts (including the first). Default 4. */\n maxAttempts?: number;\n /** Initial backoff in ms. Doubles each retry, with jitter. Default 500. */\n initialBackoffMs?: number;\n /** Upper bound on any single backoff delay. Default 10000 (10s). */\n maxBackoffMs?: number;\n /** HTTP statuses to treat as retryable. Default [408, 429, 500, 502, 503, 504]. */\n retryableStatuses?: readonly number[];\n /** Abort signal; we do NOT retry once aborted. */\n signal?: AbortSignal;\n /** Telemetry hook — called before each wait. */\n onRetry?: (info: RetryInfo) => void;\n}\n\nexport interface RetryInfo {\n attempt: number;\n reason: string;\n waitMs: number;\n}\n\nconst DEFAULT_RETRYABLE_STATUSES = [408, 429, 500, 502, 503, 504] as const;\n\nexport async function fetchWithRetry(\n fetchFn: typeof fetch,\n url: string,\n init: RequestInit,\n opts: RetryOptions = {},\n): Promise<Response> {\n const maxAttempts = opts.maxAttempts ?? 4;\n const initial = opts.initialBackoffMs ?? 500;\n const cap = opts.maxBackoffMs ?? 10_000;\n const retryable = new Set(opts.retryableStatuses ?? DEFAULT_RETRYABLE_STATUSES);\n\n let lastError: unknown;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n if (opts.signal?.aborted) throw new Error(\"aborted\");\n\n try {\n const resp = await fetchFn(url, init);\n\n // Success or non-retryable failure: return as-is.\n if (resp.ok || !retryable.has(resp.status)) return resp;\n\n // Retryable but out of attempts: return the last response so the caller\n // can surface the status to the user.\n if (attempt === maxAttempts - 1) return resp;\n\n // Drain the body so the connection can be reused on the next attempt.\n await resp.text().catch(() => undefined);\n\n const waitMs = computeWait(attempt, initial, cap, resp.headers.get(\"Retry-After\"));\n opts.onRetry?.({ attempt: attempt + 1, reason: `http ${resp.status}`, waitMs });\n await sleep(waitMs, opts.signal);\n } catch (err) {\n lastError = err;\n // Respect explicit aborts — do not retry.\n if (isAbortError(err) || opts.signal?.aborted) throw err;\n if (attempt === maxAttempts - 1) throw err;\n\n const waitMs = computeWait(attempt, initial, cap, null);\n opts.onRetry?.({\n attempt: attempt + 1,\n reason: `network: ${messageOf(err)}`,\n waitMs,\n });\n await sleep(waitMs, opts.signal);\n }\n }\n\n throw lastError ?? new Error(\"fetchWithRetry: loop exited unexpectedly\");\n}\n\nfunction computeWait(\n attempt: number,\n initial: number,\n cap: number,\n retryAfter: string | null,\n): number {\n if (retryAfter) {\n const seconds = Number.parseFloat(retryAfter);\n if (Number.isFinite(seconds) && seconds > 0) {\n return Math.min(seconds * 1000, cap);\n }\n }\n const exp = initial * 2 ** attempt;\n // Jitter range [75%, 125%] to spread retries out when many clients hit 429 together.\n const jitter = exp * (0.75 + Math.random() * 0.5);\n return Math.min(Math.max(jitter, 0), cap);\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n if (ms <= 0) return Promise.resolve();\n return new Promise((resolve, reject) => {\n const timer = setTimeout(resolve, ms);\n if (signal) {\n const onAbort = () => {\n clearTimeout(timer);\n reject(new Error(\"aborted\"));\n };\n if (signal.aborted) onAbort();\n else signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n });\n}\n\nfunction isAbortError(err: unknown): boolean {\n if (!err || typeof err !== \"object\") return false;\n const name = (err as { name?: unknown }).name;\n return name === \"AbortError\";\n}\n\nfunction messageOf(err: unknown): string {\n if (err instanceof Error) return err.message;\n try {\n return String(err);\n } catch {\n return \"unknown error\";\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// src/client.ts
|
|
4
|
-
import { createParser } from "eventsource-parser";
|
|
5
|
-
|
|
6
|
-
// src/retry.ts
|
|
7
|
-
var DEFAULT_RETRYABLE_STATUSES = [408, 429, 500, 502, 503, 504];
|
|
8
|
-
async function fetchWithRetry(fetchFn, url, init, opts = {}) {
|
|
9
|
-
const maxAttempts = opts.maxAttempts ?? 4;
|
|
10
|
-
const initial = opts.initialBackoffMs ?? 500;
|
|
11
|
-
const cap = opts.maxBackoffMs ?? 1e4;
|
|
12
|
-
const retryable = new Set(opts.retryableStatuses ?? DEFAULT_RETRYABLE_STATUSES);
|
|
13
|
-
let lastError;
|
|
14
|
-
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
15
|
-
if (opts.signal?.aborted) throw new Error("aborted");
|
|
16
|
-
try {
|
|
17
|
-
const resp = await fetchFn(url, init);
|
|
18
|
-
if (resp.ok || !retryable.has(resp.status)) return resp;
|
|
19
|
-
if (attempt === maxAttempts - 1) return resp;
|
|
20
|
-
await resp.text().catch(() => void 0);
|
|
21
|
-
const waitMs = computeWait(attempt, initial, cap, resp.headers.get("Retry-After"));
|
|
22
|
-
opts.onRetry?.({ attempt: attempt + 1, reason: `http ${resp.status}`, waitMs });
|
|
23
|
-
await sleep(waitMs, opts.signal);
|
|
24
|
-
} catch (err) {
|
|
25
|
-
lastError = err;
|
|
26
|
-
if (isAbortError(err) || opts.signal?.aborted) throw err;
|
|
27
|
-
if (attempt === maxAttempts - 1) throw err;
|
|
28
|
-
const waitMs = computeWait(attempt, initial, cap, null);
|
|
29
|
-
opts.onRetry?.({
|
|
30
|
-
attempt: attempt + 1,
|
|
31
|
-
reason: `network: ${messageOf(err)}`,
|
|
32
|
-
waitMs
|
|
33
|
-
});
|
|
34
|
-
await sleep(waitMs, opts.signal);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
throw lastError ?? new Error("fetchWithRetry: loop exited unexpectedly");
|
|
38
|
-
}
|
|
39
|
-
function computeWait(attempt, initial, cap, retryAfter) {
|
|
40
|
-
if (retryAfter) {
|
|
41
|
-
const seconds = Number.parseFloat(retryAfter);
|
|
42
|
-
if (Number.isFinite(seconds) && seconds > 0) {
|
|
43
|
-
return Math.min(seconds * 1e3, cap);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
const exp = initial * 2 ** attempt;
|
|
47
|
-
const jitter = exp * (0.75 + Math.random() * 0.5);
|
|
48
|
-
return Math.min(Math.max(jitter, 0), cap);
|
|
49
|
-
}
|
|
50
|
-
function sleep(ms, signal) {
|
|
51
|
-
if (ms <= 0) return Promise.resolve();
|
|
52
|
-
return new Promise((resolve, reject) => {
|
|
53
|
-
const timer = setTimeout(resolve, ms);
|
|
54
|
-
if (signal) {
|
|
55
|
-
const onAbort = () => {
|
|
56
|
-
clearTimeout(timer);
|
|
57
|
-
reject(new Error("aborted"));
|
|
58
|
-
};
|
|
59
|
-
if (signal.aborted) onAbort();
|
|
60
|
-
else signal.addEventListener("abort", onAbort, { once: true });
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
function isAbortError(err) {
|
|
65
|
-
if (!err || typeof err !== "object") return false;
|
|
66
|
-
const name = err.name;
|
|
67
|
-
return name === "AbortError";
|
|
68
|
-
}
|
|
69
|
-
function messageOf(err) {
|
|
70
|
-
if (err instanceof Error) return err.message;
|
|
71
|
-
try {
|
|
72
|
-
return String(err);
|
|
73
|
-
} catch {
|
|
74
|
-
return "unknown error";
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// src/client.ts
|
|
79
|
-
var Usage = class _Usage {
|
|
80
|
-
constructor(promptTokens = 0, completionTokens = 0, totalTokens = 0, promptCacheHitTokens = 0, promptCacheMissTokens = 0) {
|
|
81
|
-
this.promptTokens = promptTokens;
|
|
82
|
-
this.completionTokens = completionTokens;
|
|
83
|
-
this.totalTokens = totalTokens;
|
|
84
|
-
this.promptCacheHitTokens = promptCacheHitTokens;
|
|
85
|
-
this.promptCacheMissTokens = promptCacheMissTokens;
|
|
86
|
-
}
|
|
87
|
-
promptTokens;
|
|
88
|
-
completionTokens;
|
|
89
|
-
totalTokens;
|
|
90
|
-
promptCacheHitTokens;
|
|
91
|
-
promptCacheMissTokens;
|
|
92
|
-
get cacheHitRatio() {
|
|
93
|
-
const denom = this.promptCacheHitTokens + this.promptCacheMissTokens;
|
|
94
|
-
return denom > 0 ? this.promptCacheHitTokens / denom : 0;
|
|
95
|
-
}
|
|
96
|
-
static fromApi(raw) {
|
|
97
|
-
const u = raw ?? {};
|
|
98
|
-
return new _Usage(
|
|
99
|
-
u.prompt_tokens ?? 0,
|
|
100
|
-
u.completion_tokens ?? 0,
|
|
101
|
-
u.total_tokens ?? 0,
|
|
102
|
-
u.prompt_cache_hit_tokens ?? 0,
|
|
103
|
-
u.prompt_cache_miss_tokens ?? 0
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
var DeepSeekClient = class {
|
|
108
|
-
apiKey;
|
|
109
|
-
baseUrl;
|
|
110
|
-
timeoutMs;
|
|
111
|
-
retry;
|
|
112
|
-
_fetch;
|
|
113
|
-
constructor(opts = {}) {
|
|
114
|
-
const apiKey = opts.apiKey ?? process.env.DEEPSEEK_API_KEY;
|
|
115
|
-
if (!apiKey) {
|
|
116
|
-
throw new Error(
|
|
117
|
-
"DEEPSEEK_API_KEY is not set. Put it in .env or pass apiKey to DeepSeekClient."
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
this.apiKey = apiKey;
|
|
121
|
-
this.baseUrl = (opts.baseUrl ?? process.env.DEEPSEEK_BASE_URL ?? "https://api.deepseek.com").replace(/\/+$/, "");
|
|
122
|
-
this.timeoutMs = opts.timeoutMs ?? 12e4;
|
|
123
|
-
this._fetch = opts.fetch ?? globalThis.fetch.bind(globalThis);
|
|
124
|
-
this.retry = opts.retry ?? {};
|
|
125
|
-
}
|
|
126
|
-
buildPayload(opts, stream) {
|
|
127
|
-
const payload = {
|
|
128
|
-
model: opts.model,
|
|
129
|
-
messages: opts.messages,
|
|
130
|
-
stream
|
|
131
|
-
};
|
|
132
|
-
if (opts.tools?.length) payload.tools = opts.tools;
|
|
133
|
-
if (opts.temperature !== void 0) payload.temperature = opts.temperature;
|
|
134
|
-
if (opts.maxTokens !== void 0) payload.max_tokens = opts.maxTokens;
|
|
135
|
-
if (opts.responseFormat) payload.response_format = opts.responseFormat;
|
|
136
|
-
return payload;
|
|
137
|
-
}
|
|
138
|
-
async chat(opts) {
|
|
139
|
-
const ctrl = new AbortController();
|
|
140
|
-
const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);
|
|
141
|
-
const signal = opts.signal ?? ctrl.signal;
|
|
142
|
-
try {
|
|
143
|
-
const resp = await fetchWithRetry(
|
|
144
|
-
this._fetch,
|
|
145
|
-
`${this.baseUrl}/chat/completions`,
|
|
146
|
-
{
|
|
147
|
-
method: "POST",
|
|
148
|
-
headers: {
|
|
149
|
-
Authorization: `Bearer ${this.apiKey}`,
|
|
150
|
-
"Content-Type": "application/json"
|
|
151
|
-
},
|
|
152
|
-
body: JSON.stringify(this.buildPayload(opts, false)),
|
|
153
|
-
signal
|
|
154
|
-
},
|
|
155
|
-
{ ...this.retry, signal }
|
|
156
|
-
);
|
|
157
|
-
if (!resp.ok) {
|
|
158
|
-
throw new Error(`DeepSeek ${resp.status}: ${await resp.text()}`);
|
|
159
|
-
}
|
|
160
|
-
const data = await resp.json();
|
|
161
|
-
const choice = data.choices?.[0]?.message ?? {};
|
|
162
|
-
return {
|
|
163
|
-
content: choice.content ?? "",
|
|
164
|
-
reasoningContent: choice.reasoning_content ?? null,
|
|
165
|
-
toolCalls: choice.tool_calls ?? [],
|
|
166
|
-
usage: Usage.fromApi(data.usage),
|
|
167
|
-
raw: data
|
|
168
|
-
};
|
|
169
|
-
} finally {
|
|
170
|
-
clearTimeout(timer);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
async *stream(opts) {
|
|
174
|
-
const ctrl = new AbortController();
|
|
175
|
-
const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);
|
|
176
|
-
const signal = opts.signal ?? ctrl.signal;
|
|
177
|
-
let resp;
|
|
178
|
-
try {
|
|
179
|
-
resp = await fetchWithRetry(
|
|
180
|
-
this._fetch,
|
|
181
|
-
`${this.baseUrl}/chat/completions`,
|
|
182
|
-
{
|
|
183
|
-
method: "POST",
|
|
184
|
-
headers: {
|
|
185
|
-
Authorization: `Bearer ${this.apiKey}`,
|
|
186
|
-
"Content-Type": "application/json",
|
|
187
|
-
Accept: "text/event-stream"
|
|
188
|
-
},
|
|
189
|
-
body: JSON.stringify(this.buildPayload(opts, true)),
|
|
190
|
-
signal
|
|
191
|
-
},
|
|
192
|
-
{ ...this.retry, signal }
|
|
193
|
-
);
|
|
194
|
-
} catch (err) {
|
|
195
|
-
clearTimeout(timer);
|
|
196
|
-
throw err;
|
|
197
|
-
}
|
|
198
|
-
if (!resp.ok || !resp.body) {
|
|
199
|
-
clearTimeout(timer);
|
|
200
|
-
throw new Error(`DeepSeek ${resp.status}: ${await resp.text().catch(() => "")}`);
|
|
201
|
-
}
|
|
202
|
-
const queue = [];
|
|
203
|
-
let done = false;
|
|
204
|
-
const parser = createParser({
|
|
205
|
-
onEvent: (ev) => {
|
|
206
|
-
if (!ev.data || ev.data === "[DONE]") {
|
|
207
|
-
done = true;
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
try {
|
|
211
|
-
const json = JSON.parse(ev.data);
|
|
212
|
-
const delta = json.choices?.[0]?.delta ?? {};
|
|
213
|
-
const finishReason = json.choices?.[0]?.finish_reason ?? void 0;
|
|
214
|
-
const chunk = { raw: json, finishReason };
|
|
215
|
-
if (typeof delta.content === "string" && delta.content.length > 0) {
|
|
216
|
-
chunk.contentDelta = delta.content;
|
|
217
|
-
}
|
|
218
|
-
if (typeof delta.reasoning_content === "string" && delta.reasoning_content.length > 0) {
|
|
219
|
-
chunk.reasoningDelta = delta.reasoning_content;
|
|
220
|
-
}
|
|
221
|
-
if (Array.isArray(delta.tool_calls) && delta.tool_calls.length > 0) {
|
|
222
|
-
const tc = delta.tool_calls[0];
|
|
223
|
-
chunk.toolCallDelta = {
|
|
224
|
-
index: tc.index ?? 0,
|
|
225
|
-
id: tc.id,
|
|
226
|
-
name: tc.function?.name,
|
|
227
|
-
argumentsDelta: tc.function?.arguments
|
|
228
|
-
};
|
|
229
|
-
}
|
|
230
|
-
if (json.usage) {
|
|
231
|
-
chunk.usage = Usage.fromApi(json.usage);
|
|
232
|
-
}
|
|
233
|
-
queue.push(chunk);
|
|
234
|
-
} catch {
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
});
|
|
238
|
-
const reader = resp.body.getReader();
|
|
239
|
-
const decoder = new TextDecoder();
|
|
240
|
-
try {
|
|
241
|
-
while (true) {
|
|
242
|
-
if (queue.length > 0) {
|
|
243
|
-
yield queue.shift();
|
|
244
|
-
continue;
|
|
245
|
-
}
|
|
246
|
-
if (done) break;
|
|
247
|
-
const { value, done: streamDone } = await reader.read();
|
|
248
|
-
if (streamDone) break;
|
|
249
|
-
parser.feed(decoder.decode(value, { stream: true }));
|
|
250
|
-
}
|
|
251
|
-
while (queue.length > 0) yield queue.shift();
|
|
252
|
-
} finally {
|
|
253
|
-
clearTimeout(timer);
|
|
254
|
-
reader.releaseLock();
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
};
|
|
258
|
-
|
|
259
|
-
export {
|
|
260
|
-
Usage,
|
|
261
|
-
DeepSeekClient
|
|
262
|
-
};
|
|
263
|
-
//# sourceMappingURL=chunk-T2ODXAJP.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/client.ts","../../src/retry.ts"],"sourcesContent":["import { type EventSourceMessage, createParser } from \"eventsource-parser\";\nimport { type RetryOptions, fetchWithRetry } from \"./retry.js\";\nimport type { ChatMessage, ChatRequestOptions, RawUsage, ToolCall, ToolSpec } from \"./types.js\";\n\nexport class Usage {\n constructor(\n public promptTokens = 0,\n public completionTokens = 0,\n public totalTokens = 0,\n public promptCacheHitTokens = 0,\n public promptCacheMissTokens = 0,\n ) {}\n\n get cacheHitRatio(): number {\n const denom = this.promptCacheHitTokens + this.promptCacheMissTokens;\n return denom > 0 ? this.promptCacheHitTokens / denom : 0;\n }\n\n static fromApi(raw: RawUsage | undefined | null): Usage {\n const u = raw ?? {};\n return new Usage(\n u.prompt_tokens ?? 0,\n u.completion_tokens ?? 0,\n u.total_tokens ?? 0,\n u.prompt_cache_hit_tokens ?? 0,\n u.prompt_cache_miss_tokens ?? 0,\n );\n }\n}\n\nexport interface ChatResponse {\n content: string;\n reasoningContent: string | null;\n toolCalls: ToolCall[];\n usage: Usage;\n raw: unknown;\n}\n\nexport interface StreamChunk {\n contentDelta?: string;\n reasoningDelta?: string;\n toolCallDelta?: { index: number; id?: string; name?: string; argumentsDelta?: string };\n usage?: Usage;\n finishReason?: string;\n raw: any;\n}\n\nexport interface DeepSeekClientOptions {\n apiKey?: string;\n baseUrl?: string;\n timeoutMs?: number;\n fetch?: typeof fetch;\n /** Retry configuration. Pass `{ maxAttempts: 1 }` to disable retries. */\n retry?: RetryOptions;\n}\n\nexport class DeepSeekClient {\n readonly apiKey: string;\n readonly baseUrl: string;\n readonly timeoutMs: number;\n readonly retry: RetryOptions;\n private readonly _fetch: typeof fetch;\n\n constructor(opts: DeepSeekClientOptions = {}) {\n const apiKey = opts.apiKey ?? process.env.DEEPSEEK_API_KEY;\n if (!apiKey) {\n throw new Error(\n \"DEEPSEEK_API_KEY is not set. Put it in .env or pass apiKey to DeepSeekClient.\",\n );\n }\n this.apiKey = apiKey;\n this.baseUrl = (\n opts.baseUrl ??\n process.env.DEEPSEEK_BASE_URL ??\n \"https://api.deepseek.com\"\n ).replace(/\\/+$/, \"\");\n this.timeoutMs = opts.timeoutMs ?? 120_000;\n this._fetch = opts.fetch ?? globalThis.fetch.bind(globalThis);\n this.retry = opts.retry ?? {};\n }\n\n private buildPayload(opts: ChatRequestOptions, stream: boolean) {\n const payload: Record<string, unknown> = {\n model: opts.model,\n messages: opts.messages,\n stream,\n };\n if (opts.tools?.length) payload.tools = opts.tools;\n if (opts.temperature !== undefined) payload.temperature = opts.temperature;\n if (opts.maxTokens !== undefined) payload.max_tokens = opts.maxTokens;\n if (opts.responseFormat) payload.response_format = opts.responseFormat;\n return payload;\n }\n\n async chat(opts: ChatRequestOptions): Promise<ChatResponse> {\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\n const signal = opts.signal ?? ctrl.signal;\n\n try {\n const resp = await fetchWithRetry(\n this._fetch,\n `${this.baseUrl}/chat/completions`,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(this.buildPayload(opts, false)),\n signal,\n },\n { ...this.retry, signal },\n );\n if (!resp.ok) {\n throw new Error(`DeepSeek ${resp.status}: ${await resp.text()}`);\n }\n const data: any = await resp.json();\n const choice = data.choices?.[0]?.message ?? {};\n return {\n content: choice.content ?? \"\",\n reasoningContent: choice.reasoning_content ?? null,\n toolCalls: choice.tool_calls ?? [],\n usage: Usage.fromApi(data.usage),\n raw: data,\n };\n } finally {\n clearTimeout(timer);\n }\n }\n\n async *stream(opts: ChatRequestOptions): AsyncGenerator<StreamChunk> {\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\n const signal = opts.signal ?? ctrl.signal;\n\n let resp: Response;\n try {\n // Only the initial fetch is retried. Once the server has started sending\n // the stream body we do NOT retry — a mid-stream retry would re-bill and\n // desync the session context.\n resp = await fetchWithRetry(\n this._fetch,\n `${this.baseUrl}/chat/completions`,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n \"Content-Type\": \"application/json\",\n Accept: \"text/event-stream\",\n },\n body: JSON.stringify(this.buildPayload(opts, true)),\n signal,\n },\n { ...this.retry, signal },\n );\n } catch (err) {\n clearTimeout(timer);\n throw err;\n }\n if (!resp.ok || !resp.body) {\n clearTimeout(timer);\n throw new Error(`DeepSeek ${resp.status}: ${await resp.text().catch(() => \"\")}`);\n }\n\n const queue: StreamChunk[] = [];\n let done = false;\n const parser = createParser({\n onEvent: (ev: EventSourceMessage) => {\n if (!ev.data || ev.data === \"[DONE]\") {\n done = true;\n return;\n }\n try {\n const json = JSON.parse(ev.data);\n const delta = json.choices?.[0]?.delta ?? {};\n const finishReason = json.choices?.[0]?.finish_reason ?? undefined;\n const chunk: StreamChunk = { raw: json, finishReason };\n if (typeof delta.content === \"string\" && delta.content.length > 0) {\n chunk.contentDelta = delta.content;\n }\n if (typeof delta.reasoning_content === \"string\" && delta.reasoning_content.length > 0) {\n chunk.reasoningDelta = delta.reasoning_content;\n }\n if (Array.isArray(delta.tool_calls) && delta.tool_calls.length > 0) {\n const tc = delta.tool_calls[0];\n chunk.toolCallDelta = {\n index: tc.index ?? 0,\n id: tc.id,\n name: tc.function?.name,\n argumentsDelta: tc.function?.arguments,\n };\n }\n if (json.usage) {\n chunk.usage = Usage.fromApi(json.usage);\n }\n queue.push(chunk);\n } catch {\n /* skip malformed sse frame */\n }\n },\n });\n\n const reader = resp.body.getReader();\n const decoder = new TextDecoder();\n try {\n while (true) {\n if (queue.length > 0) {\n yield queue.shift()!;\n continue;\n }\n if (done) break;\n const { value, done: streamDone } = await reader.read();\n if (streamDone) break;\n parser.feed(decoder.decode(value, { stream: true }));\n }\n while (queue.length > 0) yield queue.shift()!;\n } finally {\n clearTimeout(timer);\n reader.releaseLock();\n }\n }\n}\n\nexport type { ChatMessage, ToolCall, ToolSpec };\n","/**\n * Retry layer for DeepSeek API calls.\n *\n * Wraps a `fetch` function so that transient failures (rate limiting, server\n * overload, network blips) don't kill an agent session. We explicitly DO NOT\n * retry:\n * - 4xx client errors other than 408 / 429 (bad key, bad request, ...)\n * - aborted requests (user cancelled)\n * - mid-stream body read errors (retrying costs money AND would desync)\n *\n * Retrying is controlled by attempt count + exponential backoff with jitter.\n * If the server sends a `Retry-After` header we honor it (capped by\n * `maxBackoffMs` so a misconfigured upstream can't park us forever).\n */\n\nexport interface RetryOptions {\n /** Maximum total attempts (including the first). Default 4. */\n maxAttempts?: number;\n /** Initial backoff in ms. Doubles each retry, with jitter. Default 500. */\n initialBackoffMs?: number;\n /** Upper bound on any single backoff delay. Default 10000 (10s). */\n maxBackoffMs?: number;\n /** HTTP statuses to treat as retryable. Default [408, 429, 500, 502, 503, 504]. */\n retryableStatuses?: readonly number[];\n /** Abort signal; we do NOT retry once aborted. */\n signal?: AbortSignal;\n /** Telemetry hook — called before each wait. */\n onRetry?: (info: RetryInfo) => void;\n}\n\nexport interface RetryInfo {\n attempt: number;\n reason: string;\n waitMs: number;\n}\n\nconst DEFAULT_RETRYABLE_STATUSES = [408, 429, 500, 502, 503, 504] as const;\n\nexport async function fetchWithRetry(\n fetchFn: typeof fetch,\n url: string,\n init: RequestInit,\n opts: RetryOptions = {},\n): Promise<Response> {\n const maxAttempts = opts.maxAttempts ?? 4;\n const initial = opts.initialBackoffMs ?? 500;\n const cap = opts.maxBackoffMs ?? 10_000;\n const retryable = new Set(opts.retryableStatuses ?? DEFAULT_RETRYABLE_STATUSES);\n\n let lastError: unknown;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n if (opts.signal?.aborted) throw new Error(\"aborted\");\n\n try {\n const resp = await fetchFn(url, init);\n\n // Success or non-retryable failure: return as-is.\n if (resp.ok || !retryable.has(resp.status)) return resp;\n\n // Retryable but out of attempts: return the last response so the caller\n // can surface the status to the user.\n if (attempt === maxAttempts - 1) return resp;\n\n // Drain the body so the connection can be reused on the next attempt.\n await resp.text().catch(() => undefined);\n\n const waitMs = computeWait(attempt, initial, cap, resp.headers.get(\"Retry-After\"));\n opts.onRetry?.({ attempt: attempt + 1, reason: `http ${resp.status}`, waitMs });\n await sleep(waitMs, opts.signal);\n } catch (err) {\n lastError = err;\n // Respect explicit aborts — do not retry.\n if (isAbortError(err) || opts.signal?.aborted) throw err;\n if (attempt === maxAttempts - 1) throw err;\n\n const waitMs = computeWait(attempt, initial, cap, null);\n opts.onRetry?.({\n attempt: attempt + 1,\n reason: `network: ${messageOf(err)}`,\n waitMs,\n });\n await sleep(waitMs, opts.signal);\n }\n }\n\n throw lastError ?? new Error(\"fetchWithRetry: loop exited unexpectedly\");\n}\n\nfunction computeWait(\n attempt: number,\n initial: number,\n cap: number,\n retryAfter: string | null,\n): number {\n if (retryAfter) {\n const seconds = Number.parseFloat(retryAfter);\n if (Number.isFinite(seconds) && seconds > 0) {\n return Math.min(seconds * 1000, cap);\n }\n }\n const exp = initial * 2 ** attempt;\n // Jitter range [75%, 125%] to spread retries out when many clients hit 429 together.\n const jitter = exp * (0.75 + Math.random() * 0.5);\n return Math.min(Math.max(jitter, 0), cap);\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n if (ms <= 0) return Promise.resolve();\n return new Promise((resolve, reject) => {\n const timer = setTimeout(resolve, ms);\n if (signal) {\n const onAbort = () => {\n clearTimeout(timer);\n reject(new Error(\"aborted\"));\n };\n if (signal.aborted) onAbort();\n else signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n });\n}\n\nfunction isAbortError(err: unknown): boolean {\n if (!err || typeof err !== \"object\") return false;\n const name = (err as { name?: unknown }).name;\n return name === \"AbortError\";\n}\n\nfunction messageOf(err: unknown): string {\n if (err instanceof Error) return err.message;\n try {\n return String(err);\n } catch {\n return \"unknown error\";\n }\n}\n"],"mappings":";;;AAAA,SAAkC,oBAAoB;;;ACoCtD,IAAM,6BAA6B,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAEhE,eAAsB,eACpB,SACA,KACA,MACA,OAAqB,CAAC,GACH;AACnB,QAAM,cAAc,KAAK,eAAe;AACxC,QAAM,UAAU,KAAK,oBAAoB;AACzC,QAAM,MAAM,KAAK,gBAAgB;AACjC,QAAM,YAAY,IAAI,IAAI,KAAK,qBAAqB,0BAA0B;AAE9E,MAAI;AAEJ,WAAS,UAAU,GAAG,UAAU,aAAa,WAAW;AACtD,QAAI,KAAK,QAAQ,QAAS,OAAM,IAAI,MAAM,SAAS;AAEnD,QAAI;AACF,YAAM,OAAO,MAAM,QAAQ,KAAK,IAAI;AAGpC,UAAI,KAAK,MAAM,CAAC,UAAU,IAAI,KAAK,MAAM,EAAG,QAAO;AAInD,UAAI,YAAY,cAAc,EAAG,QAAO;AAGxC,YAAM,KAAK,KAAK,EAAE,MAAM,MAAM,MAAS;AAEvC,YAAM,SAAS,YAAY,SAAS,SAAS,KAAK,KAAK,QAAQ,IAAI,aAAa,CAAC;AACjF,WAAK,UAAU,EAAE,SAAS,UAAU,GAAG,QAAQ,QAAQ,KAAK,MAAM,IAAI,OAAO,CAAC;AAC9E,YAAM,MAAM,QAAQ,KAAK,MAAM;AAAA,IACjC,SAAS,KAAK;AACZ,kBAAY;AAEZ,UAAI,aAAa,GAAG,KAAK,KAAK,QAAQ,QAAS,OAAM;AACrD,UAAI,YAAY,cAAc,EAAG,OAAM;AAEvC,YAAM,SAAS,YAAY,SAAS,SAAS,KAAK,IAAI;AACtD,WAAK,UAAU;AAAA,QACb,SAAS,UAAU;AAAA,QACnB,QAAQ,YAAY,UAAU,GAAG,CAAC;AAAA,QAClC;AAAA,MACF,CAAC;AACD,YAAM,MAAM,QAAQ,KAAK,MAAM;AAAA,IACjC;AAAA,EACF;AAEA,QAAM,aAAa,IAAI,MAAM,0CAA0C;AACzE;AAEA,SAAS,YACP,SACA,SACA,KACA,YACQ;AACR,MAAI,YAAY;AACd,UAAM,UAAU,OAAO,WAAW,UAAU;AAC5C,QAAI,OAAO,SAAS,OAAO,KAAK,UAAU,GAAG;AAC3C,aAAO,KAAK,IAAI,UAAU,KAAM,GAAG;AAAA,IACrC;AAAA,EACF;AACA,QAAM,MAAM,UAAU,KAAK;AAE3B,QAAM,SAAS,OAAO,OAAO,KAAK,OAAO,IAAI;AAC7C,SAAO,KAAK,IAAI,KAAK,IAAI,QAAQ,CAAC,GAAG,GAAG;AAC1C;AAEA,SAAS,MAAM,IAAY,QAAqC;AAC9D,MAAI,MAAM,EAAG,QAAO,QAAQ,QAAQ;AACpC,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,QAAQ,WAAW,SAAS,EAAE;AACpC,QAAI,QAAQ;AACV,YAAM,UAAU,MAAM;AACpB,qBAAa,KAAK;AAClB,eAAO,IAAI,MAAM,SAAS,CAAC;AAAA,MAC7B;AACA,UAAI,OAAO,QAAS,SAAQ;AAAA,UACvB,QAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAAA,IAC/D;AAAA,EACF,CAAC;AACH;AAEA,SAAS,aAAa,KAAuB;AAC3C,MAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,QAAO;AAC5C,QAAM,OAAQ,IAA2B;AACzC,SAAO,SAAS;AAClB;AAEA,SAAS,UAAU,KAAsB;AACvC,MAAI,eAAe,MAAO,QAAO,IAAI;AACrC,MAAI;AACF,WAAO,OAAO,GAAG;AAAA,EACnB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;ADnIO,IAAM,QAAN,MAAM,OAAM;AAAA,EACjB,YACS,eAAe,GACf,mBAAmB,GACnB,cAAc,GACd,uBAAuB,GACvB,wBAAwB,GAC/B;AALO;AACA;AACA;AACA;AACA;AAAA,EACN;AAAA,EALM;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAGT,IAAI,gBAAwB;AAC1B,UAAM,QAAQ,KAAK,uBAAuB,KAAK;AAC/C,WAAO,QAAQ,IAAI,KAAK,uBAAuB,QAAQ;AAAA,EACzD;AAAA,EAEA,OAAO,QAAQ,KAAyC;AACtD,UAAM,IAAI,OAAO,CAAC;AAClB,WAAO,IAAI;AAAA,MACT,EAAE,iBAAiB;AAAA,MACnB,EAAE,qBAAqB;AAAA,MACvB,EAAE,gBAAgB;AAAA,MAClB,EAAE,2BAA2B;AAAA,MAC7B,EAAE,4BAA4B;AAAA,IAChC;AAAA,EACF;AACF;AA4BO,IAAM,iBAAN,MAAqB;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACQ;AAAA,EAEjB,YAAY,OAA8B,CAAC,GAAG;AAC5C,UAAM,SAAS,KAAK,UAAU,QAAQ,IAAI;AAC1C,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,SAAK,SAAS;AACd,SAAK,WACH,KAAK,WACL,QAAQ,IAAI,qBACZ,4BACA,QAAQ,QAAQ,EAAE;AACpB,SAAK,YAAY,KAAK,aAAa;AACnC,SAAK,SAAS,KAAK,SAAS,WAAW,MAAM,KAAK,UAAU;AAC5D,SAAK,QAAQ,KAAK,SAAS,CAAC;AAAA,EAC9B;AAAA,EAEQ,aAAa,MAA0B,QAAiB;AAC9D,UAAM,UAAmC;AAAA,MACvC,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,MACf;AAAA,IACF;AACA,QAAI,KAAK,OAAO,OAAQ,SAAQ,QAAQ,KAAK;AAC7C,QAAI,KAAK,gBAAgB,OAAW,SAAQ,cAAc,KAAK;AAC/D,QAAI,KAAK,cAAc,OAAW,SAAQ,aAAa,KAAK;AAC5D,QAAI,KAAK,eAAgB,SAAQ,kBAAkB,KAAK;AACxD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,KAAK,MAAiD;AAC1D,UAAM,OAAO,IAAI,gBAAgB;AACjC,UAAM,QAAQ,WAAW,MAAM,KAAK,MAAM,GAAG,KAAK,SAAS;AAC3D,UAAM,SAAS,KAAK,UAAU,KAAK;AAEnC,QAAI;AACF,YAAM,OAAO,MAAM;AAAA,QACjB,KAAK;AAAA,QACL,GAAG,KAAK,OAAO;AAAA,QACf;AAAA,UACE,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,eAAe,UAAU,KAAK,MAAM;AAAA,YACpC,gBAAgB;AAAA,UAClB;AAAA,UACA,MAAM,KAAK,UAAU,KAAK,aAAa,MAAM,KAAK,CAAC;AAAA,UACnD;AAAA,QACF;AAAA,QACA,EAAE,GAAG,KAAK,OAAO,OAAO;AAAA,MAC1B;AACA,UAAI,CAAC,KAAK,IAAI;AACZ,cAAM,IAAI,MAAM,YAAY,KAAK,MAAM,KAAK,MAAM,KAAK,KAAK,CAAC,EAAE;AAAA,MACjE;AACA,YAAM,OAAY,MAAM,KAAK,KAAK;AAClC,YAAM,SAAS,KAAK,UAAU,CAAC,GAAG,WAAW,CAAC;AAC9C,aAAO;AAAA,QACL,SAAS,OAAO,WAAW;AAAA,QAC3B,kBAAkB,OAAO,qBAAqB;AAAA,QAC9C,WAAW,OAAO,cAAc,CAAC;AAAA,QACjC,OAAO,MAAM,QAAQ,KAAK,KAAK;AAAA,QAC/B,KAAK;AAAA,MACP;AAAA,IACF,UAAE;AACA,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,OAAO,OAAO,MAAuD;AACnE,UAAM,OAAO,IAAI,gBAAgB;AACjC,UAAM,QAAQ,WAAW,MAAM,KAAK,MAAM,GAAG,KAAK,SAAS;AAC3D,UAAM,SAAS,KAAK,UAAU,KAAK;AAEnC,QAAI;AACJ,QAAI;AAIF,aAAO,MAAM;AAAA,QACX,KAAK;AAAA,QACL,GAAG,KAAK,OAAO;AAAA,QACf;AAAA,UACE,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,eAAe,UAAU,KAAK,MAAM;AAAA,YACpC,gBAAgB;AAAA,YAChB,QAAQ;AAAA,UACV;AAAA,UACA,MAAM,KAAK,UAAU,KAAK,aAAa,MAAM,IAAI,CAAC;AAAA,UAClD;AAAA,QACF;AAAA,QACA,EAAE,GAAG,KAAK,OAAO,OAAO;AAAA,MAC1B;AAAA,IACF,SAAS,KAAK;AACZ,mBAAa,KAAK;AAClB,YAAM;AAAA,IACR;AACA,QAAI,CAAC,KAAK,MAAM,CAAC,KAAK,MAAM;AAC1B,mBAAa,KAAK;AAClB,YAAM,IAAI,MAAM,YAAY,KAAK,MAAM,KAAK,MAAM,KAAK,KAAK,EAAE,MAAM,MAAM,EAAE,CAAC,EAAE;AAAA,IACjF;AAEA,UAAM,QAAuB,CAAC;AAC9B,QAAI,OAAO;AACX,UAAM,SAAS,aAAa;AAAA,MAC1B,SAAS,CAAC,OAA2B;AACnC,YAAI,CAAC,GAAG,QAAQ,GAAG,SAAS,UAAU;AACpC,iBAAO;AACP;AAAA,QACF;AACA,YAAI;AACF,gBAAM,OAAO,KAAK,MAAM,GAAG,IAAI;AAC/B,gBAAM,QAAQ,KAAK,UAAU,CAAC,GAAG,SAAS,CAAC;AAC3C,gBAAM,eAAe,KAAK,UAAU,CAAC,GAAG,iBAAiB;AACzD,gBAAM,QAAqB,EAAE,KAAK,MAAM,aAAa;AACrD,cAAI,OAAO,MAAM,YAAY,YAAY,MAAM,QAAQ,SAAS,GAAG;AACjE,kBAAM,eAAe,MAAM;AAAA,UAC7B;AACA,cAAI,OAAO,MAAM,sBAAsB,YAAY,MAAM,kBAAkB,SAAS,GAAG;AACrF,kBAAM,iBAAiB,MAAM;AAAA,UAC/B;AACA,cAAI,MAAM,QAAQ,MAAM,UAAU,KAAK,MAAM,WAAW,SAAS,GAAG;AAClE,kBAAM,KAAK,MAAM,WAAW,CAAC;AAC7B,kBAAM,gBAAgB;AAAA,cACpB,OAAO,GAAG,SAAS;AAAA,cACnB,IAAI,GAAG;AAAA,cACP,MAAM,GAAG,UAAU;AAAA,cACnB,gBAAgB,GAAG,UAAU;AAAA,YAC/B;AAAA,UACF;AACA,cAAI,KAAK,OAAO;AACd,kBAAM,QAAQ,MAAM,QAAQ,KAAK,KAAK;AAAA,UACxC;AACA,gBAAM,KAAK,KAAK;AAAA,QAClB,QAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF,CAAC;AAED,UAAM,SAAS,KAAK,KAAK,UAAU;AACnC,UAAM,UAAU,IAAI,YAAY;AAChC,QAAI;AACF,aAAO,MAAM;AACX,YAAI,MAAM,SAAS,GAAG;AACpB,gBAAM,MAAM,MAAM;AAClB;AAAA,QACF;AACA,YAAI,KAAM;AACV,cAAM,EAAE,OAAO,MAAM,WAAW,IAAI,MAAM,OAAO,KAAK;AACtD,YAAI,WAAY;AAChB,eAAO,KAAK,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC,CAAC;AAAA,MACrD;AACA,aAAO,MAAM,SAAS,EAAG,OAAM,MAAM,MAAM;AAAA,IAC7C,UAAE;AACA,mBAAa,KAAK;AAClB,aAAO,YAAY;AAAA,IACrB;AAAA,EACF;AACF;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/client-KEA2D52Q.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|