dsh-multi-router 0.5.3 → 0.5.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.
@@ -2,9 +2,11 @@ import {
2
2
  isFreeModel,
3
3
  reasoningModes,
4
4
  writePrivateJson
5
- } from "./chunk-U7J4ABAM.js";
5
+ } from "./chunk-MCHV2R25.js";
6
6
 
7
7
  // src/telemetry.mjs
8
+ import { createHash, randomUUID } from "node:crypto";
9
+ import { assistantStreamFirstTokenTime } from "@deepseek-ai/dsh-llm";
8
10
  import { readFile } from "node:fs/promises";
9
11
  var empty = () => ({ requests: 0, failures: 0, input: 0, output: 0, tokens: 0, unmetered: 0 });
10
12
  var day = (at) => new Date(at).toLocaleDateString("en-CA", { timeZone: "Asia/Shanghai" });
@@ -14,7 +16,7 @@ var Telemetry = class {
14
16
  constructor(file, now = Date.now) {
15
17
  this.file = file;
16
18
  this.now = now;
17
- this.retentionDays = 3;
19
+ this.retentionDays = 30;
18
20
  this.data = { accounts: {}, routes: {}, days: {}, rounds: {}, expiringRounds: {}, events: [] };
19
21
  this.queue = Promise.resolve();
20
22
  }
@@ -101,7 +103,11 @@ var Telemetry = class {
101
103
  output,
102
104
  tokens: measured(event.usage?.total_tokens) ?? (input !== null && output !== null ? input + output : null),
103
105
  cachedInput: measured(event.usage?.prompt_tokens_details?.cached_tokens),
104
- reasoningOutput: measured(event.usage?.completion_tokens_details?.reasoning_tokens)
106
+ reasoningOutput: measured(event.usage?.completion_tokens_details?.reasoning_tokens),
107
+ callId: event.callId ?? null,
108
+ session: event.session ?? null,
109
+ timing: event.timing ? Object.fromEntries(["modelMs", "ttftMs", "decodeMs", "decodeTokens"].map((k) => [k, measured(event.timing[k])])) : null,
110
+ timingSource: event.timing ? "upstream" : null
105
111
  });
106
112
  const dates = Object.keys(this.data.days).sort();
107
113
  for (const key of dates.slice(0, -31)) delete this.data.days[key];
@@ -119,14 +125,15 @@ var Telemetry = class {
119
125
  return { ...structuredClone(this.data), retentionDays: this.retentionDays, today: day(this.now()), updatedAt: this.now() };
120
126
  }
121
127
  };
122
- function meterResponse(response, complete, signal) {
128
+ function meterResponse(response, complete, signal, { now = () => performance.now(), startedAt = now() } = {}) {
123
129
  if (!response.body) return response;
124
130
  const reader = response.body.getReader(), decoder = new TextDecoder();
125
- let pending = "", usage, ended = false, failed = false, finished = false;
131
+ let pending = "", usage, ended = false, failed = false, finished = false, firstToken = null, terminalAt = null;
126
132
  async function finish(cancelled = false) {
127
133
  if (finished) return;
128
134
  finished = true;
129
- await complete({ usage, ok: ended && !failed && !cancelled, cancelled });
135
+ const end = terminalAt ?? now();
136
+ await complete({ usage, ok: ended && !failed && !cancelled, cancelled, timing: { modelMs: Math.max(0, end - startedAt), ttftMs: firstToken === null ? null : Math.max(0, firstToken - startedAt), decodeMs: firstToken === null ? null : Math.max(0, end - firstToken), decodeTokens: firstToken === null ? null : measured(usage?.completion_tokens) } });
130
137
  }
131
138
  function inspect(bytes) {
132
139
  pending += decoder.decode(bytes, { stream: true });
@@ -137,13 +144,21 @@ function meterResponse(response, complete, signal) {
137
144
  const data = frame.split(/\r?\n/).filter((l) => l.startsWith("data:")).map((l) => l.slice(5).trimStart()).join("\n");
138
145
  if (data === "[DONE]") {
139
146
  ended = true;
147
+ terminalAt ??= now();
140
148
  continue;
141
149
  }
142
150
  try {
143
151
  const value = JSON.parse(data);
144
152
  if (value.usage && ["prompt_tokens", "completion_tokens", "total_tokens"].some((k) => Number.isFinite(value.usage[k]) && value.usage[k] >= 0)) usage = value.usage;
145
153
  if (value.error) failed = true;
146
- if (value.choices?.some((c) => c.finish_reason)) ended = true;
154
+ if (firstToken === null && value.choices?.some((c) => {
155
+ const d = c.delta;
156
+ return [d?.content, d?.reasoning_content, d?.reasoning].some((v) => typeof v === "string" && v.trim()) || d?.tool_calls?.some((t) => t.function?.name || t.function?.arguments);
157
+ })) firstToken = now();
158
+ if (value.choices?.some((c) => c.finish_reason)) {
159
+ ended = true;
160
+ terminalAt ??= now();
161
+ }
147
162
  } catch {
148
163
  }
149
164
  }
@@ -179,6 +194,66 @@ function meterResponse(response, complete, signal) {
179
194
  });
180
195
  return new Response(body, { status: response.status, headers: response.headers });
181
196
  }
197
+ var SessionMetrics = class {
198
+ constructor(telemetry) {
199
+ this.telemetry = telemetry;
200
+ this.steps = /* @__PURE__ */ new Map();
201
+ }
202
+ key(id) {
203
+ return createHash("sha256").update(String(id)).digest("hex").slice(0, 24);
204
+ }
205
+ beginCall(sessionId, purpose) {
206
+ const callId = randomUUID(), session = sessionId == null ? null : this.key(sessionId);
207
+ const step = session && this.steps.get(session);
208
+ if (step && !purpose) step.callId = callId;
209
+ return { callId, session };
210
+ }
211
+ event(session, event) {
212
+ const key = this.key(session.id), d = event.data;
213
+ if (event.type === "step/start") {
214
+ this.steps.set(key, { turn: d.turn, step: d.step, start: event.time, first: null, calls: /* @__PURE__ */ new Map(), toolMs: 0, toolCount: 0, toolsCompleted: 0 });
215
+ return;
216
+ }
217
+ const step = this.steps.get(key);
218
+ if (!step) return;
219
+ if (d.turn !== void 0 && (d.turn !== step.turn || d.step !== void 0 && d.step !== step.step)) return;
220
+ if (event.type === "assistant/attempt") {
221
+ step.first ??= assistantStreamFirstTokenTime(d.stream) ?? null;
222
+ return;
223
+ }
224
+ const row = this.telemetry.data.events.find((e) => e.callId === step.callId && e.session === key);
225
+ if (event.type === "assistant/message") {
226
+ if (!row || d.interrupted) return;
227
+ const first = step.first ?? assistantStreamFirstTokenTime(d.stream) ?? null;
228
+ const output = measured(d.usage?.outputTokens);
229
+ row.timing = {
230
+ modelMs: Math.max(0, event.time - step.start),
231
+ ttftMs: first === null ? null : Math.max(0, first - step.start),
232
+ decodeMs: first === null || output === null ? null : Math.max(0, event.time - first),
233
+ decodeTokens: first === null ? null : output
234
+ };
235
+ row.timingSource = "dsh-step";
236
+ } else if (event.type === "tool/call" && row?.timingSource === "dsh-step") {
237
+ if (!step.calls.has(d.callId)) {
238
+ step.calls.set(d.callId, event.time);
239
+ step.toolCount++;
240
+ }
241
+ } else if (event.type === "tool/result" && step.calls.has(d.message?.source?.callId)) {
242
+ const id = d.message.source.callId;
243
+ step.toolMs += Math.max(0, event.time - step.calls.get(id));
244
+ step.toolsCompleted++;
245
+ step.calls.delete(id);
246
+ } else if (event.type === "step/end" || event.type === "turn/end") {
247
+ this.steps.delete(key);
248
+ } else return;
249
+ if (row?.timingSource !== "dsh-step") return;
250
+ Object.assign(row.timing, { toolMs: step.toolMs, toolCount: step.toolCount, toolsCompleted: step.toolsCompleted });
251
+ return this.telemetry.persist();
252
+ }
253
+ dispose(session) {
254
+ this.steps.delete(this.key(session.id));
255
+ }
256
+ };
182
257
 
183
258
  // src/router.mjs
184
259
  var RouteError = class extends Error {
@@ -303,7 +378,7 @@ var Router = class {
303
378
  if (!attempts.length && ["tokens", "credits"].includes(strategy)) return `\u6240\u6709\u8D26\u53F7\u7684\u672C\u8F6E${strategy === "tokens" ? " Token" : "\u79EF\u5206"}\u989D\u5EA6\u5DF2\u7528\u5B8C\uFF0C\u6216\u56E0\u7F3A\u5C11\u7528\u91CF\u8BA1\u91CF\u800C\u6682\u505C\u53C2\u4E0E\u8F6E\u6362`;
304
379
  return void 0;
305
380
  }
306
- async chat(input, signal) {
381
+ async chat(input, signal, metadata = {}) {
307
382
  const alias = input.model;
308
383
  if (!Array.isArray(input.messages) || !input.messages.length || input.stream !== true) throw new RouteError(400, "messages_and_stream_true_required");
309
384
  const initialRoute = this.config.routes[alias];
@@ -384,7 +459,7 @@ var Router = class {
384
459
  signal?.throwIfAborted();
385
460
  const { account, target, key } = candidate;
386
461
  if (!available(candidate)) continue;
387
- let result, actualModel;
462
+ let result, actualModel, startedAt;
388
463
  try {
389
464
  const client = await abortable(this.client(account), signal);
390
465
  const catalog = await abortable(client.models(signal), signal);
@@ -406,17 +481,18 @@ var Router = class {
406
481
  const dedupe = `${account.id}:${model.id}`;
407
482
  if (tried.has(dedupe)) continue;
408
483
  tried.add(dedupe);
484
+ startedAt = performance.now();
409
485
  result = await abortable(client.chat({ ...input, model: model.id }, signal), signal);
410
486
  signal?.throwIfAborted();
411
487
  if (result.ok) {
412
488
  this.active.set(alias, key);
413
489
  this.onAttempt({ account: account.id, provider: account.provider, alias, model: model.id, status: 200 });
414
490
  const response = this.telemetry ? meterResponse(result.response, async (summary) => {
415
- await this.telemetry.record({ ...summary, account: account.id, provider: account.provider, alias, model: model.id, accepted: true, status: summary.ok ? 200 : summary.cancelled ? 499 : 502 });
491
+ await this.telemetry.record({ ...summary, ...metadata, account: account.id, provider: account.provider, alias, model: model.id, accepted: true, status: summary.ok ? 200 : summary.cancelled ? 499 : 502 });
416
492
  await this.syncExpiring(alias, route, expiryCandidates, below);
417
493
  if (strategy === "credits" || route.preferExpiringCredits) void this.monitor?.(account).then(() => this.syncExpiring(alias, route, expiryCandidates, below)).catch(() => {
418
494
  });
419
- }, signal) : result.response;
495
+ }, signal, { startedAt }) : result.response;
420
496
  return { response, account: account.id, provider: account.provider };
421
497
  }
422
498
  } catch (error) {
@@ -427,7 +503,7 @@ var Router = class {
427
503
  const status = result.status >= 400 && result.status <= 599 ? result.status : 502;
428
504
  const attempt = { account: account.id, provider: account.provider, status, kind: result.kind };
429
505
  attempts.push(attempt);
430
- await this.telemetry?.record({ ...attempt, alias, model: actualModel, ok: false });
506
+ await this.telemetry?.record({ ...attempt, ...metadata, alias, model: actualModel, ok: false, timing: startedAt === void 0 ? null : { modelMs: Math.max(0, performance.now() - startedAt) } });
431
507
  this.onAttempt({ ...attempt, alias });
432
508
  const retryable = status < 500 || this.config.retryServerErrors;
433
509
  if (!retryable) throw new RouteError(status, "upstream_failed", attempts, "\u4E0A\u6E38\u8FD4\u56DE 5xx \u4E14\u672A\u5F00\u542F\u300C5xx \u548C\u7F51\u7EDC\u9519\u8BEF\u4E5F\u5207\u6362\u8D26\u53F7\u300D\uFF0C\u672C\u6B21\u8BF7\u6C42\u5DF2\u505C\u6B62");
@@ -441,9 +517,10 @@ var Router = class {
441
517
 
442
518
  export {
443
519
  Telemetry,
520
+ SessionMetrics,
444
521
  RouteError,
445
522
  abortable,
446
523
  matchModel,
447
524
  Router
448
525
  };
449
- //# sourceMappingURL=chunk-XA3V2DGT.js.map
526
+ //# sourceMappingURL=chunk-J3XO7RTF.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/telemetry.mjs", "../src/router.mjs"],
4
+ "sourcesContent": ["import { createHash, randomUUID } from 'node:crypto';\nimport { assistantStreamFirstTokenTime } from '@deepseek-ai/dsh-llm';\nimport { readFile } from 'node:fs/promises';\nimport { writePrivateJson } from './config.mjs';\nconst empty = () => ({ requests: 0, failures: 0, input: 0, output: 0, tokens: 0, unmetered: 0 });\nconst day = at => new Date(at).toLocaleDateString('en-CA', { timeZone: 'Asia/Shanghai' });\nconst safe = n => typeof n === 'number' && Number.isFinite(n) && n >= 0 ? n : 0;\nconst measured = n => typeof n === 'number' && Number.isFinite(n) && n >= 0 ? n : null;\nexport class Telemetry {\n constructor(file, now = Date.now) { this.file = file; this.now = now; this.retentionDays = 30; this.data = { accounts: {}, routes: {}, days: {}, rounds: {}, expiringRounds: {}, events: [] }; this.queue = Promise.resolve(); }\n async load() {\n try { const saved = JSON.parse(await readFile(this.file, 'utf8')); if (saved.version !== 1) throw Error('Unsupported telemetry'); this.data = { ...saved, expiringRounds: saved.expiringRounds ?? {} }; }\n catch (e) { if (e.code !== 'ENOENT') throw e; }\n if (this.prune()) await this.persist();\n }\n configure(retentionDays) { this.retentionDays = retentionDays; }\n prune() {\n const cutoff = this.now() - this.retentionDays * 86400000, before = this.data.events.length;\n this.data.events = this.data.events.filter(e => Number.isFinite(e.at) && e.at >= cutoff);\n return before !== this.data.events.length;\n }\n row(group, key) { if (!Object.hasOwn(this.data[group], key)) Object.defineProperty(this.data[group], key, { value: empty(), enumerable: true, writable: true }); return this.data[group][key]; }\n count(alias, account) { return this.row('routes', JSON.stringify([alias, account])); }\n expiring(alias) {\n if (!Object.hasOwn(this.data.expiringRounds, alias)) Object.defineProperty(this.data.expiringRounds, alias, { value: { accounts: [], completed: [], cooldownUntil: 0, number: 1 }, enumerable: true, writable: true });\n return this.data.expiringRounds[alias];\n }\n restartExpiring(alias) { const row = this.expiring(alias); row.accounts = []; row.completed = []; row.cooldownUntil = 0; row.number++; return this.persist(); }\n round(alias, signature) {\n if (!Object.hasOwn(this.data.rounds, alias) || this.data.rounds[alias].signature !== signature) Object.defineProperty(this.data.rounds, alias, { value: { signature, number: 1, bases: {} }, enumerable: true, writable: true });\n return this.data.rounds[alias];\n }\n advance(alias, candidates, signature) {\n const round = this.round(alias, signature); round.number++;\n for (const c of candidates) Object.defineProperty(round.bases, c.account.id, { value: { tokens: this.count(alias, c.account.id).tokens, credits: this.row('accounts', c.account.id).creditsObserved ?? 0 }, enumerable: true, writable: true, configurable: true });\n return this.persist();\n }\n observe(account, snapshot) {\n const row = this.row('accounts', account);\n if (Number.isFinite(snapshot.remaining) && snapshot.unit === 'credits') {\n const sameCycle = row.balance?.cycle === snapshot.cycle;\n const change = sameCycle && Number.isFinite(row.balance?.remaining) ? Math.max(0, row.balance.remaining - snapshot.remaining) : 0;\n row.creditsObserved = (row.creditsObserved ?? 0) + change;\n }\n row.balance = snapshot;\n return this.persist();\n }\n record(event) {\n const at = this.now();\n const rows = [this.row('accounts', event.account), this.count(event.alias, event.account), this.row('days', day(at))];\n for (const row of rows) {\n row.requests++; if (!event.ok) row.failures++;\n if (event.usage) { const input = safe(event.usage.prompt_tokens), output = safe(event.usage.completion_tokens); row.input += input; row.output += output; row.tokens += safe(event.usage.total_tokens) || input + output; }\n else if (event.status === 200 || event.accepted) row.unmetered++;\n }\n const input = measured(event.usage?.prompt_tokens), output = measured(event.usage?.completion_tokens);\n this.data.events.unshift({ at, account: event.account, provider: event.provider, alias: event.alias, model: event.model ?? null, status: event.status,\n outcome: event.ok ? 'completed' : event.cancelled ? 'cancelled' : 'failed', input, output,\n tokens: measured(event.usage?.total_tokens) ?? (input !== null && output !== null ? input + output : null),\n cachedInput: measured(event.usage?.prompt_tokens_details?.cached_tokens), reasoningOutput: measured(event.usage?.completion_tokens_details?.reasoning_tokens),\n callId: event.callId ?? null, session: event.session ?? null,\n timing: event.timing ? Object.fromEntries(['modelMs', 'ttftMs', 'decodeMs', 'decodeTokens'].map(k => [k, measured(event.timing[k])])) : null, timingSource: event.timing ? 'upstream' : null });\n const dates = Object.keys(this.data.days).sort(); for (const key of dates.slice(0, -31)) delete this.data.days[key];\n return this.persist();\n }\n persist() { this.prune(); const saved = structuredClone({ ...this.data, version: 1 }); this.queue = this.queue.catch(() => {}).then(() => writePrivateJson(this.file, saved)); return this.queue; }\n state() { this.prune(); return { ...structuredClone(this.data), retentionDays: this.retentionDays, today: day(this.now()), updatedAt: this.now() }; }\n}\n\n// Pass bytes through unchanged; parse only usage and terminal/error markers, never persist content.\nexport function meterResponse(response, complete, signal, { now = () => performance.now(), startedAt = now() } = {}) {\n if (!response.body) return response;\n const reader = response.body.getReader(), decoder = new TextDecoder();\n let pending = '', usage, ended = false, failed = false, finished = false, firstToken = null, terminalAt = null;\n async function finish(cancelled = false) { if (finished) return; finished = true; const end = terminalAt ?? now(); await complete({ usage, ok: ended && !failed && !cancelled, cancelled, timing: { modelMs: Math.max(0, end - startedAt), ttftMs: firstToken === null ? null : Math.max(0, firstToken - startedAt), decodeMs: firstToken === null ? null : Math.max(0, end - firstToken), decodeTokens: firstToken === null ? null : measured(usage?.completion_tokens) } }); }\n function inspect(bytes) {\n pending += decoder.decode(bytes, { stream: true });\n let split;\n while ((split = /\\r?\\n\\r?\\n/.exec(pending))) {\n const frame = pending.slice(0, split.index); pending = pending.slice(split.index + split[0].length);\n const data = frame.split(/\\r?\\n/).filter(l => l.startsWith('data:')).map(l => l.slice(5).trimStart()).join('\\n');\n if (data === '[DONE]') { ended = true; terminalAt ??= now(); continue; }\n try { const value = JSON.parse(data); if (value.usage && ['prompt_tokens', 'completion_tokens', 'total_tokens'].some(k => Number.isFinite(value.usage[k]) && value.usage[k] >= 0)) usage = value.usage; if (value.error) failed = true; if (firstToken === null && value.choices?.some(c => { const d = c.delta; return [d?.content, d?.reasoning_content, d?.reasoning].some(v => typeof v === 'string' && v.trim()) || d?.tool_calls?.some(t => t.function?.name || t.function?.arguments); })) firstToken = now(); if (value.choices?.some(c => c.finish_reason)) { ended = true; terminalAt ??= now(); } } catch { /* Unknown frame is forwarded. */ }\n }\n if (pending.length > 1024 * 1024) { pending = ''; failed = true; }\n }\n const body = new ReadableStream({\n async pull(controller) {\n try { signal?.throwIfAborted(); const chunk = await reader.read(); if (chunk.done) { await finish(); controller.close(); } else { inspect(chunk.value); controller.enqueue(chunk.value); } }\n catch (e) { await finish(signal?.aborted); controller.error(e); await reader.cancel().catch(() => {}); }\n },\n async cancel(reason) { await reader.cancel(reason).catch(() => {}); await finish(!ended); },\n });\n return new Response(body, { status: response.status, headers: response.headers });\n}\n\n// Link local transport attempts to DSH steps without retaining titles, prompts,\n// tool names/arguments/results, or the original session identity.\nexport class SessionMetrics {\n constructor(telemetry) { this.telemetry = telemetry; this.steps = new Map(); }\n key(id) { return createHash('sha256').update(String(id)).digest('hex').slice(0, 24); }\n beginCall(sessionId, purpose) {\n const callId = randomUUID(), session = sessionId == null ? null : this.key(sessionId);\n const step = session && this.steps.get(session);\n if (step && !purpose) step.callId = callId;\n return { callId, session };\n }\n event(session, event) {\n const key = this.key(session.id), d = event.data;\n if (event.type === 'step/start') { this.steps.set(key, { turn: d.turn, step: d.step, start: event.time, first: null, calls: new Map(), toolMs: 0, toolCount: 0, toolsCompleted: 0 }); return; }\n const step = this.steps.get(key);\n if (!step) return;\n if (d.turn !== undefined && (d.turn !== step.turn || d.step !== undefined && d.step !== step.step)) return;\n if (event.type === 'assistant/attempt') { step.first ??= assistantStreamFirstTokenTime(d.stream) ?? null; return; }\n const row = this.telemetry.data.events.find(e => e.callId === step.callId && e.session === key);\n if (event.type === 'assistant/message') {\n if (!row || d.interrupted) return;\n const first = step.first ?? assistantStreamFirstTokenTime(d.stream) ?? null;\n const output = measured(d.usage?.outputTokens);\n row.timing = { modelMs: Math.max(0, event.time - step.start), ttftMs: first === null ? null : Math.max(0, first - step.start),\n decodeMs: first === null || output === null ? null : Math.max(0, event.time - first), decodeTokens: first === null ? null : output };\n row.timingSource = 'dsh-step';\n } else if (event.type === 'tool/call' && row?.timingSource === 'dsh-step') {\n if (!step.calls.has(d.callId)) { step.calls.set(d.callId, event.time); step.toolCount++; }\n } else if (event.type === 'tool/result' && step.calls.has(d.message?.source?.callId)) {\n const id = d.message.source.callId;\n step.toolMs += Math.max(0, event.time - step.calls.get(id)); step.toolsCompleted++; step.calls.delete(id);\n } else if (event.type === 'step/end' || event.type === 'turn/end') {\n this.steps.delete(key);\n } else return;\n if (row?.timingSource !== 'dsh-step') return;\n Object.assign(row.timing, { toolMs: step.toolMs, toolCount: step.toolCount, toolsCompleted: step.toolsCompleted });\n return this.telemetry.persist();\n }\n dispose(session) { this.steps.delete(this.key(session.id)); }\n}\n", "import { meterResponse } from './telemetry.mjs';\nimport { isFreeModel } from './config.mjs';\nimport { reasoningModes } from './reasoning.mjs';\nexport class RouteError extends Error {\n constructor(status, code, attempts = [], hint) {\n super(`${code}${attempts.length ? ': ' + attempts.map(a => `${a.account} HTTP ${a.status}`).join(', ') : ''}${hint ? `\uFF08${hint}\uFF09` : ''}`);\n this.status = status; this.code = code; this.attempts = attempts; this.hint = hint;\n }\n}\nconst normalize = value => value.toLowerCase().replace(/[^a-z0-9]/g, '').replace(/official$/, '');\nexport function abortable(promise, signal) {\n if (!signal) return promise;\n // Attach handlers even if already aborted, so a late rejection is consumed.\n return new Promise((resolve, reject) => {\n const abort = () => reject(signal.reason ?? new DOMException('Aborted', 'AbortError'));\n signal.addEventListener('abort', abort, { once: true });\n if (signal.aborted) abort();\n Promise.resolve(promise).then(resolve, reject).finally(() => signal.removeEventListener('abort', abort));\n });\n}\nexport function matchModel(alias, target, catalog, effort, provider = target.provider) {\n const allowed = m => m && (effort === undefined || reasoningModes(m, provider).includes(effort));\n if (target.model) return catalog.find(m => m.id === target.model && allowed(m));\n if (target.models) return target.models.map(id => catalog.find(m => m.id === id)).find(allowed);\n if (alias === 'ds4.1f') return catalog.find(m => allowed(m) && [m.id, m.name ?? ''].some(x => normalize(x) === 'deepseekv41flash'));\n}\n\nexport class Router {\n constructor(config, createClient, onAttempt = () => {}, now = Date.now) {\n this.config = config; this.createClient = createClient; this.onAttempt = onAttempt; this.now = now;\n this.telemetry = null; this.scores = new Map(); this.monitor = null; this.clients = new Map(); this.cooldowns = new Map(); this.active = new Map();\n }\n updateConfig(config) {\n for (const old of this.config.accounts) {\n const next = config.accounts.find(a => a.id === old.id);\n if (!next || next.provider !== old.provider || next.credentialFile !== old.credentialFile || next.identityFile !== old.identityFile) this.clients.delete(old.id);\n }\n this.config = config;\n for (const alias of this.active.keys()) if (!Object.hasOwn(config.routes, alias)) this.active.delete(alias);\n }\n async client(account) {\n if (!this.clients.has(account.id)) this.clients.set(account.id, Promise.resolve().then(() => this.createClient(account)));\n try { return await this.clients.get(account.id); }\n catch (error) { this.clients.delete(account.id); throw error; }\n }\n status() {\n return this.config.accounts.map(a => ({ id: a.id, provider: a.provider, enabled: a.enabled !== false,\n cooldowns: [...this.cooldowns].filter(([key, time]) => key.startsWith(`${a.id}:`) && time > this.now())\n .map(([key, time]) => ({ route: key.slice(a.id.length + 1), remainingMs: time - this.now() })),\n activeFor: [...this.active].filter(([, key]) => key.split(':')[0] === a.id).map(([alias]) => alias) }));\n }\n candidates(alias) {\n const route = this.config.routes[alias];\n if (!Object.hasOwn(this.config.routes, alias)) throw new RouteError(404, 'unknown_model', [], '\u63D2\u4EF6\u8DEF\u7531\u8868\u4E2D\u6CA1\u6709\u8BE5\u8C03\u7528\u540D\u79F0\uFF0C\u8BF7\u5728\u914D\u7F6E\u9875\u65B0\u5EFA\u6216\u6062\u590D\u5BF9\u5E94\u8DEF\u7531');\n const candidates = route.targets.flatMap((target, index) => this.config.accounts\n .filter(a => a.enabled !== false && a.provider === target.provider && (!target.account || a.id === target.account))\n .flatMap(account => route.freeOnly ? (this.freeModels?.(account) ?? []).filter(m => (!target.model || m.id === target.model) && (!target.models || target.models.includes(m.id)))\n .map(model => ({ account, target: { ...target, model: model.id, models: undefined }, key: `${account.id}:${index}:${model.id}` }))\n : [{ account, target, key: `${account.id}:${index}` }]));\n const active = candidates.findIndex(c => c.key === this.active.get(alias));\n return active < 0 ? candidates : [...candidates.slice(active), ...candidates.slice(0, active)];\n }\n expiringAt(account, route) {\n const balance = this.telemetry?.row('accounts', account.id).balance;\n if (!balance || balance.error || balance.unit !== 'credits' || this.now() - balance.fetchedAt > 120000) return Infinity;\n const horizon = this.now() + (route.expiringWithinDays ?? 7) * 86400000;\n return Math.min(Infinity, ...(balance.packages ?? []).filter(p => p.remaining > 0 && !p.unlimited && p.expiresAt > this.now() && p.expiresAt <= horizon).map(p => p.expiresAt));\n }\n async syncExpiring(alias, route, candidates, below = () => true) {\n if (!route.preferExpiringCredits || !this.telemetry) return false;\n const round = this.telemetry.expiring(alias);\n if (round.cooldownUntil > this.now()) return false;\n const before = JSON.stringify(round);\n if (round.cooldownUntil) { round.accounts = []; round.completed = []; round.cooldownUntil = 0; round.number++; }\n for (const id of round.accounts) {\n const matches = candidates.filter(c => c.account.id === id), balance = this.telemetry.row('accounts', id).balance;\n const fresh = balance && !balance.error && balance.unit === 'credits' && this.now() - balance.fetchedAt <= 120000;\n if (!matches.length || matches.every(c => !below(c)) || (fresh && !Number.isFinite(this.expiringAt({ id }, route)))) {\n if (!round.completed.includes(id)) round.completed.push(id);\n }\n }\n for (const c of candidates) if (below(c) && Number.isFinite(this.expiringAt(c.account, route)) && !round.accounts.includes(c.account.id)) round.accounts.push(c.account.id);\n // Cooling applies only to expiring-credit priority; ordinary routing keeps running.\n if (round.accounts.length && round.accounts.every(id => round.completed.includes(id))) round.cooldownUntil = this.now() + 3 * 86400000;\n if (JSON.stringify(round) !== before) await this.telemetry.persist();\n return round.cooldownUntil <= this.now();\n }\n remainingCooldown(candidate, alias, route) {\n const id = candidate.account.id;\n const keys = [`${id}:*`, `${id}:${alias}`];\n if (route.freeOnly) keys.push(`${id}:${alias}:${candidate.target.model}`);\n return Math.max(0, ...keys.map(key => (this.cooldowns.get(key) ?? 0) - this.now()));\n }\n exhaustHint({ alias, route, strategy, candidates, expiryCandidates, attempts }) {\n const kinds = new Set(attempts.map(a => a.kind));\n const modelOnly = attempts.length > 0 && [...kinds].every(k => ['model_unavailable', 'reasoning_effort_unavailable', 'model_no_longer_free'].includes(k));\n const cooling = candidates.map(c => this.remainingCooldown(c, alias, route)).filter(ms => ms > 0);\n const soonest = cooling.length ? Math.min(...cooling) : undefined;\n const countdown = soonest === undefined ? undefined : `\u7EA6 ${Math.max(1, Math.ceil(soonest / 1000))} \u79D2\u540E\u53EF\u91CD\u8BD5`;\n if (!expiryCandidates.length) return route.freeOnly\n ? '\u8BE5\u8DEF\u7531\u5F53\u524D\u6CA1\u6709\u53EF\u7528\u7684\u514D\u8D39\u6A21\u578B\uFF1A\u53EF\u80FD\u5DF2\u6062\u590D\u6536\u8D39\u3001\u9650\u514D\u5230\u671F\u6216\u76EE\u5F55\u83B7\u53D6\u5931\u8D25'\n : '\u8BE5\u8DEF\u7531\u6CA1\u6709\u53EF\u7528\u7684\u8D26\u53F7\u76EE\u6807\uFF1A\u8D26\u53F7\u53EF\u80FD\u5DF2\u5168\u90E8\u7981\u7528\uFF0C\u6216\u4E0E\u76EE\u6807\u6E20\u9053\u4E0D\u5339\u914D';\n if (modelOnly) return `\u5DF2\u5C1D\u8BD5\u7684\u8D26\u53F7\u76EE\u5F55\u4E2D\u90FD\u6CA1\u6709\u8BE5\u6A21\u578B\u3001\u6240\u9009\u63A8\u7406\u6863\u4F4D\u6216\u514D\u8D39\u8D44\u683C\u4E0D\u6EE1\u8DB3${countdown ? `\uFF1B\u5176\u4F59\u8D26\u53F7\u51B7\u5374\u4E2D\uFF0C${countdown}` : ''}`;\n if (soonest !== undefined && cooling.length >= candidates.length) {\n return attempts.length ? `\u6240\u6709\u5019\u9009\u8D26\u53F7\u672C\u6B21\u8C03\u7528\u5747\u5931\u8D25\u5E76\u5DF2\u8FDB\u5165\u51B7\u5374\uFF0C${countdown}` : `\u5168\u90E8\u8D26\u53F7\u90FD\u5728\u5931\u8D25\u51B7\u5374\u4E2D\uFF0C${countdown}`;\n }\n if (soonest !== undefined) return `\u90E8\u5206\u8D26\u53F7\u4ECD\u5728\u5931\u8D25\u51B7\u5374\u4E2D\uFF0C${countdown}`;\n if (!attempts.length && ['tokens', 'credits'].includes(strategy)) return `\u6240\u6709\u8D26\u53F7\u7684\u672C\u8F6E${strategy === 'tokens' ? ' Token' : '\u79EF\u5206'}\u989D\u5EA6\u5DF2\u7528\u5B8C\uFF0C\u6216\u56E0\u7F3A\u5C11\u7528\u91CF\u8BA1\u91CF\u800C\u6682\u505C\u53C2\u4E0E\u8F6E\u6362`;\n return undefined;\n }\n async chat(input, signal, metadata = {}) {\n const alias = input.model;\n if (!Array.isArray(input.messages) || !input.messages.length || input.stream !== true) throw new RouteError(400, 'messages_and_stream_true_required');\n const initialRoute = this.config.routes[alias];\n if (initialRoute?.freeOnly) {\n await abortable(this.prepareFree?.(), signal);\n if (!this.config.routes[alias]) throw new RouteError(503, 'free_model_pool_unavailable', [], '\u672C\u8DEF\u7531\u4ECA\u5929\u6CA1\u6709\u53EF\u7528\u7684\u514D\u8D39\u6A21\u578B');\n }\n const effort = Object.hasOwn(input, 'reasoning_effort') ? input.reasoning_effort : this.config.routes[alias]?.reasoningEffort;\n input = { ...input }; delete input.reasoning_effort;\n if (effort !== undefined && effort !== null) input.reasoning_effort = effort;\n let candidates = this.candidates(alias);\n const expiryCandidates = [...candidates];\n const route = this.config.routes[alias], strategy = route.strategy ?? 'failover';\n const available = c => (this.cooldowns.get(`${c.account.id}:*`) ?? 0) <= this.now() && (this.cooldowns.get(`${c.account.id}:${alias}`) ?? 0) <= this.now()\n && (!route.freeOnly || (this.cooldowns.get(`${c.account.id}:${alias}:${c.target.model}`) ?? 0) <= this.now());\n if (route.preferExpiringCredits && this.monitor) {\n await Promise.all([...new Map(candidates.filter(available).map(c => [c.account.id, c.account])).values()].map(a => {\n const snapshot = this.telemetry?.row('accounts', a.id).balance;\n return !snapshot || snapshot.error || this.now() - snapshot.fetchedAt > 60000 ? this.monitor(a) : undefined;\n }));\n signal?.throwIfAborted();\n }\n if (strategy === 'credits') {\n await Promise.all([...new Map(candidates.filter(available).map(c => [c.account.id, c.account])).values()].map(a => this.monitor?.(a)));\n signal?.throwIfAborted();\n candidates = candidates.filter(c => { const balance = this.telemetry?.row('accounts', c.account.id).balance; return balance?.unit === 'credits' && Number.isFinite(balance.remaining) && this.now() - balance.fetchedAt < 120000 && !balance.error; });\n if (!candidates.length) throw new RouteError(503, 'credit_usage_unavailable', [], '\u65E0\u6CD5\u83B7\u53D6\u4EFB\u4F55\u5019\u9009\u8D26\u53F7\u7684\u79EF\u5206\u4F59\u989D\u6570\u636E');\n }\n const signature = JSON.stringify({ strategy, targets: route.targets });\n let below = () => true, preferActive;\n if (this.telemetry && ['tokens', 'credits'].includes(strategy)) {\n const round = this.telemetry.round(alias, signature);\n const counters = c => ({ tokens: this.telemetry.count(alias, c.account.id).tokens, credits: this.telemetry.row('accounts', c.account.id).creditsObserved ?? 0 });\n for (const c of candidates) if (!Object.hasOwn(round.bases, c.account.id)) Object.defineProperty(round.bases, c.account.id, { value: counters(c), enumerable: true, writable: true, configurable: true });\n below = c => !round.bases[c.account.id] || counters(c)[strategy] - round.bases[c.account.id][strategy] < (strategy === 'tokens' ? c.target.tokenBudget : c.target.creditBudget);\n preferActive = await this.syncExpiring(alias, route, expiryCandidates, below);\n // Start another round only when every configured, metered candidate has used its budget.\n if (candidates.length && candidates.every(c => !below(c))) {\n await this.telemetry.advance(alias, candidates, signature);\n this.active.delete(alias);\n const allowed = new Set(candidates.map(c => c.key));\n candidates = this.candidates(alias).filter(c => allowed.has(c.key));\n }\n candidates = candidates.filter(below);\n if (strategy === 'tokens' && candidates.some(c => this.telemetry.count(alias, c.account.id).unmetered > 0)) {\n // A missing upstream usage marker cannot silently count as zero forever.\n candidates = candidates.filter(c => this.telemetry.count(alias, c.account.id).unmetered === 0);\n }\n }\n preferActive ??= await this.syncExpiring(alias, route, expiryCandidates, below);\n const expiry = c => preferActive && !this.telemetry.expiring(alias).completed.includes(c.account.id) ? this.expiringAt(c.account, route) : Infinity;\n if (preferActive) candidates.sort((a, b) => expiry(a) - expiry(b));\n if (strategy === 'weighted') {\n let eligible = candidates.filter(available);\n const nearest = Math.min(Infinity, ...eligible.map(expiry));\n if (Number.isFinite(nearest)) eligible = eligible.filter(c => expiry(c) === nearest);\n if (eligible.length) {\n let scores = this.scores.get(alias);\n if (scores?.signature !== signature) { scores = { signature, values: new Map() }; this.scores.set(alias, scores); }\n let total = 0, winner;\n for (const c of eligible) { const weight = c.target.weight ?? 1; total += weight; scores.values.set(c.key, (scores.values.get(c.key) ?? 0) + weight); if (!winner || scores.values.get(c.key) > scores.values.get(winner.key)) winner = c; }\n scores.values.set(winner.key, scores.values.get(winner.key) - total);\n candidates = [winner, ...candidates.filter(c => c !== winner)];\n }\n }\n const attempts = [];\n // Each account/model target is attempted once, even when configuration repeats it.\n const tried = new Set();\n for (const candidate of candidates) {\n signal?.throwIfAborted();\n const { account, target, key } = candidate;\n if (!available(candidate)) continue;\n let result, actualModel, startedAt;\n try {\n const client = await abortable(this.client(account), signal);\n const catalog = await abortable(client.models(signal), signal);\n const model = matchModel(alias, target, catalog, effort ?? undefined);\n if (!model) { attempts.push({ account: account.id, provider: account.provider, status: 404,\n kind: matchModel(alias, target, catalog) ? 'reasoning_effort_unavailable' : 'model_unavailable' }); continue; }\n if (route.freeOnly && !isFreeModel(model, this.now())) { attempts.push({ account: account.id, provider: account.provider, status: 404, kind: 'model_no_longer_free' }); continue; }\n actualModel = model.id;\n const dedupe = `${account.id}:${model.id}`;\n if (tried.has(dedupe)) continue;\n tried.add(dedupe);\n startedAt = performance.now();\n result = await abortable(client.chat({ ...input, model: model.id }, signal), signal);\n signal?.throwIfAborted();\n if (result.ok) {\n this.active.set(alias, key);\n this.onAttempt({ account: account.id, provider: account.provider, alias, model: model.id, status: 200 });\n const response = this.telemetry ? meterResponse(result.response, async summary => {\n await this.telemetry.record({ ...summary, ...metadata, account: account.id, provider: account.provider, alias, model: model.id, accepted: true, status: summary.ok ? 200 : summary.cancelled ? 499 : 502 });\n await this.syncExpiring(alias, route, expiryCandidates, below);\n if (strategy === 'credits' || route.preferExpiringCredits) void this.monitor?.(account).then(() => this.syncExpiring(alias, route, expiryCandidates, below)).catch(() => {});\n }, signal, { startedAt }) : result.response;\n return { response, account: account.id, provider: account.provider };\n }\n } catch (error) {\n signal?.throwIfAborted();\n const reported = error.status ?? error.failure?.status ?? /\\bhttp\\s+(\\d{3})\\b/i.exec(error.message ?? '')?.[1];\n result = { ok: false, status: Number(reported) || 502, kind: error.code ?? error.failure?.code ?? 'transport' };\n }\n const status = result.status >= 400 && result.status <= 599 ? result.status : 502;\n const attempt = { account: account.id, provider: account.provider, status, kind: result.kind };\n attempts.push(attempt);\n await this.telemetry?.record({ ...attempt, ...metadata, alias, model: actualModel, ok: false, timing: startedAt === undefined ? null : { modelMs: Math.max(0, performance.now() - startedAt) } });\n // Upstream messages can contain credentials or request text: log metadata only.\n this.onAttempt({ ...attempt, alias });\n const retryable = status < 500 || this.config.retryServerErrors;\n if (!retryable) throw new RouteError(status, 'upstream_failed', attempts, '\u4E0A\u6E38\u8FD4\u56DE 5xx \u4E14\u672A\u5F00\u542F\u300C5xx \u548C\u7F51\u7EDC\u9519\u8BEF\u4E5F\u5207\u6362\u8D26\u53F7\u300D\uFF0C\u672C\u6B21\u8BF7\u6C42\u5DF2\u505C\u6B62');\n const scope = [401, 402, 429].includes(status) ? '*' : route.freeOnly && actualModel ? `${alias}:${actualModel}` : alias;\n this.cooldowns.set(`${account.id}:${scope}`, this.now() + this.config.cooldownMs);\n }\n const hint = this.exhaustHint({ alias, route, strategy, candidates, expiryCandidates, attempts });\n throw new RouteError(503, route.freeOnly ? 'free_model_pool_unavailable' : 'account_pool_exhausted', attempts, hint);\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["input", "output"]
7
+ }
@@ -151,6 +151,8 @@ function validateConfig(raw, file = resolve("router.json")) {
151
151
  if (raw.retryServerErrors !== void 0 && typeof raw.retryServerErrors !== "boolean") throw new Error("Invalid retryServerErrors");
152
152
  if (raw.ignoredLocalAccounts !== void 0 && (!Array.isArray(raw.ignoredLocalAccounts) || raw.ignoredLocalAccounts.some((k) => typeof k !== "string" || k.length > 1024))) throw new Error("Invalid ignoredLocalAccounts");
153
153
  if (raw.usageRetentionDays !== void 0 && (!positive(raw.usageRetentionDays) || raw.usageRetentionDays > 365)) throw new Error("Token \u660E\u7EC6\u4FDD\u7559\u5929\u6570\u5FC5\u987B\u4E3A 1\u2013365 \u7684\u6574\u6570");
154
+ const checkinSchedule = raw.checkinSchedule ?? { mode: "scheduled", time: "10:05" };
155
+ if (!object(checkinSchedule) || !["startup", "scheduled"].includes(checkinSchedule.mode) || !/^([01]\d|2[0-3]):[0-5]\d$/.test(checkinSchedule.time ?? "") || Object.keys(checkinSchedule).some((k) => !["mode", "time"].includes(k))) throw new Error("\u7B7E\u5230\u8BA1\u5212\u5FC5\u987B\u9009\u62E9\u542F\u52A8\u6216\u5B9A\u65F6\uFF0C\u5E76\u586B\u5199\u6709\u6548\u7684\u5317\u4EAC\u65F6\u95F4\uFF08HH:mm\uFF09");
154
156
  return {
155
157
  ...raw,
156
158
  accounts,
@@ -158,10 +160,11 @@ function validateConfig(raw, file = resolve("router.json")) {
158
160
  models,
159
161
  modelVisibility,
160
162
  cooldownMs: raw.cooldownMs ?? 6e4,
163
+ checkinSchedule: { ...checkinSchedule },
161
164
  requestTimeoutMs: raw.requestTimeoutMs ?? 3e5,
162
165
  catalogTtlMs: raw.catalogTtlMs ?? 3e5,
163
166
  retryServerErrors: raw.retryServerErrors ?? false,
164
- usageRetentionDays: raw.usageRetentionDays ?? 3
167
+ usageRetentionDays: raw.usageRetentionDays ?? 30
165
168
  };
166
169
  }
167
170
  async function readConfig(file) {
@@ -207,4 +210,4 @@ export {
207
210
  ensureConfig,
208
211
  writePrivateJson
209
212
  };
210
- //# sourceMappingURL=chunk-U7J4ABAM.js.map
213
+ //# sourceMappingURL=chunk-MCHV2R25.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/reasoning.mjs", "../src/config.mjs"],
4
- "sourcesContent": ["export const REASONING_EFFORTS = ['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'];\n\n// Keep declared modes only. A fixed-thinking model without a declared set uses platform default.\nexport function reasoningModes(model, provider) {\n const r = model?.reasoning;\n if (!r || (r.supports !== true && !Array.isArray(r.supported))) return [];\n const declared = r.supportedEfforts ?? r.supported ?? [];\n const disable = r.canDisableThinking === true || declared.includes('off');\n const off = disable && !(provider === 'workbuddy' && r.onlyReasoning === true);\n return REASONING_EFFORTS.filter(e => e === 'off' ? off : declared.includes(e));\n}\n\nexport function routeReasoning(models) {\n const efforts = REASONING_EFFORTS.filter(e => models.some(({ model, provider }) => reasoningModes(model, provider).includes(e)));\n if (!efforts.length) return undefined;\n return { supports: true, supportedEfforts: efforts, canDisableThinking: efforts.includes('off'),\n defaultEffort: efforts.includes('high') ? 'high' : efforts[0] };\n}\n", "import { readFile, mkdir, rename, writeFile, chmod } from 'node:fs/promises';\nimport { dirname, resolve } from 'node:path';\nimport { randomUUID } from 'node:crypto';\nimport { withFileLock } from '@deepseek-ai/dsh-atomic-write';\nimport { REASONING_EFFORTS } from './reasoning.mjs';\n\nexport const PROVIDERS = ['workbuddy', 'workbuddy-ai', 'trae', 'trae-global', 'qoder', 'qoder-global'];\nexport const PROVIDER_NAMES = { workbuddy: 'WorkBuddy', 'workbuddy-ai': 'WorkBuddy AI', trae: 'Trae CN',\n 'trae-global': 'Trae Global', qoder: 'Qoder CN', 'qoder-global': 'Qoder Global' };\nexport const FLASH_PRESET = {\n name: 'DeepSeek V4.1 Flash \u00B7 \u81EA\u52A8\u8DEF\u7531', contextWindow: 200000, maxTokens: 32000, preferExpiringCredits: true, expiringWithinDays: 7,\n targets: ['workbuddy', 'trae', 'qoder'].map(provider => ({ provider, models: provider.startsWith('qoder')\n ? ['dfmodel'] : ['deepseek-v4.1-flash', 'DeepSeek-V4.1-Flash', 'DeepSeek-V4.1-Flash-Official'] })),\n};\n// IDs differ between providers; keep precise model/version bindings, never fuzzy-match variants.\nconst sharedPreset = (name, workbuddy, trae, qoder) => ({\n name: `${name} \u00B7 \u81EA\u52A8\u8DEF\u7531`, contextWindow: 200000, maxTokens: 32000, preferExpiringCredits: true, expiringWithinDays: 7,\n targets: [{ provider: 'workbuddy', models: [workbuddy] }, { provider: 'trae', models: Array.isArray(trae) ? trae : [trae] }, { provider: 'qoder', models: [qoder] }],\n});\nexport const ROUTE_PRESETS = {\n free: { name: 'Free \u00B7 \u52A8\u6001\u514D\u8D39\u6A21\u578B', freeOnly: true, visible: true, contextWindow: 200000, maxTokens: 32000,\n strategy: 'failover', preferExpiringCredits: false, targets: PROVIDERS.map(provider => ({ provider })) },\n 'deepseek-v4.1-flash': FLASH_PRESET,\n 'deepseek-v4-pro': sharedPreset('DeepSeek V4 Pro', 'deepseek-v4-pro', ['DeepSeek-V4-Pro-Official', 'DeepSeek-V4-Pro'], 'dmodel'),\n 'glm-5.3': sharedPreset('GLM-5.3', 'glm-5.3', 'glm-5.3', 'gmodel'),\n 'glm-5.3-flash': sharedPreset('GLM-5.3-Flash', 'glm-5.3-flash', 'glm-5.3-flash', 'gfmodel'),\n 'kimi-k3': sharedPreset('Kimi-K3', 'kimi-k3-1', 'kimi-k3', 'kmodel_latest'),\n 'kimi-k2.8-preview': sharedPreset('Kimi-K2.8-Preview', 'kimi-k2.8-preview', 'kimi-k2.8-preview', 'kmodel'),\n 'minimax-m2.7': sharedPreset('MiniMax-M2.7', 'minimax-m2.7', 'minimax-m2.7', 'mmodel'),\n};\nexport const DEFAULT_ROUTES = {\n free: ROUTE_PRESETS.free,\n 'ds4.1f': {\n name: 'DeepSeek V4.1 Flash \u00B7 Auto', contextWindow: 200000, maxTokens: 32000, preferExpiringCredits: true, expiringWithinDays: 7,\n targets: PROVIDERS.map(provider => ({ provider })),\n },\n ...ROUTE_PRESETS,\n};\nconst object = x => x !== null && typeof x === 'object' && !Array.isArray(x);\nconst nonempty = x => typeof x === 'string' && x.trim().length > 0;\nconst positive = x => Number.isSafeInteger(x) && x > 0;\nexport const beijingDay = at => new Date(at).toLocaleDateString('en-CA', { timeZone: 'Asia/Shanghai' });\nexport function isFreeModel(model, now = Date.now()) {\n if (model.billing?.rateUnknown === true) return false;\n // A badge or a zero adapter cost is not an account-scoped zero billing rate.\n const rate = model.creditMultiplier ?? (/^x?(\\d+(?:\\.\\d+)?)(?:\\s+credits?)?$/i.exec(model.billing?.credits?.trim() ?? '')?.[1]);\n if (rate === undefined || !Number.isFinite(Number(rate)) || Number(rate) !== 0) return false;\n if (model.promotions?.length && !model.promotions.some(p => now >= p.start && now < p.end)) return false;\n return true;\n}\nexport function validateConfig(raw, file = resolve('router.json')) {\n if (!object(raw) || !Array.isArray(raw.accounts)) throw new Error('Config must contain an accounts array');\n const ids = new Set();\n const accounts = raw.accounts.map(account => {\n if (!object(account) || !/^[a-zA-Z0-9_-]{1,64}$/.test(account.id ?? '') || ids.has(account.id)) throw new Error('Account ids must be unique, 1\u201364 letters, digits, _ or -');\n ids.add(account.id);\n if (!PROVIDERS.includes(account.provider) || !nonempty(account.credentialFile)) throw new Error(`Invalid provider or credentialFile for ${account.id}`);\n if (account.enabled !== undefined && typeof account.enabled !== 'boolean') throw new Error(`Invalid enabled flag for ${account.id}`);\n if (account.autoCheckin !== undefined && (typeof account.autoCheckin !== 'boolean' || (account.autoCheckin && !['workbuddy', 'trae', 'qoder', 'qoder-global'].includes(account.provider)))) throw new Error(`Invalid autoCheckin for ${account.id}`);\n if (account.name !== undefined && (!nonempty(account.name) || account.name.length > 100)) throw new Error(`Invalid account name for ${account.id}`);\n if (account.identityFile !== undefined && !nonempty(account.identityFile)) throw new Error(`Invalid identityFile for ${account.id}`);\n return { ...account, credentialFile: resolve(dirname(file), account.credentialFile),\n ...(account.identityFile ? { identityFile: resolve(dirname(file), account.identityFile) } : {}) };\n });\n if (!object(raw.routes ?? DEFAULT_ROUTES)) throw new Error('Routes must be an object');\n const routes = Object.fromEntries(Object.entries(raw.routes ?? DEFAULT_ROUTES).map(([id, route]) => [id, { ...route, preferExpiringCredits: route?.preferExpiringCredits ?? !route?.freeOnly, expiringWithinDays: route?.expiringWithinDays ?? 7 }]));\n for (const [alias, route] of Object.entries(routes)) {\n if (!/^[a-zA-Z0-9_.-]{1,128}$/.test(alias) || !object(route) || !Array.isArray(route.targets) || !route.targets.length) throw new Error(`Invalid route ${alias}`);\n for (const key of ['contextWindow', 'maxTokens']) if (!positive(route[key])) throw new Error(`Route ${alias} needs a positive ${key}`);\n if (route.maxTokens > route.contextWindow) throw new Error(`Route ${alias}: maxTokens exceeds contextWindow`);\n if (route.supportsImages !== undefined && typeof route.supportsImages !== 'boolean') throw new Error(`Invalid supportsImages for ${alias}`);\n if (route.visible !== undefined && typeof route.visible !== 'boolean') throw new Error(`Invalid visibility for ${alias}`);\n if (route.name !== undefined && (!nonempty(route.name) || route.name.length > 200)) throw new Error(`Invalid route name for ${alias}`);\n if (route.freeOnly !== undefined && typeof route.freeOnly !== 'boolean') throw new Error(`Invalid freeOnly for ${alias}`);\n if (route.freeModels !== undefined && (!route.freeOnly || !object(route.freeModels) || Object.entries(route.freeModels).some(([id, p]) =>\n !/^free_[a-f0-9]{24}$/.test(id) || !object(p) || Object.keys(p).some(k => !['visible', 'reasoningEffort'].includes(k))\n || (p.visible !== undefined && typeof p.visible !== 'boolean')\n || (p.reasoningEffort !== undefined && p.reasoningEffort !== null && !REASONING_EFFORTS.includes(p.reasoningEffort))))) throw new Error('\u514D\u8D39\u6A21\u578B\u5C55\u793A\u6216\u63A8\u7406\u7B49\u7EA7\u8BBE\u7F6E\u65E0\u6548');\n if (route.freeOnly && ((route.strategy && route.strategy !== 'failover') || route.preferExpiringCredits)) throw new Error('Free \u8DEF\u7531\u4EC5\u4F7F\u7528\u514D\u8D39\u6A21\u578B\u6545\u969C\u5207\u6362\uFF0C\u4E0D\u4F7F\u7528\u79EF\u5206\u6216\u989D\u5EA6\u8F6E\u6362');\n if (route.preferExpiringCredits !== undefined && typeof route.preferExpiringCredits !== 'boolean') throw new Error(`Invalid expiring credits flag in ${alias}`);\n if (route.expiringWithinDays !== undefined && (!positive(route.expiringWithinDays) || route.expiringWithinDays > 365)) throw new Error(`Invalid expiry horizon in ${alias}`);\n if (route.strategy !== undefined && !['failover', 'weighted', 'tokens', 'credits'].includes(route.strategy)) throw new Error(`Invalid strategy in ${alias}`);\n for (const target of route.targets) {\n if (!object(target)) throw new Error(`Invalid target in ${alias}`);\n if (target.weight !== undefined && (!positive(target.weight) || target.weight > 1000)) throw new Error(`Invalid target weight in ${alias}`);\n if (target.tokenBudget !== undefined && !positive(target.tokenBudget)) throw new Error(`Invalid token budget in ${alias}`);\n if (target.creditBudget !== undefined && (typeof target.creditBudget !== 'number' || !Number.isFinite(target.creditBudget) || target.creditBudget <= 0)) throw new Error(`Invalid credit budget in ${alias}`);\n if (route.strategy === 'tokens' && !positive(target.tokenBudget)) throw new Error(`Route ${alias} needs token budgets`);\n if (route.strategy === 'credits' && !(target.creditBudget > 0)) throw new Error(`Route ${alias} needs credit budgets`);\n if (!object(target) || !PROVIDERS.includes(target.provider) || (target.model !== undefined && !nonempty(target.model))) throw new Error(`Invalid target in ${alias}`);\n if (target.models !== undefined && (!Array.isArray(target.models) || !target.models.length || target.models.length > 20 || !target.models.every(nonempty))) throw new Error(`Invalid target models in ${alias}`);\n if (target.model !== undefined && target.models !== undefined) throw new Error(`Choose model or models in ${alias}`);\n if (target.account !== undefined && !accounts.some(a => a.id === target.account && a.provider === target.provider)) throw new Error(`Unknown target account in ${alias}`);\n if (!target.model && !target.models && alias !== 'ds4.1f' && !route.freeOnly) throw new Error(`Route ${alias} requires explicit target model ids`);\n }\n }\n const models = raw.models ?? {};\n if (!object(models)) throw new Error('Models must be an object');\n for (const [provider, preferences] of Object.entries(models)) {\n if (!PROVIDERS.includes(provider) || !object(preferences)) throw new Error('Invalid model provider');\n for (const [id, preference] of Object.entries(preferences)) {\n if (!nonempty(id) || id.length > 256 || !object(preference)\n || (preference.name !== undefined && (!nonempty(preference.name) || preference.name.length > 200))\n || (preference.visible !== undefined && typeof preference.visible !== 'boolean')) throw new Error('Invalid model preference');\n }\n }\n const modelVisibility = raw.modelVisibility ?? {};\n if (!object(modelVisibility) || Object.entries(modelVisibility).some(([provider, visible]) => !PROVIDERS.includes(provider) || typeof visible !== 'boolean')) throw new Error('Invalid modelVisibility');\n for (const key of ['cooldownMs', 'requestTimeoutMs', 'catalogTtlMs']) if (raw[key] !== undefined && !positive(raw[key])) throw new Error(`Invalid ${key}`);\n if (raw.retryServerErrors !== undefined && typeof raw.retryServerErrors !== 'boolean') throw new Error('Invalid retryServerErrors');\n if (raw.ignoredLocalAccounts !== undefined && (!Array.isArray(raw.ignoredLocalAccounts) || raw.ignoredLocalAccounts.some(k => typeof k !== 'string' || k.length > 1024))) throw new Error('Invalid ignoredLocalAccounts');\n if (raw.usageRetentionDays !== undefined && (!positive(raw.usageRetentionDays) || raw.usageRetentionDays > 365)) throw new Error('Token \u660E\u7EC6\u4FDD\u7559\u5929\u6570\u5FC5\u987B\u4E3A 1\u2013365 \u7684\u6574\u6570');\n return { ...raw, accounts, routes, models, modelVisibility, cooldownMs: raw.cooldownMs ?? 60000,\n requestTimeoutMs: raw.requestTimeoutMs ?? 300000, catalogTtlMs: raw.catalogTtlMs ?? 300000,\n retryServerErrors: raw.retryServerErrors ?? false, usageRetentionDays: raw.usageRetentionDays ?? 3 };\n}\nexport async function readConfig(file) {\n return validateConfig(JSON.parse(await readFile(file, 'utf8')), resolve(file));\n}\nexport async function ensureConfig(file) {\n try { return await readConfig(file); } catch (error) { if (error.code !== 'ENOENT') throw error; }\n await mkdir(dirname(file), { recursive: true, mode: 0o700 });\n return withFileLock(file, async () => {\n try { return await readConfig(file); } catch (error) { if (error.code !== 'ENOENT') throw error; }\n await writePrivateJson(file, { accounts: [], routes: ROUTE_PRESETS });\n return readConfig(file);\n }, { waitMs: 30000 });\n}\nexport async function writePrivateJson(file, value) {\n await mkdir(dirname(file), { recursive: true, mode: 0o700 });\n const temp = `${file}.${randomUUID()}.tmp`;\n await writeFile(temp, `${JSON.stringify(value, null, 2)}\\n`, { mode: 0o600, flag: 'wx' });\n await rename(temp, file);\n await chmod(file, 0o600);\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["export const REASONING_EFFORTS = ['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'];\n\n// Keep declared modes only. A fixed-thinking model without a declared set uses platform default.\nexport function reasoningModes(model, provider) {\n const r = model?.reasoning;\n if (!r || (r.supports !== true && !Array.isArray(r.supported))) return [];\n const declared = r.supportedEfforts ?? r.supported ?? [];\n const disable = r.canDisableThinking === true || declared.includes('off');\n const off = disable && !(provider === 'workbuddy' && r.onlyReasoning === true);\n return REASONING_EFFORTS.filter(e => e === 'off' ? off : declared.includes(e));\n}\n\nexport function routeReasoning(models) {\n const efforts = REASONING_EFFORTS.filter(e => models.some(({ model, provider }) => reasoningModes(model, provider).includes(e)));\n if (!efforts.length) return undefined;\n return { supports: true, supportedEfforts: efforts, canDisableThinking: efforts.includes('off'),\n defaultEffort: efforts.includes('high') ? 'high' : efforts[0] };\n}\n", "import { readFile, mkdir, rename, writeFile, chmod } from 'node:fs/promises';\nimport { dirname, resolve } from 'node:path';\nimport { randomUUID } from 'node:crypto';\nimport { withFileLock } from '@deepseek-ai/dsh-atomic-write';\nimport { REASONING_EFFORTS } from './reasoning.mjs';\n\nexport const PROVIDERS = ['workbuddy', 'workbuddy-ai', 'trae', 'trae-global', 'qoder', 'qoder-global'];\nexport const PROVIDER_NAMES = { workbuddy: 'WorkBuddy', 'workbuddy-ai': 'WorkBuddy AI', trae: 'Trae CN',\n 'trae-global': 'Trae Global', qoder: 'Qoder CN', 'qoder-global': 'Qoder Global' };\nexport const FLASH_PRESET = {\n name: 'DeepSeek V4.1 Flash \u00B7 \u81EA\u52A8\u8DEF\u7531', contextWindow: 200000, maxTokens: 32000, preferExpiringCredits: true, expiringWithinDays: 7,\n targets: ['workbuddy', 'trae', 'qoder'].map(provider => ({ provider, models: provider.startsWith('qoder')\n ? ['dfmodel'] : ['deepseek-v4.1-flash', 'DeepSeek-V4.1-Flash', 'DeepSeek-V4.1-Flash-Official'] })),\n};\n// IDs differ between providers; keep precise model/version bindings, never fuzzy-match variants.\nconst sharedPreset = (name, workbuddy, trae, qoder) => ({\n name: `${name} \u00B7 \u81EA\u52A8\u8DEF\u7531`, contextWindow: 200000, maxTokens: 32000, preferExpiringCredits: true, expiringWithinDays: 7,\n targets: [{ provider: 'workbuddy', models: [workbuddy] }, { provider: 'trae', models: Array.isArray(trae) ? trae : [trae] }, { provider: 'qoder', models: [qoder] }],\n});\nexport const ROUTE_PRESETS = {\n free: { name: 'Free \u00B7 \u52A8\u6001\u514D\u8D39\u6A21\u578B', freeOnly: true, visible: true, contextWindow: 200000, maxTokens: 32000,\n strategy: 'failover', preferExpiringCredits: false, targets: PROVIDERS.map(provider => ({ provider })) },\n 'deepseek-v4.1-flash': FLASH_PRESET,\n 'deepseek-v4-pro': sharedPreset('DeepSeek V4 Pro', 'deepseek-v4-pro', ['DeepSeek-V4-Pro-Official', 'DeepSeek-V4-Pro'], 'dmodel'),\n 'glm-5.3': sharedPreset('GLM-5.3', 'glm-5.3', 'glm-5.3', 'gmodel'),\n 'glm-5.3-flash': sharedPreset('GLM-5.3-Flash', 'glm-5.3-flash', 'glm-5.3-flash', 'gfmodel'),\n 'kimi-k3': sharedPreset('Kimi-K3', 'kimi-k3-1', 'kimi-k3', 'kmodel_latest'),\n 'kimi-k2.8-preview': sharedPreset('Kimi-K2.8-Preview', 'kimi-k2.8-preview', 'kimi-k2.8-preview', 'kmodel'),\n 'minimax-m2.7': sharedPreset('MiniMax-M2.7', 'minimax-m2.7', 'minimax-m2.7', 'mmodel'),\n};\nexport const DEFAULT_ROUTES = {\n free: ROUTE_PRESETS.free,\n 'ds4.1f': {\n name: 'DeepSeek V4.1 Flash \u00B7 Auto', contextWindow: 200000, maxTokens: 32000, preferExpiringCredits: true, expiringWithinDays: 7,\n targets: PROVIDERS.map(provider => ({ provider })),\n },\n ...ROUTE_PRESETS,\n};\nconst object = x => x !== null && typeof x === 'object' && !Array.isArray(x);\nconst nonempty = x => typeof x === 'string' && x.trim().length > 0;\nconst positive = x => Number.isSafeInteger(x) && x > 0;\nexport const beijingDay = at => new Date(at).toLocaleDateString('en-CA', { timeZone: 'Asia/Shanghai' });\nexport function isFreeModel(model, now = Date.now()) {\n if (model.billing?.rateUnknown === true) return false;\n // A badge or a zero adapter cost is not an account-scoped zero billing rate.\n const rate = model.creditMultiplier ?? (/^x?(\\d+(?:\\.\\d+)?)(?:\\s+credits?)?$/i.exec(model.billing?.credits?.trim() ?? '')?.[1]);\n if (rate === undefined || !Number.isFinite(Number(rate)) || Number(rate) !== 0) return false;\n if (model.promotions?.length && !model.promotions.some(p => now >= p.start && now < p.end)) return false;\n return true;\n}\nexport function validateConfig(raw, file = resolve('router.json')) {\n if (!object(raw) || !Array.isArray(raw.accounts)) throw new Error('Config must contain an accounts array');\n const ids = new Set();\n const accounts = raw.accounts.map(account => {\n if (!object(account) || !/^[a-zA-Z0-9_-]{1,64}$/.test(account.id ?? '') || ids.has(account.id)) throw new Error('Account ids must be unique, 1\u201364 letters, digits, _ or -');\n ids.add(account.id);\n if (!PROVIDERS.includes(account.provider) || !nonempty(account.credentialFile)) throw new Error(`Invalid provider or credentialFile for ${account.id}`);\n if (account.enabled !== undefined && typeof account.enabled !== 'boolean') throw new Error(`Invalid enabled flag for ${account.id}`);\n if (account.autoCheckin !== undefined && (typeof account.autoCheckin !== 'boolean' || (account.autoCheckin && !['workbuddy', 'trae', 'qoder', 'qoder-global'].includes(account.provider)))) throw new Error(`Invalid autoCheckin for ${account.id}`);\n if (account.name !== undefined && (!nonempty(account.name) || account.name.length > 100)) throw new Error(`Invalid account name for ${account.id}`);\n if (account.identityFile !== undefined && !nonempty(account.identityFile)) throw new Error(`Invalid identityFile for ${account.id}`);\n return { ...account, credentialFile: resolve(dirname(file), account.credentialFile),\n ...(account.identityFile ? { identityFile: resolve(dirname(file), account.identityFile) } : {}) };\n });\n if (!object(raw.routes ?? DEFAULT_ROUTES)) throw new Error('Routes must be an object');\n const routes = Object.fromEntries(Object.entries(raw.routes ?? DEFAULT_ROUTES).map(([id, route]) => [id, { ...route, preferExpiringCredits: route?.preferExpiringCredits ?? !route?.freeOnly, expiringWithinDays: route?.expiringWithinDays ?? 7 }]));\n for (const [alias, route] of Object.entries(routes)) {\n if (!/^[a-zA-Z0-9_.-]{1,128}$/.test(alias) || !object(route) || !Array.isArray(route.targets) || !route.targets.length) throw new Error(`Invalid route ${alias}`);\n for (const key of ['contextWindow', 'maxTokens']) if (!positive(route[key])) throw new Error(`Route ${alias} needs a positive ${key}`);\n if (route.maxTokens > route.contextWindow) throw new Error(`Route ${alias}: maxTokens exceeds contextWindow`);\n if (route.supportsImages !== undefined && typeof route.supportsImages !== 'boolean') throw new Error(`Invalid supportsImages for ${alias}`);\n if (route.visible !== undefined && typeof route.visible !== 'boolean') throw new Error(`Invalid visibility for ${alias}`);\n if (route.name !== undefined && (!nonempty(route.name) || route.name.length > 200)) throw new Error(`Invalid route name for ${alias}`);\n if (route.freeOnly !== undefined && typeof route.freeOnly !== 'boolean') throw new Error(`Invalid freeOnly for ${alias}`);\n if (route.freeModels !== undefined && (!route.freeOnly || !object(route.freeModels) || Object.entries(route.freeModels).some(([id, p]) =>\n !/^free_[a-f0-9]{24}$/.test(id) || !object(p) || Object.keys(p).some(k => !['visible', 'reasoningEffort'].includes(k))\n || (p.visible !== undefined && typeof p.visible !== 'boolean')\n || (p.reasoningEffort !== undefined && p.reasoningEffort !== null && !REASONING_EFFORTS.includes(p.reasoningEffort))))) throw new Error('\u514D\u8D39\u6A21\u578B\u5C55\u793A\u6216\u63A8\u7406\u7B49\u7EA7\u8BBE\u7F6E\u65E0\u6548');\n if (route.freeOnly && ((route.strategy && route.strategy !== 'failover') || route.preferExpiringCredits)) throw new Error('Free \u8DEF\u7531\u4EC5\u4F7F\u7528\u514D\u8D39\u6A21\u578B\u6545\u969C\u5207\u6362\uFF0C\u4E0D\u4F7F\u7528\u79EF\u5206\u6216\u989D\u5EA6\u8F6E\u6362');\n if (route.preferExpiringCredits !== undefined && typeof route.preferExpiringCredits !== 'boolean') throw new Error(`Invalid expiring credits flag in ${alias}`);\n if (route.expiringWithinDays !== undefined && (!positive(route.expiringWithinDays) || route.expiringWithinDays > 365)) throw new Error(`Invalid expiry horizon in ${alias}`);\n if (route.strategy !== undefined && !['failover', 'weighted', 'tokens', 'credits'].includes(route.strategy)) throw new Error(`Invalid strategy in ${alias}`);\n for (const target of route.targets) {\n if (!object(target)) throw new Error(`Invalid target in ${alias}`);\n if (target.weight !== undefined && (!positive(target.weight) || target.weight > 1000)) throw new Error(`Invalid target weight in ${alias}`);\n if (target.tokenBudget !== undefined && !positive(target.tokenBudget)) throw new Error(`Invalid token budget in ${alias}`);\n if (target.creditBudget !== undefined && (typeof target.creditBudget !== 'number' || !Number.isFinite(target.creditBudget) || target.creditBudget <= 0)) throw new Error(`Invalid credit budget in ${alias}`);\n if (route.strategy === 'tokens' && !positive(target.tokenBudget)) throw new Error(`Route ${alias} needs token budgets`);\n if (route.strategy === 'credits' && !(target.creditBudget > 0)) throw new Error(`Route ${alias} needs credit budgets`);\n if (!object(target) || !PROVIDERS.includes(target.provider) || (target.model !== undefined && !nonempty(target.model))) throw new Error(`Invalid target in ${alias}`);\n if (target.models !== undefined && (!Array.isArray(target.models) || !target.models.length || target.models.length > 20 || !target.models.every(nonempty))) throw new Error(`Invalid target models in ${alias}`);\n if (target.model !== undefined && target.models !== undefined) throw new Error(`Choose model or models in ${alias}`);\n if (target.account !== undefined && !accounts.some(a => a.id === target.account && a.provider === target.provider)) throw new Error(`Unknown target account in ${alias}`);\n if (!target.model && !target.models && alias !== 'ds4.1f' && !route.freeOnly) throw new Error(`Route ${alias} requires explicit target model ids`);\n }\n }\n const models = raw.models ?? {};\n if (!object(models)) throw new Error('Models must be an object');\n for (const [provider, preferences] of Object.entries(models)) {\n if (!PROVIDERS.includes(provider) || !object(preferences)) throw new Error('Invalid model provider');\n for (const [id, preference] of Object.entries(preferences)) {\n if (!nonempty(id) || id.length > 256 || !object(preference)\n || (preference.name !== undefined && (!nonempty(preference.name) || preference.name.length > 200))\n || (preference.visible !== undefined && typeof preference.visible !== 'boolean')) throw new Error('Invalid model preference');\n }\n }\n const modelVisibility = raw.modelVisibility ?? {};\n if (!object(modelVisibility) || Object.entries(modelVisibility).some(([provider, visible]) => !PROVIDERS.includes(provider) || typeof visible !== 'boolean')) throw new Error('Invalid modelVisibility');\n for (const key of ['cooldownMs', 'requestTimeoutMs', 'catalogTtlMs']) if (raw[key] !== undefined && !positive(raw[key])) throw new Error(`Invalid ${key}`);\n if (raw.retryServerErrors !== undefined && typeof raw.retryServerErrors !== 'boolean') throw new Error('Invalid retryServerErrors');\n if (raw.ignoredLocalAccounts !== undefined && (!Array.isArray(raw.ignoredLocalAccounts) || raw.ignoredLocalAccounts.some(k => typeof k !== 'string' || k.length > 1024))) throw new Error('Invalid ignoredLocalAccounts');\n if (raw.usageRetentionDays !== undefined && (!positive(raw.usageRetentionDays) || raw.usageRetentionDays > 365)) throw new Error('Token \u660E\u7EC6\u4FDD\u7559\u5929\u6570\u5FC5\u987B\u4E3A 1\u2013365 \u7684\u6574\u6570');\n const checkinSchedule = raw.checkinSchedule ?? { mode: 'scheduled', time: '10:05' };\n if (!object(checkinSchedule) || !['startup', 'scheduled'].includes(checkinSchedule.mode)\n || !/^([01]\\d|2[0-3]):[0-5]\\d$/.test(checkinSchedule.time ?? '')\n || Object.keys(checkinSchedule).some(k => !['mode', 'time'].includes(k))) throw new Error('\u7B7E\u5230\u8BA1\u5212\u5FC5\u987B\u9009\u62E9\u542F\u52A8\u6216\u5B9A\u65F6\uFF0C\u5E76\u586B\u5199\u6709\u6548\u7684\u5317\u4EAC\u65F6\u95F4\uFF08HH:mm\uFF09');\n return { ...raw, accounts, routes, models, modelVisibility, cooldownMs: raw.cooldownMs ?? 60000,\n checkinSchedule: { ...checkinSchedule },\n requestTimeoutMs: raw.requestTimeoutMs ?? 300000, catalogTtlMs: raw.catalogTtlMs ?? 300000,\n retryServerErrors: raw.retryServerErrors ?? false, usageRetentionDays: raw.usageRetentionDays ?? 30 };\n}\nexport async function readConfig(file) {\n return validateConfig(JSON.parse(await readFile(file, 'utf8')), resolve(file));\n}\nexport async function ensureConfig(file) {\n try { return await readConfig(file); } catch (error) { if (error.code !== 'ENOENT') throw error; }\n await mkdir(dirname(file), { recursive: true, mode: 0o700 });\n return withFileLock(file, async () => {\n try { return await readConfig(file); } catch (error) { if (error.code !== 'ENOENT') throw error; }\n await writePrivateJson(file, { accounts: [], routes: ROUTE_PRESETS });\n return readConfig(file);\n }, { waitMs: 30000 });\n}\nexport async function writePrivateJson(file, value) {\n await mkdir(dirname(file), { recursive: true, mode: 0o700 });\n const temp = `${file}.${randomUUID()}.tmp`;\n await writeFile(temp, `${JSON.stringify(value, null, 2)}\\n`, { mode: 0o600, flag: 'wx' });\n await rename(temp, file);\n await chmod(file, 0o600);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -12,7 +12,7 @@ import {
12
12
  import {
13
13
  PROVIDERS,
14
14
  writePrivateJson
15
- } from "./chunk-U7J4ABAM.js";
15
+ } from "./chunk-MCHV2R25.js";
16
16
 
17
17
  // src/accounts.mjs
18
18
  import { readFile } from "node:fs/promises";
@@ -161,4 +161,4 @@ export {
161
161
  readPortableCredential,
162
162
  importAccount
163
163
  };
164
- //# sourceMappingURL=chunk-4H6ZXK75.js.map
164
+ //# sourceMappingURL=chunk-OFFVP6YN.js.map