dsh-multi-router 0.6.12 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +2 -430
  2. package/package.json +5 -81
  3. package/CHANGELOG.md +0 -243
  4. package/LICENSE +0 -21
  5. package/THIRD_PARTY_NOTICES.md +0 -171
  6. package/cordis.patch.yml +0 -3
  7. package/lib/accounts.js +0 -19
  8. package/lib/accounts.js.map +0 -7
  9. package/lib/api-service.js +0 -11
  10. package/lib/api-service.js.map +0 -7
  11. package/lib/chunk-2UM45OXY.js +0 -181
  12. package/lib/chunk-2UM45OXY.js.map +0 -7
  13. package/lib/chunk-4L2CBGXN.js +0 -674
  14. package/lib/chunk-4L2CBGXN.js.map +0 -7
  15. package/lib/chunk-4V52V5GO.js +0 -105
  16. package/lib/chunk-4V52V5GO.js.map +0 -7
  17. package/lib/chunk-DNQPZMPF.js +0 -33
  18. package/lib/chunk-DNQPZMPF.js.map +0 -7
  19. package/lib/chunk-FLL3DUVP.js +0 -2017
  20. package/lib/chunk-FLL3DUVP.js.map +0 -7
  21. package/lib/chunk-GEBZMIMA.js +0 -287
  22. package/lib/chunk-GEBZMIMA.js.map +0 -7
  23. package/lib/chunk-KWXLQJS5.js +0 -1102
  24. package/lib/chunk-KWXLQJS5.js.map +0 -7
  25. package/lib/chunk-NZF36O5I.js +0 -5421
  26. package/lib/chunk-NZF36O5I.js.map +0 -7
  27. package/lib/chunk-S5KMFAQM.js +0 -50
  28. package/lib/chunk-S5KMFAQM.js.map +0 -7
  29. package/lib/chunk-TM5XDMGY.js +0 -332
  30. package/lib/chunk-TM5XDMGY.js.map +0 -7
  31. package/lib/chunk-V37VG7MN.js +0 -2101
  32. package/lib/chunk-V37VG7MN.js.map +0 -7
  33. package/lib/chunk-WDIT4E2W.js +0 -120
  34. package/lib/chunk-WDIT4E2W.js.map +0 -7
  35. package/lib/cli.js +0 -103
  36. package/lib/cli.js.map +0 -7
  37. package/lib/client.js +0 -2805
  38. package/lib/client.js.map +0 -7
  39. package/lib/clients.js +0 -30
  40. package/lib/clients.js.map +0 -7
  41. package/lib/host-v0.6.12.js +0 -414
  42. package/lib/host.js +0 -414
  43. package/lib/index.js +0 -414
  44. package/lib/index.js.map +0 -7
  45. package/lib/manager.js +0 -27
  46. package/lib/manager.js.map +0 -7
  47. package/lib/region-DO3KAV7V.js +0 -15
  48. package/lib/region-DO3KAV7V.js.map +0 -7
  49. package/lib/router.js +0 -14
  50. package/lib/router.js.map +0 -7
  51. package/lib/shim.js +0 -10
  52. package/lib/shim.js.map +0 -7
  53. package/lib/upstream-VP6J7LU2.js +0 -25
  54. package/lib/upstream-VP6J7LU2.js.map +0 -7
  55. package/router.example.json +0 -289
  56. package/upstream-lock.json +0 -17
@@ -1,7 +0,0 @@
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(); this.budgets = new Map();\n }\n /**\n * Sort candidates inside each expiring-credit group, never across the boundary.\n *\n * `group` classifies a candidate \u2014 expiring versus not \u2014 and only the order inside a\n * group changes. That keeps every account holding expiring credits ahead of the ones\n * that do not, whatever their price, while the accounts within the expiring group are\n * still ordered among themselves. `key` returning undefined means \"no opinion\" and\n * sorts last inside its own group rather than counting as the cheapest.\n */\n sortWithinGroups(candidates, group, key) {\n const groups = new Map();\n for (const candidate of candidates) {\n const name = group(candidate);\n if (!groups.has(name)) groups.set(name, []);\n groups.get(name).push(candidate);\n }\n const result = [];\n for (const members of groups.values()) {\n const decorated = members.map((candidate, index) => ({ candidate, index, key: key(candidate) }));\n decorated.sort((a, b) => {\n if (a.key === b.key) return a.index - b.index;\n if (a.key === undefined) return 1;\n if (b.key === undefined) return -1;\n return a.key - b.key;\n });\n result.push(...decorated.map(entry => entry.candidate));\n }\n return result;\n }\n /**\n * Move accounts whose observed credit spend exceeded this route's threshold behind\n * the ones that still have headroom, inside each expiring-credit group.\n *\n * This is a preference, not a filter: the caller keeps every candidate, so a route\n * whose accounts are all over budget still serves requests instead of failing. The\n * baseline is per route and per account, so switching accounts resets a newcomer's\n * counter to zero while the previous account stays demoted for the rest of the round.\n *\n * `group` splits candidates into expiring and non-expiring. Scoping the demotion to\n * that split keeps an account holding expiring credits ahead of one that does not,\n * while the expiring accounts still take turns among themselves \u2014 grouping by the exact\n * expiry date instead would leave each of them alone in its own group, and the allowance\n * would never move a request off an account that still has credits left.\n *\n * Once every candidate in a group has spent its allowance the round is over and those\n * baselines restart from the current total. Without that reset the counters only ever\n * grow, every account stays demoted forever and the ordering stops changing after one pass.\n *\n * Spend is inferred from platform balance drops, so one request may overshoot and an\n * account without a usable balance reading is never demoted on a guess.\n */\n demoteOverBudget(alias, route, candidates, group = () => false) {\n if (!candidates.length) return candidates;\n const threshold = route.creditBalanceThreshold ?? 1000;\n const bases = this.budgets.get(alias) ?? new Map();\n this.budgets.set(alias, bases);\n const live = new Set(candidates.map(c => c.account.id));\n for (const id of bases.keys()) if (!live.has(id)) bases.delete(id);\n const groups = new Map();\n for (const candidate of candidates) {\n const name = group(candidate);\n if (!groups.has(name)) groups.set(name, []);\n groups.get(name).push(candidate);\n }\n const result = [];\n for (const group of groups.values()) {\n const fresh = [], spent = [];\n for (const candidate of group) {\n const id = candidate.account.id, row = this.telemetry.row('accounts', id);\n const observed = row.creditsObserved ?? 0;\n if (!bases.has(id)) bases.set(id, observed);\n const used = observed - bases.get(id);\n // A balance rewrite (prepaid top-up, new settlement cycle) must not keep an account\n // demoted on a negative counter.\n if (!Number.isFinite(used) || used < 0) { bases.set(id, observed); fresh.push(candidate); continue; }\n (used >= threshold ? spent : fresh).push(candidate);\n }\n if (!spent.length) { result.push(...fresh); continue; }\n if (spent.length === group.length) {\n // Every account in this group has used its allowance: bank the totals and start a\n // new round for the group.\n for (const candidate of group) bases.set(candidate.account.id, this.telemetry.row('accounts', candidate.account.id).creditsObserved ?? 0);\n result.push(...group);\n continue;\n }\n result.push(...fresh, ...spent);\n }\n return result;\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 for (const alias of this.budgets.keys()) if (!Object.hasOwn(config.routes, alias)) this.budgets.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 // One group for accounts holding expiring credits and one for the rest. Every rule\n // below reorders only inside a group, so an expiring account stays ahead of a\n // non-expiring one whatever its price or remaining allowance.\n const expiringGroup = c => Number.isFinite(expiry(c));\n // Soonest expiry first, and that order is the starting point every later rule refines.\n // Comparing dates directly and breaking ties by the original index keeps two\n // non-expiring accounts equal, which subtracting two Infinity values would not.\n if (preferActive) {\n const ordered = candidates.map((candidate, index) => ({ candidate, index }));\n ordered.sort((a, b) => Number(expiringGroup(b.candidate)) - Number(expiringGroup(a.candidate))\n || expiry(a.candidate) - expiry(b.candidate) || a.index - b.index);\n candidates = ordered.map(entry => entry.candidate);\n }\n // Cheapest known rate first, inside the expiring group only. The rate is unrelated to\n // expiry, so it must not reorder accounts by how soon their credits run out: that\n // ordering is the point of the priority rule, and a cheaper pack expiring later is not\n // a reason to spend it first.\n if (route.discountOrder && !route.freeOnly) candidates = this.sortWithinGroups(candidates, candidate => expiry(candidate), candidate => {\n const rate = route.creditRates?.[candidate.account.id];\n return rate === undefined ? undefined : rate;\n });\n if (route.balanceCredits && !route.freeOnly && this.telemetry) candidates = this.demoteOverBudget(alias, route, candidates, expiringGroup);\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", "group"]
7
- }
@@ -1,105 +0,0 @@
1
- // upstream/trae/src/sse.ts
2
- var SseDecoder = class {
3
- buffer = "";
4
- event;
5
- id;
6
- retry;
7
- data = [];
8
- push(chunk) {
9
- this.buffer += chunk;
10
- const events = [];
11
- while (true) {
12
- const match = /\r?\n/.exec(this.buffer);
13
- if (match === null || match.index === void 0) break;
14
- const line = this.buffer.slice(0, match.index);
15
- this.buffer = this.buffer.slice(match.index + match[0].length);
16
- const emitted = this.consumeLine(line);
17
- if (emitted !== void 0) events.push(emitted);
18
- }
19
- return events;
20
- }
21
- finish() {
22
- const events = [];
23
- if (this.buffer !== "") {
24
- const emitted = this.consumeLine(this.buffer);
25
- this.buffer = "";
26
- if (emitted !== void 0) events.push(emitted);
27
- }
28
- const final = this.dispatch();
29
- if (final !== void 0) events.push(final);
30
- return events;
31
- }
32
- consumeLine(line) {
33
- if (line === "") return this.dispatch();
34
- if (line.startsWith(":")) return void 0;
35
- const colon = line.indexOf(":");
36
- const field = colon === -1 ? line : line.slice(0, colon);
37
- let value = colon === -1 ? "" : line.slice(colon + 1);
38
- if (value.startsWith(" ")) value = value.slice(1);
39
- if (field === "event") this.event = value;
40
- else if (field === "data") this.data.push(value);
41
- else if (field === "id" && !value.includes("\0")) this.id = value;
42
- else if (field === "retry" && /^\d+$/.test(value)) this.retry = Number(value);
43
- return void 0;
44
- }
45
- dispatch() {
46
- if (this.data.length === 0) {
47
- this.event = void 0;
48
- this.retry = void 0;
49
- return void 0;
50
- }
51
- const result = {
52
- ...this.event === void 0 || this.event === "" ? {} : { event: this.event },
53
- data: this.data.join("\n"),
54
- ...this.id === void 0 ? {} : { id: this.id },
55
- ...this.retry === void 0 ? {} : { retry: this.retry }
56
- };
57
- this.event = void 0;
58
- this.retry = void 0;
59
- this.data = [];
60
- return result;
61
- }
62
- };
63
- function decodeTraeEvent(event) {
64
- if (event.data === "[DONE]") return { type: "done", finishReason: "stop" };
65
- let payload;
66
- try {
67
- payload = JSON.parse(event.data);
68
- } catch {
69
- return { type: "unknown", ...event.event === void 0 ? {} : { event: event.event }, data: event.data };
70
- }
71
- const record = typeof payload === "object" && payload !== null && !Array.isArray(payload) ? payload : {};
72
- if (event.event === "request_wait_in_queue") {
73
- return { type: "queue", ...typeof record["position"] === "number" ? { position: record["position"] } : {} };
74
- }
75
- if (event.event === "progress_notice") return { type: "progress", notice: payload };
76
- if (event.event === "token_usage") {
77
- return {
78
- type: "usage",
79
- ...typeof record["prompt_tokens"] === "number" ? { inputTokens: record["prompt_tokens"] } : {},
80
- ...typeof record["completion_tokens"] === "number" ? { outputTokens: record["completion_tokens"] } : {},
81
- ...typeof record["total_tokens"] === "number" ? { totalTokens: record["total_tokens"] } : {},
82
- ...typeof record["reasoning_tokens"] === "number" ? { reasoningTokens: record["reasoning_tokens"] } : {},
83
- ...typeof record["cache_read_input_tokens"] === "number" ? { cacheReadTokens: record["cache_read_input_tokens"] } : {},
84
- ...typeof record["cache_creation_input_tokens"] === "number" ? { cacheWriteTokens: record["cache_creation_input_tokens"] } : {}
85
- };
86
- }
87
- if (event.event === "done" || typeof record["finish_reason"] === "string" && record["response"] === void 0) {
88
- return { type: "done", finishReason: typeof record["finish_reason"] === "string" ? record["finish_reason"] : "stop" };
89
- }
90
- if (event.event === "output" || record["response"] !== void 0 || record["reasoning_content"] !== void 0) {
91
- return {
92
- type: "delta",
93
- text: typeof record["response"] === "string" ? record["response"] : "",
94
- ...typeof record["reasoning_content"] === "string" ? { reasoning: record["reasoning_content"] } : {},
95
- ...record["tool_calls"] === void 0 || record["tool_calls"] === null ? {} : { toolCalls: record["tool_calls"] }
96
- };
97
- }
98
- return { type: "unknown", ...event.event === void 0 ? {} : { event: event.event }, data: payload };
99
- }
100
-
101
- export {
102
- SseDecoder,
103
- decodeTraeEvent
104
- };
105
- //# sourceMappingURL=chunk-4V52V5GO.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../upstream/trae/src/sse.ts"],
4
- "sourcesContent": ["export interface SseEvent {\n event?: string\n data: string\n id?: string\n retry?: number\n}\n\n/** Incremental SSE decoder supporting CRLF, chunk splits and multi-line data. */\nexport class SseDecoder {\n private buffer = ''\n private event: string | undefined\n private id: string | undefined\n private retry: number | undefined\n private data: string[] = []\n\n push(chunk: string): SseEvent[] {\n this.buffer += chunk\n const events: SseEvent[] = []\n while (true) {\n const match = /\\r?\\n/.exec(this.buffer)\n if (match === null || match.index === undefined) break\n const line = this.buffer.slice(0, match.index)\n this.buffer = this.buffer.slice(match.index + match[0].length)\n const emitted = this.consumeLine(line)\n if (emitted !== undefined) events.push(emitted)\n }\n return events\n }\n\n finish(): SseEvent[] {\n const events: SseEvent[] = []\n if (this.buffer !== '') {\n const emitted = this.consumeLine(this.buffer)\n this.buffer = ''\n if (emitted !== undefined) events.push(emitted)\n }\n const final = this.dispatch()\n if (final !== undefined) events.push(final)\n return events\n }\n\n private consumeLine(line: string): SseEvent | undefined {\n if (line === '') return this.dispatch()\n if (line.startsWith(':')) return undefined\n const colon = line.indexOf(':')\n const field = colon === -1 ? line : line.slice(0, colon)\n let value = colon === -1 ? '' : line.slice(colon + 1)\n if (value.startsWith(' ')) value = value.slice(1)\n if (field === 'event') this.event = value\n else if (field === 'data') this.data.push(value)\n else if (field === 'id' && !value.includes('\\0')) this.id = value\n else if (field === 'retry' && /^\\d+$/.test(value)) this.retry = Number(value)\n return undefined\n }\n\n private dispatch(): SseEvent | undefined {\n if (this.data.length === 0) {\n this.event = undefined\n this.retry = undefined\n return undefined\n }\n const result: SseEvent = {\n ...this.event === undefined || this.event === '' ? {} : { event: this.event },\n data: this.data.join('\\n'),\n ...this.id === undefined ? {} : { id: this.id },\n ...this.retry === undefined ? {} : { retry: this.retry },\n }\n this.event = undefined\n this.retry = undefined\n this.data = []\n return result\n }\n}\n\nexport type TraeStreamEvent =\n | { type: 'queue'; position?: number }\n | { type: 'progress'; notice: unknown }\n | { type: 'delta'; text: string; reasoning?: string; toolCalls?: unknown }\n | {\n type: 'usage'\n inputTokens?: number\n outputTokens?: number\n totalTokens?: number\n reasoningTokens?: number\n /**\n * Trae's prompt-cache accounting (`cache_read_input_tokens` /\n * `cache_creation_input_tokens` on the `token_usage` event). Verified\n * 2026-09-22 (docs/ISSUE10_DIAGNOSIS.md): a byte-identical 9224-token\n * prompt reports `prompt_tokens: 9224` while `cache_read_input_tokens`\n * rises to 9216, so these are a *subset* of `prompt_tokens` \u2014 the OpenAI\n * convention, not Anthropic's exclusive one. Forwarding them as\n * `cached_tokens` is therefore arithmetically correct.\n */\n cacheReadTokens?: number\n cacheWriteTokens?: number\n }\n | { type: 'done'; finishReason: string }\n | { type: 'unknown'; event?: string; data: unknown }\n\nexport function decodeTraeEvent(event: SseEvent): TraeStreamEvent {\n if (event.data === '[DONE]') return { type: 'done', finishReason: 'stop' }\n let payload: unknown\n try { payload = JSON.parse(event.data) as unknown } catch { return { type: 'unknown', ...event.event === undefined ? {} : { event: event.event }, data: event.data } }\n const record = typeof payload === 'object' && payload !== null && !Array.isArray(payload) ? payload as Record<string, unknown> : {}\n if (event.event === 'request_wait_in_queue') {\n return { type: 'queue', ...typeof record['position'] === 'number' ? { position: record['position'] } : {} }\n }\n if (event.event === 'progress_notice') return { type: 'progress', notice: payload }\n if (event.event === 'token_usage') {\n return {\n type: 'usage',\n ...typeof record['prompt_tokens'] === 'number' ? { inputTokens: record['prompt_tokens'] } : {},\n ...typeof record['completion_tokens'] === 'number' ? { outputTokens: record['completion_tokens'] } : {},\n ...typeof record['total_tokens'] === 'number' ? { totalTokens: record['total_tokens'] } : {},\n ...typeof record['reasoning_tokens'] === 'number' ? { reasoningTokens: record['reasoning_tokens'] } : {},\n ...typeof record['cache_read_input_tokens'] === 'number' ? { cacheReadTokens: record['cache_read_input_tokens'] } : {},\n ...typeof record['cache_creation_input_tokens'] === 'number' ? { cacheWriteTokens: record['cache_creation_input_tokens'] } : {},\n }\n }\n if (event.event === 'done' || typeof record['finish_reason'] === 'string' && record['response'] === undefined) {\n return { type: 'done', finishReason: typeof record['finish_reason'] === 'string' ? record['finish_reason'] : 'stop' }\n }\n if (event.event === 'output' || record['response'] !== undefined || record['reasoning_content'] !== undefined) {\n return {\n type: 'delta',\n text: typeof record['response'] === 'string' ? record['response'] : '',\n ...typeof record['reasoning_content'] === 'string' ? { reasoning: record['reasoning_content'] } : {},\n ...record['tool_calls'] === undefined || record['tool_calls'] === null ? {} : { toolCalls: record['tool_calls'] },\n }\n }\n return { type: 'unknown', ...event.event === undefined ? {} : { event: event.event }, data: payload }\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,33 +0,0 @@
1
- // upstream/workbuddy/src/loopback.ts
2
- var LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["127.0.0.1", "localhost", "[::1]"]);
3
- function hostnameOfHost(host) {
4
- let hostname = host.trim().toLowerCase();
5
- if (hostname.startsWith("[")) {
6
- const end = hostname.indexOf("]");
7
- return end === -1 ? hostname : hostname.slice(0, end + 1);
8
- }
9
- const colon = hostname.lastIndexOf(":");
10
- if (colon !== -1 && !hostname.slice(0, colon).includes(":") && /^\d+$/.test(hostname.slice(colon + 1))) {
11
- hostname = hostname.slice(0, colon);
12
- }
13
- return hostname;
14
- }
15
- function hostIsLoopback(host) {
16
- if (host === void 0 || host.trim() === "") return false;
17
- return LOOPBACK_HOSTS.has(hostnameOfHost(host));
18
- }
19
- function originIsLoopback(origin) {
20
- if (origin === void 0 || origin.trim() === "") return true;
21
- try {
22
- const { hostname } = new URL(origin);
23
- return LOOPBACK_HOSTS.has(hostname) || hostname === "::1";
24
- } catch {
25
- return false;
26
- }
27
- }
28
-
29
- export {
30
- hostIsLoopback,
31
- originIsLoopback
32
- };
33
- //# sourceMappingURL=chunk-DNQPZMPF.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../upstream/workbuddy/src/loopback.ts"],
4
- "sourcesContent": ["/**\n * Shared loopback gates for the plugin's local HTTP surfaces: the loopback\n * shim and the same-origin web-status route. Both are only ever meant to be\n * addressed through the machine's loopback interface.\n *\n * @module dsh-workbuddy-connect/loopback\n */\n\n/** Loopback hostnames a local plugin surface may be addressed by. */\nexport const LOOPBACK_HOSTS = new Set(['127.0.0.1', 'localhost', '[::1]'])\n\n/** Strip the optional :port from a Host header value, IPv6-bracket aware. */\nexport function hostnameOfHost(host: string): string {\n let hostname = host.trim().toLowerCase()\n if (hostname.startsWith('[')) {\n const end = hostname.indexOf(']')\n return end === -1 ? hostname : hostname.slice(0, end + 1)\n }\n // Only `name:port` with a single colon is a port; anything with more colons\n // is an (unbracketed) IPv6 literal and must not be truncated.\n const colon = hostname.lastIndexOf(':')\n if (colon !== -1 && !hostname.slice(0, colon).includes(':') && /^\\d+$/.test(hostname.slice(colon + 1))) {\n hostname = hostname.slice(0, colon)\n }\n return hostname\n}\n\n/**\n * The request's Host header must name the loopback interface. A DNS-rebinding\n * page (attacker domain re-resolved to 127.0.0.1) sends its own domain in\n * Host, so this check drops those before any routing happens.\n */\nexport function hostIsLoopback(host: string | undefined): boolean {\n if (host === undefined || host.trim() === '') return false\n return LOOPBACK_HOSTS.has(hostnameOfHost(host))\n}\n\n/**\n * A browser-sent Origin (present header) must be loopback. Non-browser\n * clients (the plugin's own fetch calls) send no Origin at all and pass.\n */\nexport function originIsLoopback(origin: string | undefined): boolean {\n if (origin === undefined || origin.trim() === '') return true\n try {\n const { hostname } = new URL(origin)\n return LOOPBACK_HOSTS.has(hostname) || hostname === '::1'\n } catch {\n return false\n }\n}\n"],
5
- "mappings": ";AASO,IAAM,iBAAiB,oBAAI,IAAI,CAAC,aAAa,aAAa,OAAO,CAAC;AAGlE,SAAS,eAAe,MAAsB;AACnD,MAAI,WAAW,KAAK,KAAK,EAAE,YAAY;AACvC,MAAI,SAAS,WAAW,GAAG,GAAG;AAC5B,UAAM,MAAM,SAAS,QAAQ,GAAG;AAChC,WAAO,QAAQ,KAAK,WAAW,SAAS,MAAM,GAAG,MAAM,CAAC;AAAA,EAC1D;AAGA,QAAM,QAAQ,SAAS,YAAY,GAAG;AACtC,MAAI,UAAU,MAAM,CAAC,SAAS,MAAM,GAAG,KAAK,EAAE,SAAS,GAAG,KAAK,QAAQ,KAAK,SAAS,MAAM,QAAQ,CAAC,CAAC,GAAG;AACtG,eAAW,SAAS,MAAM,GAAG,KAAK;AAAA,EACpC;AACA,SAAO;AACT;AAOO,SAAS,eAAe,MAAmC;AAChE,MAAI,SAAS,UAAa,KAAK,KAAK,MAAM,GAAI,QAAO;AACrD,SAAO,eAAe,IAAI,eAAe,IAAI,CAAC;AAChD;AAMO,SAAS,iBAAiB,QAAqC;AACpE,MAAI,WAAW,UAAa,OAAO,KAAK,MAAM,GAAI,QAAO;AACzD,MAAI;AACF,UAAM,EAAE,SAAS,IAAI,IAAI,IAAI,MAAM;AACnC,WAAO,eAAe,IAAI,QAAQ,KAAK,aAAa;AAAA,EACtD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;",
6
- "names": []
7
- }