dskcode 0.1.40 → 0.1.42

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,707 +0,0 @@
1
- // src/provider/models.ts
2
- var SUPPORTED_MODELS = {
3
- "deepseek-v4-flash": {
4
- id: "deepseek-v4-flash",
5
- displayName: "DeepSeek V4 Flash",
6
- /** 上下文窗口大小(token) */
7
- contextWindow: 1e6,
8
- /** 输入价格(元 / 百万 token,缓存未命中) */
9
- inputPricePerMillion: 1,
10
- /** 输出价格(元 / 百万 token) */
11
- outputPricePerMillion: 2,
12
- /** 输入价格(元 / 百万 token,缓存命中) */
13
- cacheHitPricePerMillion: 0.02
14
- },
15
- "deepseek-v4-pro": {
16
- id: "deepseek-v4-pro",
17
- displayName: "DeepSeek V4 Pro",
18
- /** 上下文窗口大小(token) */
19
- contextWindow: 1e6,
20
- /** 输入价格(元 / 百万 token,缓存未命中) */
21
- inputPricePerMillion: 3,
22
- /** 输出价格(元 / 百万 token) */
23
- outputPricePerMillion: 6,
24
- /** 输入价格(元 / 百万 token,缓存命中) */
25
- cacheHitPricePerMillion: 0.025
26
- }
27
- };
28
- var SUPPORTED_MODEL_IDS = Object.keys(SUPPORTED_MODELS);
29
- function isSupportedModel(model) {
30
- return model in SUPPORTED_MODELS;
31
- }
32
- function getModelMeta(model) {
33
- return SUPPORTED_MODELS[model];
34
- }
35
- function isCJK(char) {
36
- const code = char.codePointAt(0);
37
- return code >= 19968 && code <= 40959 || // CJK 扩展 A
38
- code >= 13312 && code <= 19903 || // CJK 扩展 B 及其他
39
- code >= 131072 && code <= 173791 || // CJK 兼容汉字
40
- code >= 63744 && code <= 64255 || // 全角字符
41
- code >= 65281 && code <= 65376;
42
- }
43
- function estimateTokens(text) {
44
- let cjkCount = 0;
45
- let otherCount = 0;
46
- for (const char of text) {
47
- if (isCJK(char)) {
48
- cjkCount++;
49
- } else {
50
- otherCount++;
51
- }
52
- }
53
- const tokens = cjkCount * 0.6 + otherCount * 0.3;
54
- return Math.max(1, Math.ceil(tokens));
55
- }
56
- function calculateCost(usage, model) {
57
- const meta = SUPPORTED_MODELS[model];
58
- const cached = usage.cachedPromptTokens ?? 0;
59
- const nonCached = usage.promptTokens - cached;
60
- const inputCost = nonCached * meta.inputPricePerMillion / 1e6;
61
- const cacheHitCost = cached * meta.cacheHitPricePerMillion / 1e6;
62
- const outputCost = usage.completionTokens * meta.outputPricePerMillion / 1e6;
63
- return {
64
- inputCost,
65
- cacheHitCost,
66
- outputCost,
67
- totalCost: inputCost + cacheHitCost + outputCost
68
- };
69
- }
70
-
71
- // src/provider/errors.ts
72
- var ProviderError = class extends Error {
73
- constructor(message, code, statusCode) {
74
- super(message);
75
- this.code = code;
76
- this.statusCode = statusCode;
77
- this.name = "ProviderError";
78
- }
79
- code;
80
- statusCode;
81
- };
82
- var AuthError = class extends ProviderError {
83
- constructor(message, statusCode) {
84
- super(message, "AUTH_ERROR", statusCode);
85
- this.name = "AuthError";
86
- }
87
- };
88
- var RateLimitError = class extends ProviderError {
89
- /** 建议等待的毫秒数 */
90
- retryAfterMs;
91
- constructor(message, retryAfterMs) {
92
- super(message, "RATE_LIMIT", 429);
93
- this.name = "RateLimitError";
94
- this.retryAfterMs = retryAfterMs;
95
- }
96
- };
97
- var ServerError = class extends ProviderError {
98
- constructor(message, statusCode) {
99
- super(message, "SERVER_ERROR", statusCode);
100
- this.name = "ServerError";
101
- }
102
- };
103
- var NetworkError = class extends ProviderError {
104
- /** 导致网络错误的底层错误 */
105
- originalError;
106
- constructor(message, originalError) {
107
- super(message, "NETWORK_ERROR");
108
- this.name = "NetworkError";
109
- this.originalError = originalError;
110
- }
111
- };
112
- var TimeoutError = class extends ProviderError {
113
- /** 触发超时的等待时间(毫秒) */
114
- timeoutMs;
115
- constructor(message, timeoutMs) {
116
- super(message, "TIMEOUT");
117
- this.name = "TimeoutError";
118
- this.timeoutMs = timeoutMs;
119
- }
120
- };
121
- var StreamIdleTimeoutError = class extends ProviderError {
122
- /** 触发空闲超时的最大间隔(毫秒) */
123
- idleMs;
124
- constructor(message, idleMs) {
125
- super(message, "STREAM_IDLE_TIMEOUT");
126
- this.name = "StreamIdleTimeoutError";
127
- this.idleMs = idleMs;
128
- }
129
- };
130
- var ModelNotSupportedError = class extends ProviderError {
131
- constructor(model) {
132
- super(
133
- `\u4E0D\u652F\u6301\u7684\u6A21\u578B: "${model}"\u3002dskcode \u4EC5\u652F\u6301: deepseek-v4-flash, deepseek-v4-pro`,
134
- "MODEL_NOT_SUPPORTED"
135
- );
136
- this.name = "ModelNotSupportedError";
137
- }
138
- };
139
- function mapHttpError(status, body) {
140
- switch (status) {
141
- case 401:
142
- case 403:
143
- return new AuthError(
144
- `\u8BA4\u8BC1\u5931\u8D25\uFF1A\u8BF7\u68C0\u67E5 API Key \u662F\u5426\u6B63\u786E\u3002(${status})`,
145
- status
146
- );
147
- case 429: {
148
- let retryAfterMs;
149
- try {
150
- const parsed = JSON.parse(body);
151
- const msg = parsed.error?.message ?? "";
152
- const match = /(\d+)\s*second/i.exec(msg);
153
- if (match?.[1]) {
154
- retryAfterMs = Number(match[1]) * 1e3;
155
- }
156
- } catch {
157
- }
158
- return new RateLimitError(
159
- `\u8BF7\u6C42\u8FC7\u4E8E\u9891\u7E41\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5\u3002${retryAfterMs ? `\u5EFA\u8BAE\u7B49\u5F85 ${Math.ceil(retryAfterMs / 1e3)} \u79D2\u3002` : ""}`,
160
- retryAfterMs
161
- );
162
- }
163
- case 400: {
164
- let detail = "";
165
- try {
166
- const parsed = JSON.parse(body);
167
- detail = parsed.error?.message ?? "";
168
- } catch {
169
- }
170
- return new ProviderError(
171
- `\u8BF7\u6C42\u53C2\u6570\u9519\u8BEF${detail ? `: ${detail}` : ""}`,
172
- "BAD_REQUEST",
173
- status
174
- );
175
- }
176
- default:
177
- if (status >= 500) {
178
- return new ServerError(
179
- `\u670D\u52A1\u7AEF\u9519\u8BEF (${status})\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5\u3002`,
180
- status
181
- );
182
- }
183
- return new ProviderError(`\u8BF7\u6C42\u5931\u8D25 (${status})`, "UNKNOWN_ERROR", status);
184
- }
185
- }
186
- function isRetryableError(err) {
187
- return err instanceof RateLimitError || err instanceof ServerError || err instanceof NetworkError;
188
- }
189
-
190
- // src/provider/retry.ts
191
- var DEFAULT_RETRY_OPTIONS = {
192
- maxRetries: 3,
193
- baseDelayMs: 1e3,
194
- maxDelayMs: 3e4
195
- };
196
- function computeBackoffDelay(attempt, baseDelayMs, maxDelayMs) {
197
- const exp = Math.pow(2, attempt - 1);
198
- const jitter = Math.random() * (baseDelayMs / 2);
199
- const delay = baseDelayMs * exp + jitter;
200
- return Math.min(delay, maxDelayMs);
201
- }
202
- async function withRetry(fn, options = {}) {
203
- const maxRetries = options.maxRetries ?? DEFAULT_RETRY_OPTIONS.maxRetries;
204
- const baseDelayMs = options.baseDelayMs ?? DEFAULT_RETRY_OPTIONS.baseDelayMs;
205
- const maxDelayMs = options.maxDelayMs ?? DEFAULT_RETRY_OPTIONS.maxDelayMs;
206
- let lastError;
207
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
208
- try {
209
- return await fn();
210
- } catch (err) {
211
- lastError = err;
212
- if (!(err instanceof ProviderError) || !isRetryableError(err)) {
213
- throw err;
214
- }
215
- if (attempt >= maxRetries) break;
216
- let delayMs;
217
- if (err instanceof RateLimitError && err.retryAfterMs !== void 0) {
218
- delayMs = Math.min(err.retryAfterMs, maxDelayMs);
219
- } else {
220
- delayMs = computeBackoffDelay(attempt + 1, baseDelayMs, maxDelayMs);
221
- }
222
- options.onRetry?.(attempt + 1, err, delayMs);
223
- await sleep(delayMs);
224
- }
225
- }
226
- throw lastError instanceof Error ? lastError : new Error("withRetry: \u672A\u77E5\u9519\u8BEF");
227
- }
228
- var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
229
-
230
- // src/provider/client.ts
231
- var DEFAULT_CONNECT_TIMEOUT_MS = 3e4;
232
- var HttpClient = class {
233
- #connectTimeoutMs;
234
- #maxRetries;
235
- #retryBaseDelayMs;
236
- #retryMaxDelayMs;
237
- constructor(config = {}) {
238
- this.#connectTimeoutMs = config.connectTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS;
239
- this.#maxRetries = config.maxRetries ?? 3;
240
- this.#retryBaseDelayMs = config.retryBaseDelayMs ?? 1e3;
241
- this.#retryMaxDelayMs = config.retryMaxDelayMs ?? 3e4;
242
- }
243
- /**
244
- * 发起单次 HTTP 请求(带连接超时,不重试)。
245
- *
246
- * - 自动附加 `Content-Type: application/json`(若 body 是字符串)
247
- * - 非 2xx 响应:抛出 mapHttpError 映射后的 ProviderError
248
- * - 网络错误:抛出 NetworkError
249
- * - 超时:抛出 TimeoutError
250
- *
251
- * @param url 请求 URL
252
- * @param init fetch 初始化(method/headers/body)
253
- * @param options 请求级选项(超时、中止信号)
254
- * @returns 成功(2xx)的 Response
255
- */
256
- async request(url, init = {}, options = {}) {
257
- const timeoutMs = options.connectTimeoutMs === void 0 ? this.#connectTimeoutMs : options.connectTimeoutMs;
258
- const headers = new Headers(init.headers);
259
- if (init.body && typeof init.body === "string" && !headers.has("Content-Type")) {
260
- headers.set("Content-Type", "application/json");
261
- }
262
- const { signal, cleanup } = this.#mergeSignals(
263
- options.signal,
264
- timeoutMs
265
- );
266
- let response;
267
- try {
268
- response = await fetch(url, {
269
- ...init,
270
- headers,
271
- signal
272
- });
273
- } catch (err) {
274
- if (options.signal?.aborted) {
275
- throw new ProviderError("\u8BF7\u6C42\u5DF2\u53D6\u6D88", "ABORTED");
276
- }
277
- if (signal?.aborted && !options.signal?.aborted) {
278
- throw new TimeoutError(
279
- `\u8FDE\u63A5\u8D85\u65F6\uFF08${timeoutMs}ms\uFF09: ${url}`,
280
- timeoutMs
281
- );
282
- }
283
- throw new NetworkError(
284
- `\u7F51\u7EDC\u9519\u8BEF\uFF1A\u65E0\u6CD5\u8FDE\u63A5\u5230 ${url}`,
285
- err instanceof Error ? err : void 0
286
- );
287
- } finally {
288
- cleanup();
289
- }
290
- if (!response.ok) {
291
- const body = await response.text().catch(() => "");
292
- throw mapHttpError(response.status, body);
293
- }
294
- return response;
295
- }
296
- /**
297
- * 发起带重试的 HTTP 请求。
298
- *
299
- * 等价于 request,但用 withRetry 包装:429 / 5xx / 网络错误会自动重试。
300
- * 流式响应一旦获得 2xx,重试即停止,剩余流式稳定性交给 SSE 解析器。
301
- */
302
- async requestWithRetry(url, init = {}, options = {}) {
303
- const retryOptions = options.retry === false ? { maxRetries: 0 } : options.retry ?? {
304
- maxRetries: this.#maxRetries,
305
- baseDelayMs: this.#retryBaseDelayMs,
306
- maxDelayMs: this.#retryMaxDelayMs
307
- };
308
- return withRetry(() => this.request(url, init, options), retryOptions);
309
- }
310
- /**
311
- * 合并外部 signal 与连接超时 signal。
312
- *
313
- * 策略:
314
- * - 若 timeoutMs <= 0 且无外部 signal → 不使用 signal
315
- * - 若已有外部 signal 且无超时 → 直接使用外部 signal
316
- * - 否则用 AbortSignal.any([外部, 超时]) 合并(Node 20+ 原生支持)
317
- *
318
- * @returns { signal, cleanup } 调用方应在 finally 调用 cleanup 取消监听
319
- */
320
- #mergeSignals(external, timeoutMs) {
321
- const useTimeout = timeoutMs > 0;
322
- if (!external && !useTimeout) {
323
- return { signal: void 0, cleanup: () => {
324
- } };
325
- }
326
- if (!useTimeout) {
327
- return { signal: external, cleanup: () => {
328
- } };
329
- }
330
- const controller = new AbortController();
331
- const timer = setTimeout(() => controller.abort(), timeoutMs);
332
- const onExternalAbort = () => controller.abort();
333
- if (external) {
334
- if (external.aborted) controller.abort();
335
- else external.addEventListener("abort", onExternalAbort, { once: true });
336
- }
337
- return {
338
- signal: controller.signal,
339
- cleanup: () => {
340
- clearTimeout(timer);
341
- if (external) {
342
- external.removeEventListener("abort", onExternalAbort);
343
- }
344
- }
345
- };
346
- }
347
- };
348
-
349
- // src/provider/sse.ts
350
- async function* parseSSE(response, options = {}) {
351
- const reader = response.body?.getReader();
352
- if (!reader) {
353
- throw new Error("SSE \u54CD\u5E94\u4F53\u4E3A\u7A7A\uFF0C\u65E0\u6CD5\u89E3\u6790");
354
- }
355
- const decoder = new TextDecoder();
356
- let buffer = "";
357
- let pendingData = [];
358
- let pendingEvent;
359
- let pendingId;
360
- let pendingRetry;
361
- const idleMs = options.idleTimeoutMs ?? 6e4;
362
- const shouldStopOnDone = options.stopOnDone !== false;
363
- let streamDone = false;
364
- function* flush() {
365
- if (pendingData.length === 0) {
366
- pendingEvent = void 0;
367
- pendingId = void 0;
368
- pendingRetry = void 0;
369
- return;
370
- }
371
- const evt = { data: pendingData.join("\n") };
372
- if (pendingEvent) evt.event = pendingEvent;
373
- if (pendingId) evt.id = pendingId;
374
- if (pendingRetry !== void 0) evt.retry = pendingRetry;
375
- pendingData = [];
376
- pendingEvent = void 0;
377
- pendingId = void 0;
378
- pendingRetry = void 0;
379
- if (shouldStopOnDone && evt.data === "[DONE]") {
380
- streamDone = true;
381
- }
382
- yield evt;
383
- }
384
- function* processLine(rawLine) {
385
- const line = rawLine.endsWith("\r") ? rawLine.slice(0, -1) : rawLine;
386
- if (line === "") {
387
- yield* flush();
388
- return;
389
- }
390
- if (line.startsWith(":")) return;
391
- const colonIdx = line.indexOf(":");
392
- if (colonIdx === -1) {
393
- applyField(line, "");
394
- return;
395
- }
396
- const field = line.slice(0, colonIdx);
397
- let value = line.slice(colonIdx + 1);
398
- if (value.startsWith(" ")) value = value.slice(1);
399
- applyField(field, value);
400
- }
401
- function applyField(field, value) {
402
- switch (field) {
403
- case "event":
404
- pendingEvent = value;
405
- break;
406
- case "data":
407
- pendingData.push(value);
408
- break;
409
- case "id":
410
- pendingId = value;
411
- break;
412
- case "retry": {
413
- const n = Number(value);
414
- if (Number.isFinite(n)) pendingRetry = n;
415
- break;
416
- }
417
- default:
418
- break;
419
- }
420
- }
421
- try {
422
- while (true) {
423
- if (options.signal?.aborted) return;
424
- const readResult = await readWithTimeout(reader, idleMs, options.signal);
425
- if (readResult === null) return;
426
- const { done, value } = readResult;
427
- if (done) {
428
- buffer += decoder.decode();
429
- if (buffer.length > 0) {
430
- const line = buffer.endsWith("\r") ? buffer.slice(0, -1) : buffer;
431
- if (line !== "") yield* processLine(line);
432
- buffer = "";
433
- }
434
- yield* flush();
435
- if (streamDone) return;
436
- return;
437
- }
438
- buffer += decoder.decode(value, { stream: true });
439
- let nl;
440
- while ((nl = buffer.indexOf("\n")) !== -1) {
441
- const line = buffer.slice(0, nl);
442
- buffer = buffer.slice(nl + 1);
443
- yield* processLine(line);
444
- if (streamDone) return;
445
- }
446
- }
447
- } finally {
448
- reader.releaseLock();
449
- }
450
- }
451
- function readWithTimeout(reader, idleMs, signal) {
452
- if (signal?.aborted) return Promise.resolve(null);
453
- return new Promise((resolve, reject) => {
454
- let settled = false;
455
- const timer = setTimeout(() => {
456
- if (settled) return;
457
- settled = true;
458
- reject(new StreamIdleTimeoutError(`\u6D41\u5F0F\u7A7A\u95F2\u8D85\u65F6\uFF08${idleMs}ms \u65E0\u6570\u636E\uFF09`, idleMs));
459
- }, idleMs);
460
- const onAbort = () => {
461
- if (settled) return;
462
- settled = true;
463
- clearTimeout(timer);
464
- resolve(null);
465
- };
466
- if (signal) signal.addEventListener("abort", onAbort, { once: true });
467
- reader.read().then((result) => {
468
- if (settled) return;
469
- settled = true;
470
- clearTimeout(timer);
471
- if (signal) signal.removeEventListener("abort", onAbort);
472
- resolve(result);
473
- }).catch((err) => {
474
- if (settled) return;
475
- settled = true;
476
- clearTimeout(timer);
477
- if (signal) signal.removeEventListener("abort", onAbort);
478
- reject(err);
479
- });
480
- });
481
- }
482
-
483
- // src/provider/deepseek-protocol.ts
484
- async function* streamCompletion(client, baseUrl, apiKey, request, opts) {
485
- const url = `${baseUrl}/chat/completions`;
486
- const idleTimeoutMs = opts?.idleTimeoutMs ?? 6e4;
487
- const response = await client.requestWithRetry(
488
- url,
489
- {
490
- method: "POST",
491
- headers: {
492
- Authorization: `Bearer ${apiKey}`
493
- },
494
- body: JSON.stringify(request)
495
- },
496
- { signal: opts?.signal }
497
- );
498
- for await (const evt of parseSSE(response, { idleTimeoutMs, signal: opts?.signal })) {
499
- if (evt.data === "[DONE]") return;
500
- let chunk;
501
- try {
502
- chunk = JSON.parse(evt.data);
503
- } catch {
504
- continue;
505
- }
506
- yield chunk;
507
- }
508
- }
509
- async function getBalance(client, baseUrl, apiKey) {
510
- const response = await client.request(`${baseUrl}/user/balance`, {
511
- method: "GET",
512
- headers: { Authorization: `Bearer ${apiKey}` }
513
- });
514
- const data = await response.json();
515
- return {
516
- isAvailable: data.is_available,
517
- balances: data.balance_infos.map((b) => ({
518
- currency: b.currency,
519
- totalBalance: Number(b.total_balance),
520
- grantedBalance: Number(b.granted_balance),
521
- toppedUpBalance: Number(b.topped_up_balance)
522
- }))
523
- };
524
- }
525
-
526
- // src/provider/deepseek.ts
527
- function intoDeepSeekMessages(messages) {
528
- return messages.map((msg) => {
529
- const mapped = {
530
- role: msg.role,
531
- content: msg.content || null
532
- };
533
- if (msg.name) mapped.name = msg.name;
534
- if (msg.toolCallId) mapped.tool_call_id = msg.toolCallId;
535
- if (msg.toolCalls && msg.toolCalls.length > 0) {
536
- mapped.tool_calls = msg.toolCalls.map((tc) => ({
537
- id: tc.id,
538
- type: "function",
539
- function: {
540
- name: tc.name,
541
- arguments: tc.arguments
542
- }
543
- }));
544
- }
545
- return mapped;
546
- });
547
- }
548
- var DeepSeekEventMapper = class {
549
- #toolCallsByIndex = /* @__PURE__ */ new Map();
550
- /**
551
- * 重置内部状态(每次新请求前调用)。
552
- */
553
- reset() {
554
- this.#toolCallsByIndex.clear();
555
- }
556
- /**
557
- * 将 DeepSeek 原始流式块映射为 ChatChunk 数组。
558
- * 一个 SSE 数据块可能生成 0~N 个 ChatChunk 事件。
559
- */
560
- mapEvent(chunk) {
561
- const choice = chunk.choices?.[0];
562
- if (!choice) return [];
563
- const events = [];
564
- const delta = choice.delta;
565
- const content = delta?.content ?? "";
566
- const reasoningContent = delta?.reasoning_content ?? "";
567
- const finishReason = this.#mapFinishReason(choice.finish_reason);
568
- if (delta?.tool_calls) {
569
- for (const tc of delta.tool_calls) {
570
- this.#accumulateToolCall(tc);
571
- }
572
- }
573
- let usage;
574
- if (chunk.usage) {
575
- usage = {
576
- promptTokens: chunk.usage.prompt_tokens,
577
- completionTokens: chunk.usage.completion_tokens,
578
- cachedPromptTokens: chunk.usage.prompt_cache_hit_tokens
579
- };
580
- }
581
- const shouldYieldToolCalls = finishReason === "tool_calls" && this.#toolCallsByIndex.size > 0;
582
- if (!content && !reasoningContent && finishReason === null && !shouldYieldToolCalls && !usage) {
583
- return [];
584
- }
585
- events.push({
586
- content,
587
- ...reasoningContent ? { reasoningContent } : {},
588
- finishReason,
589
- ...shouldYieldToolCalls ? { toolCalls: [...this.#toolCallsByIndex.values()] } : {},
590
- ...usage ? { usage } : {}
591
- });
592
- if (shouldYieldToolCalls) {
593
- this.#toolCallsByIndex.clear();
594
- }
595
- return events;
596
- }
597
- /** 将 DeepSeek 的 finish_reason 映射为内部类型 */
598
- #mapFinishReason(reason) {
599
- switch (reason) {
600
- case "stop":
601
- return "stop";
602
- case "tool_calls":
603
- return "tool_calls";
604
- case "length":
605
- return "length";
606
- default:
607
- return null;
608
- }
609
- }
610
- /** 累积一个工具调用分块 */
611
- #accumulateToolCall(tc) {
612
- const idx = tc.index ?? 0;
613
- const existing = this.#toolCallsByIndex.get(idx);
614
- if (!existing) {
615
- this.#toolCallsByIndex.set(idx, {
616
- id: tc.id ?? "",
617
- name: tc.function?.name ?? "",
618
- arguments: tc.function?.arguments ?? ""
619
- });
620
- } else {
621
- if (tc.id) existing.id = tc.id;
622
- if (tc.function?.name) existing.name = tc.function.name;
623
- if (tc.function?.arguments) {
624
- existing.arguments += tc.function.arguments;
625
- }
626
- }
627
- }
628
- };
629
- var DeepSeekProvider = class {
630
- #apiKey;
631
- #baseUrl;
632
- #model;
633
- #client;
634
- #idleTimeoutMs;
635
- #mapper = new DeepSeekEventMapper();
636
- name = "deepseek";
637
- constructor(config) {
638
- this.#apiKey = config.apiKey;
639
- this.#baseUrl = config.baseUrl.replace(/\/+$/, "");
640
- this.#model = config.model;
641
- this.#idleTimeoutMs = config.idleTimeoutMs ?? 6e4;
642
- this.#client = new HttpClient({
643
- connectTimeoutMs: config.connectTimeoutMs,
644
- maxRetries: config.maxRetries,
645
- retryBaseDelayMs: config.retryBaseDelayMs,
646
- retryMaxDelayMs: config.retryMaxDelayMs
647
- });
648
- }
649
- model() {
650
- return this.#model;
651
- }
652
- countTokens(text) {
653
- return estimateTokens(text);
654
- }
655
- /**
656
- * 查询账户余额。
657
- */
658
- async getBalance() {
659
- return getBalance(this.#client, this.#baseUrl, this.#apiKey);
660
- }
661
- /**
662
- * 发起聊天补全请求(流式)。
663
- */
664
- async *chat(messages, opts) {
665
- const apiMessages = intoDeepSeekMessages(messages);
666
- const request = {
667
- model: this.#model,
668
- messages: apiMessages,
669
- stream: true,
670
- max_tokens: opts?.maxTokens,
671
- temperature: opts?.temperature,
672
- // 从 ChatOptions 映射 thinking / reasoning_effort
673
- thinking: opts?.thinkingAllowed !== void 0 ? { type: opts.thinkingAllowed ? "enabled" : "disabled" } : void 0,
674
- reasoning_effort: opts?.thinkingEffort,
675
- // 从 ChatOptions 映射 response_format
676
- response_format: opts?.responseFormat ? { type: opts.responseFormat } : void 0,
677
- // 从 ChatOptions 映射 tool_choice
678
- tool_choice: opts?.toolChoice
679
- };
680
- if (opts?.tools && opts.tools.length > 0) {
681
- request.tools = opts.tools;
682
- }
683
- this.#mapper.reset();
684
- const stream = streamCompletion(this.#client, this.#baseUrl, this.#apiKey, request, {
685
- signal: opts?.signal,
686
- idleTimeoutMs: this.#idleTimeoutMs
687
- });
688
- for await (const rawChunk of stream) {
689
- const events = this.#mapper.mapEvent(rawChunk);
690
- for (const event of events) {
691
- yield event;
692
- }
693
- }
694
- }
695
- };
696
-
697
- export {
698
- SUPPORTED_MODELS,
699
- isSupportedModel,
700
- getModelMeta,
701
- estimateTokens,
702
- calculateCost,
703
- ModelNotSupportedError,
704
- DeepSeekEventMapper,
705
- DeepSeekProvider
706
- };
707
- //# sourceMappingURL=chunk-LWOBXEMJ.js.map