dsh-multi-router 0.6.0 → 0.6.2
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/CHANGELOG.md +16 -0
- package/README.md +23 -6
- package/THIRD_PARTY_NOTICES.md +4 -0
- package/cordis.patch.yml +2 -2
- package/lib/accounts.js +2 -2
- package/lib/api-service.js +3 -3
- package/lib/{chunk-LLDJVBTQ.js → chunk-3O3L3526.js} +3 -3
- package/lib/{chunk-OCMOMSB4.js → chunk-4EO5V6FW.js} +128 -42
- package/lib/chunk-4EO5V6FW.js.map +7 -0
- package/lib/{chunk-ROZINFTV.js → chunk-5KYJADJ4.js} +49 -6
- package/lib/chunk-5KYJADJ4.js.map +7 -0
- package/lib/{chunk-WVNY4LSL.js → chunk-5R3IOPSF.js} +60 -13
- package/lib/chunk-5R3IOPSF.js.map +7 -0
- package/lib/{chunk-NSKCFVHP.js → chunk-74WQLVJO.js} +15 -7
- package/lib/chunk-74WQLVJO.js.map +7 -0
- package/lib/{chunk-JUOESKAK.js → chunk-KGVTRS5K.js} +2 -2
- package/lib/{chunk-SNEZMYNU.js → chunk-Q34JSMGN.js} +3 -3
- package/lib/cli.js +4 -4
- package/lib/client.js +125 -40
- package/lib/client.js.map +2 -2
- package/lib/clients.js +6 -3
- package/lib/{host-v0.6.0.js → host-v0.6.2.js} +8 -7
- package/lib/host.js +8 -7
- package/lib/index.js +8 -7
- package/lib/index.js.map +2 -2
- package/lib/manager.js +6 -6
- package/lib/router.js +2 -2
- package/lib/shim.js +3 -3
- package/package.json +1 -1
- package/lib/chunk-NSKCFVHP.js.map +0 -7
- package/lib/chunk-OCMOMSB4.js.map +0 -7
- package/lib/chunk-ROZINFTV.js.map +0 -7
- package/lib/chunk-WVNY4LSL.js.map +0 -7
- /package/lib/{chunk-LLDJVBTQ.js.map → chunk-3O3L3526.js.map} +0 -0
- /package/lib/{chunk-JUOESKAK.js.map → chunk-KGVTRS5K.js.map} +0 -0
- /package/lib/{chunk-SNEZMYNU.js.map → chunk-Q34JSMGN.js.map} +0 -0
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
isFreeModel,
|
|
3
3
|
reasoningModes,
|
|
4
4
|
writePrivateJson
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-5R3IOPSF.js";
|
|
6
6
|
|
|
7
7
|
// src/telemetry.mjs
|
|
8
8
|
import { createHash, randomUUID } from "node:crypto";
|
|
@@ -256,6 +256,44 @@ var SessionMetrics = class {
|
|
|
256
256
|
}
|
|
257
257
|
};
|
|
258
258
|
|
|
259
|
+
// src/model-context.mjs
|
|
260
|
+
var positive = (n) => Number.isSafeInteger(n) && n > 0;
|
|
261
|
+
function contextInfo(model) {
|
|
262
|
+
const defaultContextWindow = positive(model.defaultContextWindow) ? model.defaultContextWindow : positive(model.contextWindow) ? model.contextWindow : 2e5;
|
|
263
|
+
const supportedContextWindows = [...new Set([
|
|
264
|
+
defaultContextWindow,
|
|
265
|
+
model.contextWindow,
|
|
266
|
+
model.maxContextWindow,
|
|
267
|
+
...Array.isArray(model.supportedContextWindows) ? model.supportedContextWindows : []
|
|
268
|
+
].filter(positive))].sort((a, b) => a - b);
|
|
269
|
+
const maxContextWindow = supportedContextWindows.at(-1);
|
|
270
|
+
return { defaultContextWindow, supportedContextWindows, maxContextWindow, contextWindow: maxContextWindow };
|
|
271
|
+
}
|
|
272
|
+
function resolveContext(models, selected, fallback = 2e5) {
|
|
273
|
+
const infos = models.map(contextInfo);
|
|
274
|
+
const maxContextWindow = infos.length ? Math.max(...infos.map((m) => m.maxContextWindow)) : fallback;
|
|
275
|
+
const contextWindow = positive(selected) ? Math.min(selected, maxContextWindow) : maxContextWindow;
|
|
276
|
+
return {
|
|
277
|
+
maxContextWindow,
|
|
278
|
+
contextWindow,
|
|
279
|
+
contextKnown: infos.length > 0,
|
|
280
|
+
configuredContextWindow: positive(selected) ? selected : null,
|
|
281
|
+
supportedContextWindows: [.../* @__PURE__ */ new Set([contextWindow, ...infos.flatMap((m) => m.supportedContextWindows)])].sort((a, b) => a - b)
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
function qoderContextModel(model, budget) {
|
|
285
|
+
if (!model?.contextOptions) return model;
|
|
286
|
+
const entries = Object.entries(model.contextOptions).filter(([, v]) => positive(v.tokenCount)).sort((a, b) => a[1].tokenCount - b[1].tokenCount);
|
|
287
|
+
if (!entries.length) return model;
|
|
288
|
+
const selected = budget == null ? entries.at(-1) : entries.find(([, v]) => v.tokenCount >= budget);
|
|
289
|
+
if (!selected) throw Object.assign(Error("context_window_unavailable"), { status: 400, code: "context_window_unavailable" });
|
|
290
|
+
return {
|
|
291
|
+
...model,
|
|
292
|
+
contextWindow: selected[1].tokenCount,
|
|
293
|
+
contextOptions: Object.fromEntries(Object.entries(model.contextOptions).map(([key, value]) => [key, { ...value, isDefault: key === selected[0] }]))
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
|
|
259
297
|
// src/router.mjs
|
|
260
298
|
var RouteError = class extends Error {
|
|
261
299
|
constructor(status, code, attempts = [], hint) {
|
|
@@ -366,11 +404,12 @@ var Router = class {
|
|
|
366
404
|
}
|
|
367
405
|
exhaustHint({ alias, route, strategy, candidates, expiryCandidates, attempts }) {
|
|
368
406
|
const kinds = new Set(attempts.map((a) => a.kind));
|
|
369
|
-
const modelOnly = attempts.length > 0 && [...kinds].every((k) => ["model_unavailable", "reasoning_effort_unavailable", "model_no_longer_free"].includes(k));
|
|
407
|
+
const modelOnly = attempts.length > 0 && [...kinds].every((k) => ["model_unavailable", "reasoning_effort_unavailable", "model_no_longer_free", "context_window_unavailable"].includes(k));
|
|
370
408
|
const cooling = candidates.map((c) => this.remainingCooldown(c, alias, route)).filter((ms) => ms > 0);
|
|
371
409
|
const soonest = cooling.length ? Math.min(...cooling) : void 0;
|
|
372
410
|
const countdown = soonest === void 0 ? void 0 : `\u7EA6 ${Math.max(1, Math.ceil(soonest / 1e3))} \u79D2\u540E\u53EF\u91CD\u8BD5`;
|
|
373
411
|
if (!expiryCandidates.length) return route.freeOnly ? "\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" : "\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";
|
|
412
|
+
if (kinds.has("context_window_unavailable") && modelOnly) return "\u5019\u9009\u6E20\u9053\u4E0D\u652F\u6301\u5F53\u524D\u4E0A\u4E0B\u6587\u9884\u7B97\uFF0C\u8BF7\u5237\u65B0\u76EE\u5F55\u6216\u5728\u6A21\u578B\uFF0F\u8DEF\u7531\u8BBE\u7F6E\u4E2D\u8C03\u4F4E\u9884\u7B97\uFF1B\u4E0D\u4F1A\u622A\u65AD\u4F1A\u8BDD\u6216\u964D\u7EA7\u5230\u5C0F\u5BB9\u91CF\u6E20\u9053";
|
|
374
413
|
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}` : ""}`;
|
|
375
414
|
if (soonest !== void 0 && cooling.length >= candidates.length) {
|
|
376
415
|
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}`;
|
|
@@ -464,13 +503,14 @@ var Router = class {
|
|
|
464
503
|
try {
|
|
465
504
|
const client = await abortable(this.client(account), signal);
|
|
466
505
|
const catalog = await abortable(client.models(signal), signal);
|
|
467
|
-
const
|
|
506
|
+
const suitable = route.enforceContext ? catalog.filter((m) => contextInfo(m).maxContextWindow >= route.contextWindow) : catalog;
|
|
507
|
+
const model = matchModel(alias, target, suitable, effort ?? void 0);
|
|
468
508
|
if (!model) {
|
|
469
509
|
attempts.push({
|
|
470
510
|
account: account.id,
|
|
471
511
|
provider: account.provider,
|
|
472
512
|
status: 404,
|
|
473
|
-
kind: matchModel(alias, target, catalog) ? "reasoning_effort_unavailable" : "model_unavailable"
|
|
513
|
+
kind: matchModel(alias, target, catalog, effort ?? void 0) ? "context_window_unavailable" : matchModel(alias, target, catalog) ? "reasoning_effort_unavailable" : "model_unavailable"
|
|
474
514
|
});
|
|
475
515
|
continue;
|
|
476
516
|
}
|
|
@@ -483,7 +523,7 @@ var Router = class {
|
|
|
483
523
|
if (tried.has(dedupe)) continue;
|
|
484
524
|
tried.add(dedupe);
|
|
485
525
|
startedAt = performance.now();
|
|
486
|
-
result = await abortable(client.chat({ ...input, model: model.id }, signal), signal);
|
|
526
|
+
result = await abortable(client.chat({ ...input, model: model.id }, signal, { contextWindow: route.contextWindow }), signal);
|
|
487
527
|
signal?.throwIfAborted();
|
|
488
528
|
if (result.ok) {
|
|
489
529
|
this.active.set(alias, key);
|
|
@@ -519,9 +559,12 @@ var Router = class {
|
|
|
519
559
|
export {
|
|
520
560
|
Telemetry,
|
|
521
561
|
SessionMetrics,
|
|
562
|
+
contextInfo,
|
|
563
|
+
resolveContext,
|
|
564
|
+
qoderContextModel,
|
|
522
565
|
RouteError,
|
|
523
566
|
abortable,
|
|
524
567
|
matchModel,
|
|
525
568
|
Router
|
|
526
569
|
};
|
|
527
|
-
//# sourceMappingURL=chunk-
|
|
570
|
+
//# sourceMappingURL=chunk-5KYJADJ4.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/telemetry.mjs", "../src/model-context.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, source: event.source === 'api' ? 'api' : 'dsh',\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", "const positive = n => Number.isSafeInteger(n) && n > 0;\n\n// Preserve native/default tiers separately from the local DSH budget.\nexport function contextInfo(model) {\n const defaultContextWindow = positive(model.defaultContextWindow) ? model.defaultContextWindow\n : positive(model.contextWindow) ? model.contextWindow : 200000;\n const supportedContextWindows = [...new Set([defaultContextWindow, model.contextWindow, model.maxContextWindow,\n ...(Array.isArray(model.supportedContextWindows) ? model.supportedContextWindows : [])].filter(positive))].sort((a, b) => a - b);\n const maxContextWindow = supportedContextWindows.at(-1);\n return { defaultContextWindow, supportedContextWindows, maxContextWindow, contextWindow: maxContextWindow };\n}\n\nexport function resolveContext(models, selected, fallback = 200000) {\n const infos = models.map(contextInfo);\n const maxContextWindow = infos.length ? Math.max(...infos.map(m => m.maxContextWindow)) : fallback;\n const contextWindow = positive(selected) ? Math.min(selected, maxContextWindow) : maxContextWindow;\n return { maxContextWindow, contextWindow, contextKnown: infos.length > 0, configuredContextWindow: positive(selected) ? selected : null,\n supportedContextWindows: [...new Set([contextWindow, ...infos.flatMap(m => m.supportedContextWindows)])].sort((a, b) => a - b) };\n}\n\n// Select the smallest real wire tier that can honour a local budget. Never mutate\n// the shared discovered catalog: concurrent routes may request different tiers.\nexport function qoderContextModel(model, budget) {\n if (!model?.contextOptions) return model;\n const entries = Object.entries(model.contextOptions).filter(([, v]) => positive(v.tokenCount)).sort((a, b) => a[1].tokenCount - b[1].tokenCount);\n if (!entries.length) return model;\n const selected = budget == null ? entries.at(-1) : entries.find(([, v]) => v.tokenCount >= budget);\n if (!selected) throw Object.assign(Error('context_window_unavailable'), { status: 400, code: 'context_window_unavailable' });\n return { ...model, contextWindow: selected[1].tokenCount,\n contextOptions: Object.fromEntries(Object.entries(model.contextOptions).map(([key, value]) => [key, { ...value, isDefault: key === selected[0] }])) };\n}\n", "import { meterResponse } from './telemetry.mjs';\nimport { isFreeModel } from './config.mjs';\nimport { reasoningModes } from './reasoning.mjs';\nimport { contextInfo } from './model-context.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', 'context_window_unavailable'].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 (kinds.has('context_window_unavailable') && modelOnly) return '\u5019\u9009\u6E20\u9053\u4E0D\u652F\u6301\u5F53\u524D\u4E0A\u4E0B\u6587\u9884\u7B97\uFF0C\u8BF7\u5237\u65B0\u76EE\u5F55\u6216\u5728\u6A21\u578B\uFF0F\u8DEF\u7531\u8BBE\u7F6E\u4E2D\u8C03\u4F4E\u9884\u7B97\uFF1B\u4E0D\u4F1A\u622A\u65AD\u4F1A\u8BDD\u6216\u964D\u7EA7\u5230\u5C0F\u5BB9\u91CF\u6E20\u9053';\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 suitable = route.enforceContext ? catalog.filter(m => contextInfo(m).maxContextWindow >= route.contextWindow) : catalog;\n const model = matchModel(alias, target, suitable, effort ?? undefined);\n if (!model) { attempts.push({ account: account.id, provider: account.provider, status: 404,\n kind: matchModel(alias, target, catalog, effort ?? undefined) ? 'context_window_unavailable'\n : 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, { contextWindow: route.contextWindow }), 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
|
+
}
|
|
@@ -35,6 +35,7 @@ var PROVIDER_NAMES = {
|
|
|
35
35
|
};
|
|
36
36
|
var FLASH_PRESET = {
|
|
37
37
|
name: "DeepSeek V4.1 Flash \xB7 \u81EA\u52A8\u8DEF\u7531",
|
|
38
|
+
contextMode: "maximum",
|
|
38
39
|
contextWindow: 2e5,
|
|
39
40
|
maxTokens: 32e3,
|
|
40
41
|
preferExpiringCredits: true,
|
|
@@ -43,17 +44,19 @@ var FLASH_PRESET = {
|
|
|
43
44
|
};
|
|
44
45
|
var sharedPreset = (name, workbuddy, trae, qoder) => ({
|
|
45
46
|
name: `${name} \xB7 \u81EA\u52A8\u8DEF\u7531`,
|
|
47
|
+
contextMode: "maximum",
|
|
46
48
|
contextWindow: 2e5,
|
|
47
49
|
maxTokens: 32e3,
|
|
48
50
|
preferExpiringCredits: true,
|
|
49
51
|
expiringWithinDays: 7,
|
|
50
|
-
targets: [
|
|
52
|
+
targets: [["workbuddy", workbuddy], ["trae", trae], ["qoder", qoder]].filter(([, models]) => models).map(([provider, models]) => ({ provider, models: Array.isArray(models) ? models : [models] }))
|
|
51
53
|
});
|
|
52
54
|
var ROUTE_PRESETS = {
|
|
53
55
|
free: {
|
|
54
56
|
name: "Free \xB7 \u52A8\u6001\u514D\u8D39\u6A21\u578B",
|
|
55
57
|
freeOnly: true,
|
|
56
58
|
visible: true,
|
|
59
|
+
contextMode: "maximum",
|
|
57
60
|
contextWindow: 2e5,
|
|
58
61
|
maxTokens: 32e3,
|
|
59
62
|
strategy: "failover",
|
|
@@ -66,12 +69,17 @@ var ROUTE_PRESETS = {
|
|
|
66
69
|
"glm-5.3-flash": sharedPreset("GLM-5.3-Flash", "glm-5.3-flash", "glm-5.3-flash", "gfmodel"),
|
|
67
70
|
"kimi-k3": sharedPreset("Kimi-K3", "kimi-k3-1", "kimi-k3", "kmodel_latest"),
|
|
68
71
|
"kimi-k2.8-preview": sharedPreset("Kimi-K2.8-Preview", "kimi-k2.8-preview", "kimi-k2.8-preview", "kmodel"),
|
|
69
|
-
"minimax-m2.7": sharedPreset("MiniMax-M2.7", "minimax-m2.7", "minimax-m2.7", "mmodel")
|
|
72
|
+
"minimax-m2.7": sharedPreset("MiniMax-M2.7", "minimax-m2.7", "minimax-m2.7", "mmodel"),
|
|
73
|
+
// WorkBuddy does not advertise these models. Only bind verified Trae/Qoder IDs.
|
|
74
|
+
"qwen3.8-max": sharedPreset("Qwen3.8-Max", null, "qwen3.8-max", "qmodel_38max"),
|
|
75
|
+
"qwen3.8-flash": sharedPreset("Qwen3.8-Flash", null, "qwen3.8-flash", "qfmodel"),
|
|
76
|
+
"hy4-preview": sharedPreset("Hy4 Preview", "hy4-preview", null, null)
|
|
70
77
|
};
|
|
71
78
|
var DEFAULT_ROUTES = {
|
|
72
79
|
free: ROUTE_PRESETS.free,
|
|
73
80
|
"ds4.1f": {
|
|
74
81
|
name: "DeepSeek V4.1 Flash \xB7 Auto",
|
|
82
|
+
contextMode: "maximum",
|
|
75
83
|
contextWindow: 2e5,
|
|
76
84
|
maxTokens: 32e3,
|
|
77
85
|
preferExpiringCredits: true,
|
|
@@ -80,6 +88,35 @@ var DEFAULT_ROUTES = {
|
|
|
80
88
|
},
|
|
81
89
|
...ROUTE_PRESETS
|
|
82
90
|
};
|
|
91
|
+
var LEGACY_ROUTE_PRESETS = [
|
|
92
|
+
"free",
|
|
93
|
+
"deepseek-v4.1-flash",
|
|
94
|
+
"deepseek-v4-pro",
|
|
95
|
+
"glm-5.3",
|
|
96
|
+
"glm-5.3-flash",
|
|
97
|
+
"kimi-k3",
|
|
98
|
+
"kimi-k2.8-preview",
|
|
99
|
+
"minimax-m2.7"
|
|
100
|
+
];
|
|
101
|
+
function upgradeRoutePresets(raw) {
|
|
102
|
+
const ids = Object.keys(ROUTE_PRESETS);
|
|
103
|
+
if (ids.every((id) => raw.seenRoutePresets?.includes(id))) return raw;
|
|
104
|
+
const routes = raw.routes ?? DEFAULT_ROUTES;
|
|
105
|
+
const seen = /* @__PURE__ */ new Set([
|
|
106
|
+
...LEGACY_ROUTE_PRESETS,
|
|
107
|
+
...raw.seenRoutePresets ?? [],
|
|
108
|
+
...Object.keys(routes).filter((id) => Object.hasOwn(ROUTE_PRESETS, id))
|
|
109
|
+
]);
|
|
110
|
+
const additions = ids.filter((id) => !seen.has(id));
|
|
111
|
+
return {
|
|
112
|
+
...raw,
|
|
113
|
+
...additions.length ? { routes: {
|
|
114
|
+
...routes,
|
|
115
|
+
...Object.fromEntries(additions.map((id) => [id, structuredClone(ROUTE_PRESETS[id])]))
|
|
116
|
+
} } : {},
|
|
117
|
+
seenRoutePresets: [.../* @__PURE__ */ new Set([...seen, ...ids])]
|
|
118
|
+
};
|
|
119
|
+
}
|
|
83
120
|
var object = (x) => x !== null && typeof x === "object" && !Array.isArray(x);
|
|
84
121
|
var nonempty = (x) => typeof x === "string" && x.trim().length > 0;
|
|
85
122
|
var positive = (x) => Number.isSafeInteger(x) && x > 0;
|
|
@@ -109,16 +146,22 @@ function validateConfig(raw, file = resolve("router.json")) {
|
|
|
109
146
|
};
|
|
110
147
|
});
|
|
111
148
|
if (!object(raw.routes ?? DEFAULT_ROUTES)) throw new Error("Routes must be an object");
|
|
112
|
-
const routes = Object.fromEntries(Object.entries(raw.routes ?? DEFAULT_ROUTES).map(([id, route]) => [id, {
|
|
149
|
+
const routes = Object.fromEntries(Object.entries(raw.routes ?? DEFAULT_ROUTES).map(([id, route]) => [id, {
|
|
150
|
+
...route,
|
|
151
|
+
contextMode: route?.contextMode ?? (route?.contextWindow === 2e5 ? "maximum" : "custom"),
|
|
152
|
+
preferExpiringCredits: route?.preferExpiringCredits ?? !route?.freeOnly,
|
|
153
|
+
expiringWithinDays: route?.expiringWithinDays ?? 7
|
|
154
|
+
}]));
|
|
113
155
|
for (const [alias, route] of Object.entries(routes)) {
|
|
114
156
|
if (!/^[a-zA-Z0-9_.-]{1,128}$/.test(alias) || !object(route) || !Array.isArray(route.targets) || !route.targets.length) throw new Error(`Invalid route ${alias}`);
|
|
115
157
|
for (const key of ["contextWindow", "maxTokens"]) if (!positive(route[key])) throw new Error(`Route ${alias} needs a positive ${key}`);
|
|
158
|
+
if (!["maximum", "custom"].includes(route.contextMode)) throw new Error(`Invalid contextMode in ${alias}`);
|
|
116
159
|
if (route.maxTokens > route.contextWindow) throw new Error(`Route ${alias}: maxTokens exceeds contextWindow`);
|
|
117
160
|
if (route.supportsImages !== void 0 && typeof route.supportsImages !== "boolean") throw new Error(`Invalid supportsImages for ${alias}`);
|
|
118
161
|
if (route.visible !== void 0 && typeof route.visible !== "boolean") throw new Error(`Invalid visibility for ${alias}`);
|
|
119
162
|
if (route.name !== void 0 && (!nonempty(route.name) || route.name.length > 200)) throw new Error(`Invalid route name for ${alias}`);
|
|
120
163
|
if (route.freeOnly !== void 0 && typeof route.freeOnly !== "boolean") throw new Error(`Invalid freeOnly for ${alias}`);
|
|
121
|
-
if (route.freeModels !== void 0 && (!route.freeOnly || !object(route.freeModels) || Object.entries(route.freeModels).some(([id, p]) => !/^free_[a-f0-9]{24}$/.test(id) || !object(p) || Object.keys(p).some((k) => !["visible", "reasoningEffort"].includes(k)) || p.visible !== void 0 && typeof p.visible !== "boolean" || p.reasoningEffort !== void 0 && 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");
|
|
164
|
+
if (route.freeModels !== void 0 && (!route.freeOnly || !object(route.freeModels) || Object.entries(route.freeModels).some(([id, p]) => !/^free_[a-f0-9]{24}$/.test(id) || !object(p) || Object.keys(p).some((k) => !["visible", "reasoningEffort", "contextWindow"].includes(k)) || p.visible !== void 0 && typeof p.visible !== "boolean" || p.contextWindow !== void 0 && p.contextWindow !== null && !positive(p.contextWindow) || p.reasoningEffort !== void 0 && 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");
|
|
122
165
|
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");
|
|
123
166
|
if (route.preferExpiringCredits !== void 0 && typeof route.preferExpiringCredits !== "boolean") throw new Error(`Invalid expiring credits flag in ${alias}`);
|
|
124
167
|
if (route.expiringWithinDays !== void 0 && (!positive(route.expiringWithinDays) || route.expiringWithinDays > 365)) throw new Error(`Invalid expiry horizon in ${alias}`);
|
|
@@ -142,7 +185,7 @@ function validateConfig(raw, file = resolve("router.json")) {
|
|
|
142
185
|
for (const [provider, preferences] of Object.entries(models)) {
|
|
143
186
|
if (!PROVIDERS.includes(provider) || !object(preferences)) throw new Error("Invalid model provider");
|
|
144
187
|
for (const [id, preference] of Object.entries(preferences)) {
|
|
145
|
-
if (!nonempty(id) || id.length > 256 || !object(preference) || preference.name !== void 0 && (!nonempty(preference.name) || preference.name.length > 200) || preference.visible !== void 0 && typeof preference.visible !== "boolean") throw new Error("Invalid model preference");
|
|
188
|
+
if (!nonempty(id) || id.length > 256 || !object(preference) || preference.name !== void 0 && (!nonempty(preference.name) || preference.name.length > 200) || preference.visible !== void 0 && typeof preference.visible !== "boolean" || preference.contextWindow !== void 0 && preference.contextWindow !== null && !positive(preference.contextWindow) || preference.supportsImages !== void 0 && typeof preference.supportsImages !== "boolean" || preference.reasoningEffort !== void 0 && preference.reasoningEffort !== null && !REASONING_EFFORTS.includes(preference.reasoningEffort)) throw new Error("Invalid model preference");
|
|
146
189
|
}
|
|
147
190
|
}
|
|
148
191
|
const modelVisibility = raw.modelVisibility ?? {};
|
|
@@ -151,6 +194,7 @@ function validateConfig(raw, file = resolve("router.json")) {
|
|
|
151
194
|
if (raw.retryServerErrors !== void 0 && typeof raw.retryServerErrors !== "boolean") throw new Error("Invalid retryServerErrors");
|
|
152
195
|
if (raw.sidebarUsage !== void 0 && typeof raw.sidebarUsage !== "boolean") throw new Error("\u4FA7\u680F\u7528\u91CF\u5F00\u5173\u5FC5\u987B\u662F\u5E03\u5C14\u503C");
|
|
153
196
|
if (raw.ignoredLocalAccounts !== void 0 && (!Array.isArray(raw.ignoredLocalAccounts) || raw.ignoredLocalAccounts.some((k) => typeof k !== "string" || k.length > 1024))) throw new Error("Invalid ignoredLocalAccounts");
|
|
197
|
+
if (raw.seenRoutePresets !== void 0 && (!Array.isArray(raw.seenRoutePresets) || raw.seenRoutePresets.length > 500 || raw.seenRoutePresets.some((id) => typeof id !== "string" || !/^[a-zA-Z0-9_.-]{1,128}$/.test(id)))) throw new Error("Invalid seenRoutePresets");
|
|
154
198
|
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");
|
|
155
199
|
const checkinSchedule = raw.checkinSchedule ?? { mode: "scheduled", time: "10:05" };
|
|
156
200
|
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");
|
|
@@ -169,24 +213,27 @@ function validateConfig(raw, file = resolve("router.json")) {
|
|
|
169
213
|
usageRetentionDays: raw.usageRetentionDays ?? 30
|
|
170
214
|
};
|
|
171
215
|
}
|
|
172
|
-
async function readConfig(file) {
|
|
173
|
-
return validateConfig(JSON.parse(await readFile(file, "utf8")), resolve(file));
|
|
174
|
-
}
|
|
175
216
|
async function ensureConfig(file) {
|
|
176
217
|
try {
|
|
177
|
-
|
|
218
|
+
const raw = JSON.parse(await readFile(file, "utf8")), config = validateConfig(raw, resolve(file));
|
|
219
|
+
if (upgradeRoutePresets(raw) === raw) return config;
|
|
178
220
|
} catch (error) {
|
|
179
221
|
if (error.code !== "ENOENT") throw error;
|
|
180
222
|
}
|
|
181
223
|
await mkdir(dirname(file), { recursive: true, mode: 448 });
|
|
182
224
|
return withFileLock(file, async () => {
|
|
225
|
+
let raw, created = false;
|
|
183
226
|
try {
|
|
184
|
-
|
|
227
|
+
raw = JSON.parse(await readFile(file, "utf8"));
|
|
185
228
|
} catch (error) {
|
|
186
229
|
if (error.code !== "ENOENT") throw error;
|
|
230
|
+
raw = { accounts: [], routes: ROUTE_PRESETS };
|
|
231
|
+
created = true;
|
|
187
232
|
}
|
|
188
|
-
|
|
189
|
-
|
|
233
|
+
validateConfig(raw, resolve(file));
|
|
234
|
+
const next = upgradeRoutePresets(raw), config = validateConfig(next, resolve(file));
|
|
235
|
+
if (created || next !== raw) await writePrivateJson(file, next);
|
|
236
|
+
return config;
|
|
190
237
|
}, { waitMs: 3e4 });
|
|
191
238
|
}
|
|
192
239
|
async function writePrivateJson(file, value) {
|
|
@@ -212,4 +259,4 @@ export {
|
|
|
212
259
|
ensureConfig,
|
|
213
260
|
writePrivateJson
|
|
214
261
|
};
|
|
215
|
-
//# sourceMappingURL=chunk-
|
|
262
|
+
//# sourceMappingURL=chunk-5R3IOPSF.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 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', contextMode: 'maximum', 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`, contextMode: 'maximum', contextWindow: 200000, maxTokens: 32000, preferExpiringCredits: true, expiringWithinDays: 7,\n targets: [['workbuddy', workbuddy], ['trae', trae], ['qoder', qoder]]\n .filter(([, models]) => models).map(([provider, models]) => ({ provider, models: Array.isArray(models) ? models : [models] })),\n});\nexport const ROUTE_PRESETS = {\n free: { name: 'Free \u00B7 \u52A8\u6001\u514D\u8D39\u6A21\u578B', freeOnly: true, visible: true, contextMode: 'maximum', 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 // WorkBuddy does not advertise these models. Only bind verified Trae/Qoder IDs.\n 'qwen3.8-max': sharedPreset('Qwen3.8-Max', null, 'qwen3.8-max', 'qmodel_38max'),\n 'qwen3.8-flash': sharedPreset('Qwen3.8-Flash', null, 'qwen3.8-flash', 'qfmodel'),\n 'hy4-preview': sharedPreset('Hy4 Preview', 'hy4-preview', null, null),\n};\nexport const DEFAULT_ROUTES = {\n free: ROUTE_PRESETS.free,\n 'ds4.1f': {\n name: 'DeepSeek V4.1 Flash \u00B7 Auto', contextMode: 'maximum', contextWindow: 200000, maxTokens: 32000, preferExpiringCredits: true, expiringWithinDays: 7,\n targets: PROVIDERS.map(provider => ({ provider })),\n },\n ...ROUTE_PRESETS,\n};\n// Before preset history existed, these were already shipped. Missing old IDs\n// represent user removals; only subsequently introduced presets are auto-added.\nconst LEGACY_ROUTE_PRESETS = ['free', 'deepseek-v4.1-flash', 'deepseek-v4-pro', 'glm-5.3',\n 'glm-5.3-flash', 'kimi-k3', 'kimi-k2.8-preview', 'minimax-m2.7'];\nexport function upgradeRoutePresets(raw) {\n const ids = Object.keys(ROUTE_PRESETS);\n if (ids.every(id => raw.seenRoutePresets?.includes(id))) return raw;\n const routes = raw.routes ?? DEFAULT_ROUTES;\n const seen = new Set([...LEGACY_ROUTE_PRESETS, ...(raw.seenRoutePresets ?? []),\n ...Object.keys(routes).filter(id => Object.hasOwn(ROUTE_PRESETS, id))]);\n const additions = ids.filter(id => !seen.has(id));\n return { ...raw, ...(additions.length ? { routes: { ...routes,\n ...Object.fromEntries(additions.map(id => [id, structuredClone(ROUTE_PRESETS[id])])) } } : {}),\n seenRoutePresets: [...new Set([...seen, ...ids])] };\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,\n contextMode: route?.contextMode ?? (route?.contextWindow === 200000 ? 'maximum' : 'custom'),\n 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 (!['maximum', 'custom'].includes(route.contextMode)) throw new Error(`Invalid contextMode in ${alias}`);\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', 'contextWindow'].includes(k))\n || (p.visible !== undefined && typeof p.visible !== 'boolean')\n || (p.contextWindow !== undefined && p.contextWindow !== null && !positive(p.contextWindow))\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')\n || (preference.contextWindow !== undefined && preference.contextWindow !== null && !positive(preference.contextWindow))\n || (preference.supportsImages !== undefined && typeof preference.supportsImages !== 'boolean')\n || (preference.reasoningEffort !== undefined && preference.reasoningEffort !== null && !REASONING_EFFORTS.includes(preference.reasoningEffort))) 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.sidebarUsage !== undefined && typeof raw.sidebarUsage !== 'boolean') throw new Error('\u4FA7\u680F\u7528\u91CF\u5F00\u5173\u5FC5\u987B\u662F\u5E03\u5C14\u503C');\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.seenRoutePresets !== undefined && (!Array.isArray(raw.seenRoutePresets) || raw.seenRoutePresets.length > 500\n || raw.seenRoutePresets.some(id => typeof id !== 'string' || !/^[a-zA-Z0-9_.-]{1,128}$/.test(id)))) throw new Error('Invalid seenRoutePresets');\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 }, sidebarUsage: raw.sidebarUsage ?? true,\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 {\n const raw = JSON.parse(await readFile(file, 'utf8')), config = validateConfig(raw, resolve(file));\n if (upgradeRoutePresets(raw) === raw) return config;\n } catch (error) { if (error.code !== 'ENOENT') throw error; }\n await mkdir(dirname(file), { recursive: true, mode: 0o700 });\n return withFileLock(file, async () => {\n let raw, created = false;\n try { raw = JSON.parse(await readFile(file, 'utf8')); } catch (error) {\n if (error.code !== 'ENOENT') throw error;\n raw = { accounts: [], routes: ROUTE_PRESETS }; created = true;\n }\n validateConfig(raw, resolve(file));\n const next = upgradeRoutePresets(raw), config = validateConfig(next, resolve(file));\n if (created || next !== raw) await writePrivateJson(file, next);\n return config;\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
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -20,12 +20,13 @@ import {
|
|
|
20
20
|
} from "./chunk-4V52V5GO.js";
|
|
21
21
|
import {
|
|
22
22
|
RouteError,
|
|
23
|
-
abortable
|
|
24
|
-
|
|
23
|
+
abortable,
|
|
24
|
+
qoderContextModel
|
|
25
|
+
} from "./chunk-5KYJADJ4.js";
|
|
25
26
|
import {
|
|
26
27
|
beijingDay,
|
|
27
28
|
writePrivateJson
|
|
28
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-5R3IOPSF.js";
|
|
29
30
|
|
|
30
31
|
// src/clients.mjs
|
|
31
32
|
import { readFile as readFile2 } from "node:fs/promises";
|
|
@@ -5221,14 +5222,21 @@ async function createAccountClient(account, config, attachments) {
|
|
|
5221
5222
|
};
|
|
5222
5223
|
};
|
|
5223
5224
|
discover = (signal) => client.fetchModels(signal);
|
|
5224
|
-
chat = (input, signal) =>
|
|
5225
|
+
chat = (input, signal, options) => new QoderUpstreamClient({
|
|
5226
|
+
region,
|
|
5227
|
+
providerId: account.provider,
|
|
5228
|
+
getPat,
|
|
5229
|
+
transport,
|
|
5230
|
+
...attachments ? { attachments } : {},
|
|
5231
|
+
catalogProvider: (id) => qoderContextModel(client.catalogModelFor(id), options?.contextWindow)
|
|
5232
|
+
}).chatStream(JSON.stringify(input), signal);
|
|
5225
5233
|
}
|
|
5226
5234
|
return {
|
|
5227
5235
|
models: cachedModels(discover, config.catalogTtlMs),
|
|
5228
5236
|
accountInfo,
|
|
5229
5237
|
checkin,
|
|
5230
|
-
async chat(input, signal) {
|
|
5231
|
-
const result = await chat(input, signal);
|
|
5238
|
+
async chat(input, signal, options) {
|
|
5239
|
+
const result = await chat(input, signal, options);
|
|
5232
5240
|
return result.ok ? preflightStream(result.response, signal) : result;
|
|
5233
5241
|
}
|
|
5234
5242
|
};
|
|
@@ -5410,4 +5418,4 @@ export {
|
|
|
5410
5418
|
refreshWorkBuddyCheckinCredential,
|
|
5411
5419
|
createWorkBuddyCheckin
|
|
5412
5420
|
};
|
|
5413
|
-
//# sourceMappingURL=chunk-
|
|
5421
|
+
//# sourceMappingURL=chunk-74WQLVJO.js.map
|