@jeffusion/bungee-core 5.10.0 → 5.12.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.
- package/dist/main.js +31436 -17327
- package/dist/plugins/ai-transformer/index.js.map +2 -2
- package/dist/plugins/anthropic-request-sanitizer/index.js.map +2 -2
- package/dist/plugins/anthropic-tool-name-transformer/index.js.map +2 -2
- package/dist/plugins/chatgpt-oauth/control.js +850 -47
- package/dist/plugins/chatgpt-oauth/control.js.map +16 -7
- package/dist/plugins/chatgpt-oauth/index.js +691 -16
- package/dist/plugins/chatgpt-oauth/index.js.map +15 -7
- package/dist/plugins/chatgpt-oauth/manifest.json +117 -7
- package/dist/plugins/chatgpt-oauth/ui/AccountsPage.svelte +25 -15
- package/dist/plugins/chatgpt-oauth/ui/ChatgptQuotaWidget.svelte +7 -4
- package/dist/plugins/chatgpt-oauth/ui/account-model.js +16 -7
- package/dist/plugins/deepseek-reasoning-fix/index.js.map +2 -2
- package/dist/plugins/key-access/index.js.map +2 -2
- package/dist/plugins/key-rate-limit/index.js.map +2 -2
- package/dist/plugins/local-accounts/control.js.map +2 -2
- package/dist/plugins/local-accounts/index.js.map +2 -2
- package/dist/plugins/model-mapping/control.js +72 -17741
- package/dist/plugins/model-mapping/control.js.map +6 -58
- package/dist/plugins/model-mapping/index.js +32 -17433
- package/dist/plugins/model-mapping/index.js.map +6 -58
- package/dist/plugins/model-mapping/manifest.json +30 -14
- package/dist/plugins/models-dev/control.js +1042 -0
- package/dist/plugins/models-dev/control.js.map +16 -0
- package/dist/plugins/models-dev/index.js +15418 -0
- package/dist/plugins/models-dev/index.js.map +134 -0
- package/dist/plugins/models-dev/manifest.json +199 -0
- package/dist/plugins/models-dev/ui/ModelsDevSettings.svelte +120 -0
- package/dist/plugins/openai-messages-to-chat/index.js.map +2 -2
- package/dist/plugins/signature-repair/index.js.map +2 -2
- package/dist/plugins/token-budget/control.js +524 -9
- package/dist/plugins/token-budget/control.js.map +12 -4
- package/dist/plugins/token-budget/index.js +519 -12
- package/dist/plugins/token-budget/index.js.map +13 -6
- package/dist/plugins/token-budget/manifest.json +16 -2
- package/dist/plugins/token-metering/index.js +93 -2
- package/dist/plugins/token-metering/index.js.map +12 -6
- package/dist/plugins/token-stats/control.js +174 -312
- package/dist/plugins/token-stats/control.js.map +7 -7
- package/dist/plugins/token-stats/index.js +283 -486
- package/dist/plugins/token-stats/index.js.map +16 -12
- package/dist/plugins/token-stats/manifest.json +99 -12
- package/dist/plugins/token-stats/ui/ClientModelPicker.svelte +76 -0
- package/dist/plugins/token-stats/ui/PriceModelPicker.svelte +87 -0
- package/dist/plugins/token-stats/ui/TokenStatsSettings.svelte +136 -80
- package/dist/plugins/token-stats/ui/client-model-search.test.ts +58 -0
- package/dist/plugins/token-stats/ui/client-model-search.ts +16 -0
- package/dist/plugins/token-stats/ui/model-search.ts +45 -0
- package/dist/plugins/token-stats/ui/pricing-catalog.test.ts +114 -0
- package/dist/plugins/token-stats/ui/pricing-catalog.ts +17 -0
- package/package.json +2 -2
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../../src/token-stats-window.ts", "../../../../../plugins/token-stats/server/storage.ts", "../../../../../plugins/token-stats/server/
|
|
3
|
+
"sources": ["../../../../../plugins/models-dev/contract.ts", "../../../src/token-stats-window.ts", "../../../../../plugins/token-stats/server/storage.ts", "../../../../../plugins/token-stats/server/model-mappings.ts", "../../../../../plugins/token-stats/server/repository.ts", "../../../../../plugins/token-stats/server/control.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
+
"/**\n * Public contract of the models-dev catalog provider.\n *\n * This is the ONLY file other plugins may import from models-dev. It contains the\n * declared service identity, the wire-contract snapshot literal and the data types\n * of the read surface; it never exposes the downloader, the private storage keys or\n * the internal catalog representation.\n *\n * Consumers must declare a real dependency on `models-dev` and consume the local\n * service for their own process. The service methods are synchronous and read an\n * already-loaded in-memory view: no per-request network or SQL is performed.\n */\n\n/** Provider plugin name. Must match the manifest. */\nexport const MODELS_DEV_PLUGIN_NAME = 'models-dev';\n\n/** The single upstream source; models-dev is the only component allowed to fetch it. */\nexport const MODELS_DEV_SOURCE_URL = 'https://models.dev/api.json';\n\n/** Same-process local read service, published in both the control and worker processes. */\nexport const MODELS_DEV_CATALOG_SERVICE_ID = 'models-dev.catalog.v1';\nexport const MODELS_DEV_CATALOG_CONTRACT_VERSION = 1;\n\n/** Versioned immutable snapshot of the full catalog, published by the control writer. */\nexport const MODELS_DEV_CATALOG_SNAPSHOT_ID = 'models-dev.catalog.snapshot.v1';\nexport const MODELS_DEV_CATALOG_SNAPSHOT_CONTRACT_VERSION = 1;\n/**\n * One atomic record keeps fetchedAt and the immutable catalog with its version.\n * The catalog remains unrestricted JSON so every upstream field is preserved.\n */\nexport const MODELS_DEV_CATALOG_SNAPSHOT_SCHEMA = Object.freeze({\n type: 'object', properties: {\n version: { type: 'number', integer: true, minimum: 1 },\n fetchedAt: { type: 'number', minimum: 0 },\n catalog: { type: 'json', maxBytes: 32 * 1024 * 1024 },\n },\n} as const);\nexport const MODELS_DEV_CATALOG_SNAPSHOT_CONTRACT = Object.freeze({\n id: MODELS_DEV_CATALOG_SNAPSHOT_ID,\n version: MODELS_DEV_CATALOG_SNAPSHOT_CONTRACT_VERSION,\n content: MODELS_DEV_CATALOG_SNAPSHOT_SCHEMA,\n});\n\n/** Catalog availability is separate from whether the service is published. */\nexport type ModelsDevCatalogState = 'empty' | 'ready' | 'stale' | 'failed';\n\nexport interface ModelsDevCatalogStatus {\n readonly state: ModelsDevCatalogState;\n /** Monotonic published data version; `null` before the first successful load. */\n readonly version: number | null;\n readonly fetchedAt: number | null;\n readonly providerCount: number;\n readonly modelCount: number;\n /** Last failure reason; `null` after a fully successful load. */\n readonly error: string | null;\n}\n\nexport interface ModelsDevProviderSummary {\n readonly provider: string;\n readonly name: string;\n /** Normalized upstream API base (`provider.api`), or `null` when models.dev declares none. */\n readonly api: string | null;\n readonly modelCount: number;\n}\n\n/** One selectable catalog model. `provider` is the pricing provider, never the protocol. */\nexport interface ModelsDevModelOption {\n readonly provider: string;\n readonly providerName: string;\n readonly model: string;\n readonly name: string;\n}\n\nexport interface ModelsDevModelPage {\n readonly models: readonly ModelsDevModelOption[];\n readonly total: number;\n /** 1-based page actually returned. */\n readonly page: number;\n readonly pageSize: number;\n}\n\n/** USD per million tokens, applied to the whole request at this input threshold. */\nexport interface ModelsDevContextTier {\n readonly minimumInputTokens: number;\n readonly input: number;\n readonly output: number;\n readonly cacheRead: number | null;\n readonly cacheWrite: number | null;\n}\n\n/** A resolved catalog entry with optional ascending context price bands. */\nexport interface ModelsDevModelMatch {\n readonly provider: string;\n readonly model: string;\n readonly input: number;\n readonly output: number;\n readonly cacheRead: number | null;\n readonly cacheWrite: number | null;\n readonly tiered: boolean;\n readonly contextTiers?: readonly ModelsDevContextTier[];\n}\n\nexport interface ModelsDevProviderMatch {\n readonly provider: string;\n}\n\n/**\n * The declared local read surface. Implementations must be side-effect free and\n * must never throw for a miss/corruption of the current view: an unavailable\n * catalog returns an `empty`/`failed` status instead of a fabricated price.\n */\nexport interface ModelsDevCatalogService {\n status(): ModelsDevCatalogStatus;\n providers(): readonly ModelsDevProviderSummary[];\n modelOptions(input?: { readonly provider?: string; readonly search?: string; readonly page?: number; readonly pageSize?: number }): ModelsDevModelPage;\n /**\n * Resolve exactly one catalog entry for a client model name.\n *\n * `url` (when supplied) is canonicalized to host + path and matched against the\n * full catalog's `provider.api`; more than one candidate is ambiguous and returns\n * null. `pricingProvider` is a catalog provider id and takes priority over URL and\n * prefix inference. A model id present under several providers without an explicit\n * provider is ambiguous. Matching defaults to exact and case-sensitive.\n * `estimate` additionally permits normalized names, original-lab prices and\n * dated members of the same family. Explicit provider IDs remain binding;\n * an unresolved URL is only a hint in estimate mode.\n */\n resolveModel(input: { readonly model: string; readonly pricingProvider?: string; readonly url?: string; readonly mode?: 'exact' | 'estimate' }): ModelsDevModelMatch | null;\n /** Resolve one provider from a real upstream URL via `provider.api`; ambiguous/none => null. */\n resolveProvider(input: { readonly url: string }): ModelsDevProviderMatch | null;\n}\n",
|
|
5
6
|
"import type { TokenStatsRange } from './plugin.types';\n\nconst HOUR = 3_600_000;\nexport const TOKEN_STATS_RETENTION_MS = 31 * 24 * HOUR;\nexport const TOKEN_STATS_RANGES = ['1h', '12h', '24h', '1d', '7d', '30d', 'day', 'week', 'month'] as const;\n\n/** Recent page ranges are consecutive elapsed hours; calendar ranges use local dates. */\nexport function tokenStatsWindow(range: TokenStatsRange, asOfMs: number, timeZone = 'UTC') {\n if (range === '1h' || range === '12h' || range === '24h') {\n const duration = { '1h': HOUR, '12h': 12 * HOUR, '24h': 24 * HOUR };\n const bucketMs = { '1h': 300_000, '12h': HOUR, '24h': 2 * HOUR }[range];\n return { startMs: asOfMs - duration[range], endMs: asOfMs, bucketMs };\n }\n if (range === '1d' || range === '7d' || range === '30d') {\n const days = { '1d': 1, '7d': 7, '30d': 30 }[range];\n const bucketMs = range === '1d' ? HOUR : 24 * HOUR;\n const startMs = asOfMs - days * 24 * HOUR;\n const bucketStarts = Array.from({ length: range === '1d' ? 24 : days }, (_, i) => startMs + i * bucketMs);\n return { startMs, endMs: asOfMs, bucketMs, bucketStarts };\n }\n const format = new Intl.DateTimeFormat('en-US', {\n timeZone, year: 'numeric', month: 'numeric', day: 'numeric',\n hour: 'numeric', minute: 'numeric', second: 'numeric', hourCycle: 'h23',\n });\n const parts = (ms: number) => Object.fromEntries(format.formatToParts(ms)\n .filter(part => part.type !== 'literal').map(part => [part.type, Number(part.value)]));\n const today = parts(asOfMs);\n const day = Date.UTC(today.year!, today.month! - 1, today.day!);\n // Resolve each local midnight separately so DST days can contain 23 or 25 hours.\n const midnight = (date: number) => {\n let candidate = date;\n for (let i = 0; i < 4; i++) {\n const p = parts(candidate);\n const local = Date.UTC(p.year!, p.month! - 1, p.day!, p.hour!, p.minute!, p.second!);\n const next = candidate + date - local;\n if (next === candidate) return candidate;\n candidate = next;\n }\n return candidate;\n };\n if (range === 'day') {\n const startMs = midnight(day);\n const bucketEndMs = midnight(day + 24 * HOUR);\n const bucketStarts = Array.from({ length: Math.ceil((bucketEndMs - startMs) / HOUR) }, (_, i) => startMs + i * HOUR);\n return { startMs, endMs: asOfMs, bucketMs: HOUR, bucketStarts, bucketEndMs };\n }\n const firstDay = range === 'month' ? Date.UTC(today.year!, today.month! - 1, 1)\n : day - ((new Date(day).getUTCDay() + 6) % 7) * 24 * HOUR;\n const nextPeriod = range === 'month' ? Date.UTC(today.year!, today.month!, 1) : firstDay + 7 * 24 * HOUR;\n const days = (nextPeriod - firstDay) / (24 * HOUR);\n const bucketStarts = Array.from({ length: days }, (_, i) => midnight(firstDay + i * 24 * HOUR));\n return { startMs: bucketStarts[0]!, endMs: asOfMs, bucketMs: 24 * HOUR, bucketStarts, bucketEndMs: midnight(nextPeriod) };\n}\n",
|
|
6
7
|
"import type { Database } from 'bun:sqlite';\nimport type { PluginStorage, PluginObservationStorage, TokenStatsAttempt, TokenStatsGroupBy, TokenStatsMeteringStorage,\n TokenStatsMetricName, TokenStatsSnapshotMetrics, TokenStatsValueSource, TokenStatsRange } from '../../../packages/core/src/plugin.types';\nimport { TOKEN_STATS_RETENTION_MS, TOKEN_STATS_RANGES, tokenStatsWindow } from '../../../packages/core/src/token-stats-window';\n\n/** Explicit assembly for legacy fixtures and embedders; the host never checks a business name. */\nexport function withTokenStatsMetering<T extends PluginStorage>(storage: T): T & { metering: TokenStatsMeteringStorage } {\n if (!storage.observation) throw new Error('token-stats metering storage is required');\n return Object.assign(storage, { metering: new SQLiteTokenStatsMetering(storage.observation) });\n}\n\nconst TOKEN_STATS_METRICS: readonly TokenStatsMetricName[] = [\n 'inputTokens', 'outputTokens', 'officialInputTokens', 'officialOutputTokens',\n 'estimatedInputTokens', 'estimatedOutputTokens', 'cacheReadTokens', 'cacheWriteTokens',\n 'partialOutputs', 'logicalRequests', 'upstreamAttempts', 'observationIncompleteAttempts',\n 'inputAuthorityOfficial', 'inputAuthorityLocal', 'inputAuthorityHeuristic', 'inputAuthorityPartial', 'inputAuthorityNone',\n 'outputAuthorityOfficial', 'outputAuthorityLocal', 'outputAuthorityHeuristic', 'outputAuthorityPartial', 'outputAuthorityNone',\n];\nconst TOKEN_STATS_MAX_FUTURE_SKEW_MS = 5 * 60 * 1000;\nconst TOKEN_STATS_BUSY_TIMEOUT_MS = 5;\n\nconst EMPTY_METRICS: Record<TokenStatsMetricName, number> = Object.fromEntries(\n TOKEN_STATS_METRICS.map((name) => [name, 0]),\n) as Record<TokenStatsMetricName, number>;\n\nexport class SQLiteTokenStatsMetering implements TokenStatsMeteringStorage {\n constructor(private readonly observation: PluginObservationStorage) {}\n\n async recordAttempt(row: TokenStatsAttempt): Promise<void> {\n return this.observation.withDatabase((db) => {\n validateTokenStatsAttempt(row);\n const transaction = db.transaction(() => {\n db.query(`\n INSERT OR IGNORE INTO token_stats_attempts (\n attempt_id, request_id, finished_at_ms, route_id, upstream_id, provider, outcome, model, key_id,\n input_tokens, output_tokens, input_source, output_source,\n cache_read_tokens, cache_write_tokens, cost_usd, observation_incomplete\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `).run(\n row.attempt_id, row.request_id, row.finished_at_ms, row.route_id, row.upstream_id, row.provider,\n row.outcome, row.model, row.key_id ?? null, row.input_tokens, row.output_tokens, row.input_source, row.output_source,\n row.cache_read_tokens, row.cache_write_tokens, row.cost_usd, row.observation_incomplete ? 1 : 0,\n );\n // A fixed one-batch cleanup keeps the write transaction bounded.\n db.query(`\n DELETE FROM token_stats_attempts WHERE attempt_id IN (\n SELECT attempt_id FROM token_stats_attempts INDEXED BY idx_token_stats_attempts_finished\n WHERE finished_at_ms < ? ORDER BY finished_at_ms LIMIT 500\n )\n `).run(Date.now() - TOKEN_STATS_RETENTION_MS);\n });\n withReportingWriteTimeout(db, () => transaction.immediate());\n });\n }\n\n async queryWindowSnapshot(input: {\n asOfMs: number;\n range: TokenStatsRange;\n groupBy: TokenStatsGroupBy;\n timeZone?: string;\n keyId?: string;\n }): Promise<{\n all: TokenStatsSnapshotMetrics;\n data: Array<{ dimension: string; bucketStartMs?: number; metrics: TokenStatsSnapshotMetrics }>;\n bucketMs?: number;\n bucketStarts?: number[];\n bucketEndMs?: number;\n present: boolean;\n }> {\n return this.observation.withDatabase((db) => {\n validateTokenStatsTimestamp(input.asOfMs, 'asOfMs');\n if (!(TOKEN_STATS_RANGES as readonly string[]).includes(input.range)) throw new Error('invalid token-stats range');\n if (!['model', 'time'].includes(input.groupBy)) throw new Error('invalid token-stats groupBy');\n const window = tokenStatsWindow(input.range, input.asOfMs, input.timeZone);\n const startMs = Math.max(window.startMs, Date.now() - TOKEN_STATS_RETENTION_MS);\n const bucketMs = input.groupBy === 'time' ? window.bucketMs : undefined;\n const bucketStarts = input.groupBy === 'time' ? window.bucketStarts : undefined;\n const bucketEndMs = input.groupBy === 'time' ? window.bucketEndMs : undefined;\n const { sql, params } = buildTokenStatsWindowSnapshotQuery({ ...window, startMs, groupBy: input.groupBy, bucketMs, bucketStarts, keyId: input.keyId });\n const rows = db.query<Record<string, number | string | null>, (number | string)[]>(sql).all(...params);\n const allRow = rows.find((row) => row.kind === 'all');\n const dataRows = rows.filter((row) => row.kind === 'data');\n const metrics = (row: Record<string, number | string | null> | undefined): TokenStatsSnapshotMetrics => {\n const base = !row ? { ...EMPTY_METRICS } : Object.fromEntries(TOKEN_STATS_METRICS.map((key) => {\n const value = Number(row[key] ?? 0);\n if (!Number.isSafeInteger(value) || value < 0) throw new RangeError(`invalid token-stats aggregate: ${key}`);\n return [key, value];\n })) as Record<TokenStatsMetricName, number>;\n const rawCost = row?.estimatedCostUsd;\n const estimatedCostUsd = rawCost === undefined || rawCost === null ? null : Number(rawCost);\n if (estimatedCostUsd !== null && (!Number.isFinite(estimatedCostUsd) || estimatedCostUsd < 0)) {\n throw new RangeError('invalid token-stats aggregate: estimatedCostUsd');\n }\n return { ...base, estimatedCostUsd };\n };\n return {\n all: metrics(allRow),\n data: dataRows.map((row) => ({\n dimension: String(row.dimension),\n ...(input.groupBy === 'time' ? { bucketStartMs: Number(row.bucketStartMs) } : {}),\n metrics: metrics(row),\n })),\n ...(bucketMs === undefined ? {} : { bucketMs }),\n ...(bucketStarts === undefined ? {} : { bucketStarts }),\n ...(bucketEndMs === undefined ? {} : { bucketEndMs }),\n present: Number(allRow?.present ?? 0) === 1,\n };\n });\n }\n}\n\nexport function buildTokenStatsWindowSnapshotQuery(input: {\n startMs: number;\n endMs: number;\n groupBy: TokenStatsGroupBy;\n bucketMs?: number;\n bucketStarts?: readonly number[];\n keyId?: string;\n}): { sql: string; params: (number | string)[] } {\n const metrics = (alias: string) => `\n COALESCE(SUM(CASE WHEN ${alias}.input_source = 'usage' THEN ${alias}.input_tokens ELSE 0 END), 0) AS officialInputTokens,\n COALESCE(SUM(CASE WHEN ${alias}.output_source = 'usage' THEN ${alias}.output_tokens ELSE 0 END), 0) AS officialOutputTokens,\n COALESCE(SUM(CASE WHEN ${alias}.input_source IN ('estimated', 'partial') THEN ${alias}.input_tokens ELSE 0 END), 0) AS estimatedInputTokens,\n COALESCE(SUM(CASE WHEN ${alias}.output_source IN ('estimated', 'partial') THEN ${alias}.output_tokens ELSE 0 END), 0) AS estimatedOutputTokens,\n COALESCE(SUM(CASE WHEN ${alias}.input_source IN ('usage', 'estimated', 'partial') THEN ${alias}.input_tokens ELSE 0 END), 0) AS inputTokens,\n COALESCE(SUM(CASE WHEN ${alias}.output_source IN ('usage', 'estimated', 'partial') THEN ${alias}.output_tokens ELSE 0 END), 0) AS outputTokens,\n COALESCE(SUM(${alias}.cache_read_tokens), 0) AS cacheReadTokens,\n COALESCE(SUM(${alias}.cache_write_tokens), 0) AS cacheWriteTokens,\n SUM(${alias}.cost_usd) AS estimatedCostUsd,\n SUM(CASE WHEN ${alias}.observation_incomplete = 1 AND ${alias}.output_source = 'usage' THEN 1 ELSE 0 END) AS partialOutputs,\n COUNT(DISTINCT ${alias}.request_id) AS logicalRequests,\n COUNT(*) AS upstreamAttempts,\n SUM(${alias}.observation_incomplete) AS observationIncompleteAttempts,\n SUM(${alias}.input_source = 'usage') AS inputAuthorityOfficial,\n 0 AS inputAuthorityLocal, SUM(${alias}.input_source = 'estimated') AS inputAuthorityHeuristic,\n SUM(${alias}.input_source = 'partial') AS inputAuthorityPartial, SUM(${alias}.input_source = 'unknown') AS inputAuthorityNone,\n SUM(${alias}.output_source = 'usage') AS outputAuthorityOfficial,\n 0 AS outputAuthorityLocal, SUM(${alias}.output_source = 'estimated') AS outputAuthorityHeuristic,\n SUM(${alias}.output_source = 'partial') AS outputAuthorityPartial, SUM(${alias}.output_source = 'unknown') AS outputAuthorityNone`;\n if (input.groupBy === 'time' && (!Number.isSafeInteger(input.bucketMs) || input.bucketMs! <= 0)) {\n throw new Error('invalid token-stats bucketMs');\n }\n if (input.bucketStarts && (!input.bucketStarts.length || input.bucketStarts.length > 31\n || input.bucketStarts.some((start, i, starts) => !Number.isSafeInteger(start) || start < 0 || i > 0 && start <= starts[i - 1]!))) {\n throw new Error('invalid token-stats bucketStarts');\n }\n if (input.keyId !== undefined && (typeof input.keyId !== 'string' || !input.keyId || input.keyId.length > 128)) throw new Error('invalid token-stats keyId');\n const keyFilter = input.keyId === undefined ? '' : input.keyId === '__unattributed__' ? ' AND key_id IS NULL' : ' AND key_id = ?';\n const index = input.keyId === undefined ? 'idx_token_stats_attempts_finished' : 'idx_token_stats_attempts_key_finished';\n const origin = input.bucketStarts?.[0] ?? 0;\n const uniform = !input.bucketStarts || input.bucketStarts.every((start, i) => start === origin + i * input.bucketMs!);\n const bucketStart = input.groupBy !== 'time' ? 'NULL' : uniform\n ? `CAST((attempt.finished_at_ms - ${origin}) / ${input.bucketMs} AS INTEGER) * ${input.bucketMs} + ${origin}`\n : `CASE ${[...input.bucketStarts!].reverse().map(start => `WHEN attempt.finished_at_ms >= ${start} THEN ${start}`).join(' ')} END`;\n const groupColumns = input.groupBy === 'time' ? `attempt.model, bucketStartMs` : 'attempt.model';\n const grouped = `\n UNION ALL\n SELECT 'data' AS kind, attempt.model AS dimension, ${bucketStart} AS bucketStartMs, ${metrics('attempt')}, 0 AS present\n FROM window_rows AS attempt GROUP BY ${groupColumns}`;\n return {\n sql: `\n WITH window_rows AS MATERIALIZED (\n SELECT * FROM token_stats_attempts INDEXED BY ${index}\n WHERE finished_at_ms >= ? AND finished_at_ms < ?${keyFilter}\n )\n SELECT 'all' AS kind, 'all' AS dimension, NULL AS bucketStartMs, ${metrics('attempt')}, (COUNT(*) > 0) AS present\n FROM window_rows AS attempt\n ${grouped}\n ORDER BY kind, bucketStartMs, dimension\n `,\n params: [input.startMs, input.endMs, ...(input.keyId !== undefined && input.keyId !== '__unattributed__' ? [input.keyId] : [])],\n };\n}\n\nfunction validateTokenStatsAttempt(row: TokenStatsAttempt): void {\n if (!row || typeof row !== 'object' || Array.isArray(row)) throw new Error('invalid token-stats attempt');\n for (const key of ['attempt_id', 'request_id', 'route_id', 'upstream_id', 'provider', 'outcome', 'model'] as const) {\n if (typeof row[key] !== 'string' || row[key].length === 0) throw new Error(`invalid token-stats ${key}`);\n }\n if (row.key_id != null && (typeof row.key_id !== 'string' || !row.key_id || row.key_id.length > 128)) throw new Error('invalid token-stats key_id');\n validateTokenStatsTimestamp(row.finished_at_ms, 'finished_at_ms');\n for (const [key, value] of [\n ['input_tokens', row.input_tokens], ['output_tokens', row.output_tokens],\n ['cache_read_tokens', row.cache_read_tokens], ['cache_write_tokens', row.cache_write_tokens],\n ] as const) {\n if (value !== null && (!Number.isSafeInteger(value) || value < 0)) throw new Error(`invalid token-stats ${key}`);\n }\n if (row.cost_usd !== null && (!Number.isFinite(row.cost_usd) || row.cost_usd < 0)) throw new Error('invalid token-stats cost_usd');\n if (!isTokenStatsSource(row.input_source) || !isTokenStatsSource(row.output_source)) throw new Error('invalid token-stats value source');\n if (typeof row.observation_incomplete !== 'boolean') throw new Error('invalid token-stats observation_incomplete');\n if ((row.input_source === 'unknown') !== (row.input_tokens === null)\n || (row.output_source === 'unknown') !== (row.output_tokens === null)) throw new Error('token-stats value/source mismatch');\n}\n\nfunction isTokenStatsSource(value: unknown): value is TokenStatsValueSource {\n return value === 'usage' || value === 'estimated' || value === 'partial' || value === 'unknown';\n}\n\nfunction validateTokenStatsTimestamp(value: number, name: string): void {\n if (!Number.isSafeInteger(value) || value < 0) throw new Error(`invalid token-stats ${name}`);\n const now = Date.now();\n if (value < now - TOKEN_STATS_RETENTION_MS) throw new RangeError(`token-stats ${name} exceeds 31-day retention`);\n if (value > now + TOKEN_STATS_MAX_FUTURE_SKEW_MS) throw new RangeError(`token-stats ${name} is too far in the future`);\n}\n\n\n/** Reporting writes have a short lock deadline and never retain a changed connection pragma. */\nexport function withReportingWriteTimeout<T>(db: Database, operation: () => T): T {\n const busyTimeout = db.query<{ timeout: number }, []>('PRAGMA busy_timeout').get()?.timeout;\n if (!Number.isSafeInteger(busyTimeout) || busyTimeout! < 0) throw new Error('unable to read SQLite busy_timeout');\n try {\n db.run(`PRAGMA busy_timeout = ${TOKEN_STATS_BUSY_TIMEOUT_MS}`);\n return operation();\n } finally {\n db.run(`PRAGMA busy_timeout = ${busyTimeout}`);\n }\n}\n",
|
|
7
|
-
"import type {\n PluginStorage,\n TokenStatsAttempt,\n TokenStatsMetricName,\n TokenStatsMeteringStorage,\n TokenStatsSnapshotMetrics,\n TokenStatsRange,\n} from '../../../packages/core/src/plugin.types';\nimport type { CanonicalTokenAccountingEventV2 } from '@jeffusion/bungee-llms/plugin-api';\n// The control artifact needs only authority names, not the worker conversion runtime.\nconst TOKEN_ACCOUNTING_AUTHORITIES = ['official', 'local', 'heuristic', 'partial', 'none'] as const satisfies readonly CanonicalTokenAccountingEventV2['inputAuthority'][];\nimport { SQLiteTokenStatsMetering } from './storage';\nimport { TOKEN_STATS_RANGES } from '../../../packages/core/src/token-stats-window';\n\nexport type GroupByDimension = 'model' | 'time';\ntype TokenAccountingAuthority = typeof TOKEN_ACCOUNTING_AUTHORITIES[number];\nexport type CanonicalEvent = CanonicalTokenAccountingEventV2;\n\nexport interface AuthorityBreakdownDto {\n input: Record<TokenAccountingAuthority, number>;\n output: Record<TokenAccountingAuthority, number>;\n}\n\nexport interface GroupedAggregateDto {\n dimension: string;\n bucketStartMs?: number;\n inputTokens: number;\n outputTokens: number;\n officialInputTokens: number;\n officialOutputTokens: number;\n estimatedInputTokens: number;\n estimatedOutputTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n partialOutputs: number;\n logicalRequests: number;\n upstreamAttempts: number;\n observationIncompleteAttempts: number;\n estimatedCostUsd: number | null;\n authorityBreakdown: AuthorityBreakdownDto;\n}\n\nexport interface AggregateDto extends Omit<GroupedAggregateDto, 'dimension' | 'bucketStartMs' | 'inputTokens' | 'outputTokens'> {\n /** Sticky evidence of dropped or failed reporting, shared across worker/control processes. */\n reportingIncomplete: boolean;\n groupBy: GroupByDimension;\n asOfMs: number;\n bucketMs?: number;\n bucketStarts?: number[];\n bucketEndMs?: number;\n totalInputTokens: number;\n totalOutputTokens: number;\n data: GroupedAggregateDto[];\n}\n\nexport class TokenStatsRepositoryError extends Error {\n constructor(message: string) { super(message); this.name = 'TokenStatsRepositoryError'; }\n}\n\nexport class TokenStatsRepositoryLimitError extends TokenStatsRepositoryError {}\n\nexport const REPORTING_INCOMPLETE_KEY = 'reporting:incomplete';\n\ntype MeteringLogger = { onFailure?(): void; warn(message: string, metadata?: object): void; error(message: string, metadata?: object): void };\ntype AttemptTask = () => TokenStatsAttempt | undefined | Promise<TokenStatsAttempt | undefined>;\ntype QueuedAttempt = { metering: TokenStatsMeteringStorage; task: AttemptTask; logger: MeteringLogger };\n\nconst MAX_PENDING_ATTEMPTS = 256;\nconst LOG_INTERVAL_MS = 60_000;\nconst pendingAttempts: QueuedAttempt[] = [];\nlet pendingCount = 0;\nlet drainTimer: ReturnType<typeof setTimeout> | undefined;\nlet draining = false;\nlet lastDropLogAt = 0;\nlet lastFailureLogAt = 0;\n\nfunction logRateLimited(logger: MeteringLogger, kind: 'drop' | 'failure', error?: unknown): void {\n try { logger.onFailure?.(); } catch { /* failure reporting must not affect proxy flow */ }\n const now = Date.now();\n if (kind === 'drop') {\n if (now - lastDropLogAt < LOG_INTERVAL_MS) return;\n lastDropLogAt = now;\n try { logger.warn('Token stats attempt queue full; dropping metering rows', { capacity: MAX_PENDING_ATTEMPTS }); } catch { /* logging must not affect proxy flow */ }\n return;\n }\n if (now - lastFailureLogAt < LOG_INTERVAL_MS) return;\n lastFailureLogAt = now;\n try {\n logger.error('Token stats attempt processing failed; dropping metering row', {\n error: error instanceof Error ? error.message : error === undefined ? 'attempt task returned no row' : String(error),\n });\n } catch { /* logging must not affect proxy flow */ }\n}\n\nfunction scheduleDrain(): void {\n if (drainTimer !== undefined || draining) return;\n drainTimer = setTimeout(() => { drainTimer = undefined; void drainOneAttempt(); }, 0);\n}\n\nasync function drainOneAttempt(): Promise<void> {\n if (draining) return;\n const item = pendingAttempts.shift();\n if (!item) return;\n draining = true;\n try {\n try {\n const row = await item.task();\n if (row === undefined) {\n logRateLimited(item.logger, 'failure');\n } else {\n await item.metering.recordAttempt(row);\n }\n } catch (error) {\n logRateLimited(item.logger, 'failure', error);\n }\n } finally {\n pendingCount--;\n draining = false;\n if (pendingAttempts.length) scheduleDrain();\n }\n}\n\nconst METRIC_FIELDS: readonly TokenStatsMetricName[] = [\n 'inputTokens', 'outputTokens', 'officialInputTokens', 'officialOutputTokens',\n 'estimatedInputTokens', 'estimatedOutputTokens', 'cacheReadTokens', 'cacheWriteTokens',\n 'partialOutputs', 'logicalRequests', 'upstreamAttempts', 'observationIncompleteAttempts',\n 'inputAuthorityOfficial', 'inputAuthorityLocal', 'inputAuthorityHeuristic', 'inputAuthorityPartial', 'inputAuthorityNone',\n 'outputAuthorityOfficial', 'outputAuthorityLocal', 'outputAuthorityHeuristic', 'outputAuthorityPartial', 'outputAuthorityNone',\n];\n\nfunction emptyMetrics(): TokenStatsSnapshotMetrics {\n return { ...Object.fromEntries(METRIC_FIELDS.map((key) => [key, 0])) as Record<TokenStatsMetricName, number>, estimatedCostUsd: null };\n}\n\nfunction emptyAuthorityBreakdown(): AuthorityBreakdownDto {\n const empty = () => Object.fromEntries(TOKEN_ACCOUNTING_AUTHORITIES.map((authority) => [authority, 0])) as Record<TokenAccountingAuthority, number>;\n return { input: empty(), output: empty() };\n}\n\nfunction metricsToDto(metrics: TokenStatsSnapshotMetrics): Omit<GroupedAggregateDto, 'dimension'> {\n const authorityBreakdown = emptyAuthorityBreakdown();\n for (const authority of TOKEN_ACCOUNTING_AUTHORITIES) {\n authorityBreakdown.input[authority] = metrics[`inputAuthority${authority[0]!.toUpperCase()}${authority.slice(1)}` as TokenStatsMetricName];\n authorityBreakdown.output[authority] = metrics[`outputAuthority${authority[0]!.toUpperCase()}${authority.slice(1)}` as TokenStatsMetricName];\n }\n return {\n inputTokens: metrics.inputTokens,\n outputTokens: metrics.outputTokens,\n officialInputTokens: metrics.officialInputTokens,\n officialOutputTokens: metrics.officialOutputTokens,\n estimatedInputTokens: metrics.estimatedInputTokens,\n estimatedOutputTokens: metrics.estimatedOutputTokens,\n cacheReadTokens: metrics.cacheReadTokens,\n cacheWriteTokens: metrics.cacheWriteTokens,\n partialOutputs: metrics.partialOutputs,\n logicalRequests: metrics.logicalRequests,\n upstreamAttempts: metrics.upstreamAttempts,\n observationIncompleteAttempts: metrics.observationIncompleteAttempts,\n estimatedCostUsd: metrics.estimatedCostUsd,\n authorityBreakdown,\n };\n}\n\nfunction sourceFor(value: number | undefined, authority: CanonicalTokenAccountingEventV2['inputAuthority']): TokenStatsAttempt['input_source'] {\n if (!Number.isSafeInteger(value) || value! < 0) return 'unknown';\n if (authority === 'official') return 'usage';\n if (authority === 'partial') return 'partial';\n return authority === 'none' ? 'unknown' : 'estimated';\n}\n\nexport function attemptRowFromEvent(\n event: CanonicalEvent,\n finishedAtMs: number,\n observationIncomplete: boolean,\n model: string,\n): TokenStatsAttempt {\n const inputSource = sourceFor(event.inputTokens, event.inputAuthority);\n const outputSource = sourceFor(event.outputTokens, event.outputAuthority);\n return {\n attempt_id: event.attemptId,\n request_id: event.requestId,\n finished_at_ms: finishedAtMs,\n route_id: event.routeId || 'unknown',\n upstream_id: event.upstreamId || 'unknown',\n provider: event.provider || 'unknown',\n outcome: event.outcome,\n model,\n input_tokens: inputSource === 'unknown' ? null : event.inputTokens!,\n output_tokens: outputSource === 'unknown' ? null : event.outputTokens!,\n input_source: inputSource,\n output_source: outputSource,\n cache_read_tokens: Number.isSafeInteger(event.cacheReadTokens) && event.cacheReadTokens! >= 0 ? event.cacheReadTokens! : null,\n cache_write_tokens: Number.isSafeInteger(event.cacheWriteTokens) && event.cacheWriteTokens! >= 0 ? event.cacheWriteTokens! : null,\n cost_usd: null,\n observation_incomplete: observationIncomplete,\n };\n}\n\nexport class TokenStatsRepository {\n private readonly metering: TokenStatsMeteringStorage;\n\n constructor(private readonly storage: PluginStorage) {\n if (!storage.metering && !storage.observation) throw new TokenStatsRepositoryError('token-stats metering storage is required');\n this.metering = storage.metering ?? new SQLiteTokenStatsMetering(storage.observation!);\n }\n\n /** Defers synchronous task work to drain; a task can still occupy the EventLoop. */\n enqueueAttempt(task: AttemptTask, logger: MeteringLogger): boolean {\n if (pendingCount >= MAX_PENDING_ATTEMPTS) {\n logRateLimited(logger, 'drop');\n return false;\n }\n pendingAttempts.push({ metering: this.metering, task, logger });\n pendingCount++;\n scheduleDrain();\n return true;\n }\n\n async query(range: string, groupBy: GroupByDimension, asOfMs = Date.now(), timeZone?: string, keyId?: string): Promise<AggregateDto> {\n if (!(TOKEN_STATS_RANGES as readonly string[]).includes(range)) throw new TokenStatsRepositoryError('invalid token-stats range');\n if (groupBy !== 'model' && groupBy !== 'time') {\n throw new TokenStatsRepositoryError('invalid token-stats groupBy');\n }\n if (!Number.isSafeInteger(asOfMs) || asOfMs < 0) throw new TokenStatsRepositoryError('invalid token-stats asOfMs');\n const snapshot = await this.metering.queryWindowSnapshot({ asOfMs, range: range as TokenStatsRange, groupBy, timeZone, keyId });\n const total = metricsToDto(snapshot.all);\n const { inputTokens, outputTokens, ...summary } = total;\n return {\n reportingIncomplete: await (this.storage.uncached?.() ?? this.storage).get(REPORTING_INCOMPLETE_KEY) === true,\n groupBy,\n asOfMs,\n ...summary,\n totalInputTokens: inputTokens,\n totalOutputTokens: outputTokens,\n ...(snapshot.bucketMs === undefined ? {} : { bucketMs: snapshot.bucketMs }),\n ...(snapshot.bucketStarts === undefined ? {} : { bucketStarts: snapshot.bucketStarts }),\n ...(snapshot.bucketEndMs === undefined ? {} : { bucketEndMs: snapshot.bucketEndMs }),\n data: snapshot.data.map((row) => ({\n dimension: row.dimension,\n ...(row.bucketStartMs === undefined ? {} : { bucketStartMs: row.bucketStartMs }),\n ...metricsToDto(row.metrics),\n })).sort(groupBy === 'model'\n ? (a, b) => b.inputTokens + b.outputTokens - a.inputTokens - a.outputTokens\n || b.upstreamAttempts - a.upstreamAttempts || a.dimension.localeCompare(b.dimension)\n : (a, b) => a.bucketStartMs! - b.bucketStartMs! || a.dimension.localeCompare(b.dimension)),\n };\n }\n}\n",
|
|
8
|
-
"/**\n * Thin async client for the models.dev API (https://models.dev/api.json).\n *\n * - Defaults to returning the full JSON catalog.\n * - Optionally filter by `provider` (e.g. \"deepseek\", \"vercel\") and/or `model` (e.g. \"gpt-4o\").\n * - No runtime dependencies. Uses `globalThis.fetch` if available, or accept a custom `fetch` via options.\n *\n * Note: This returns the raw models.dev schema as-is. Any higher-level formatting can be layered on later.\n */\nexport { getModelMeta } from \"@tokenlens/core\";\n/** Coded error for better ergonomics in consumers */\nexport class FetchModelsError extends Error {\n code;\n status;\n constructor(opts) {\n super(opts.message);\n this.name = \"FetchModelsError\";\n this.code = opts.code;\n this.status = opts.status;\n }\n}\n/**\n * Fetches the models.dev catalog and optionally filters results by provider and/or model.\n *\n * Error handling:\n * - Throws FetchModelsError with code: 'UNAVAILABLE' (no fetch present), 'NETWORK', 'HTTP', or 'PARSE'.\n */\nexport async function fetchModels(opts = {}) {\n if (typeof opts === \"string\") {\n return fetchModels({ provider: opts });\n }\n const url = opts.baseUrl ?? \"https://models.dev/api.json\";\n const fetchImpl = opts.fetch ?? globalThis.fetch;\n if (typeof fetchImpl !== \"function\") {\n throw new FetchModelsError({\n code: \"UNAVAILABLE\",\n message: \"No fetch implementation found. Pass a custom `fetch` in options or run on a platform with global fetch (Node 18+, modern browsers).\",\n });\n }\n let res;\n try {\n res = await fetchImpl(url, opts.signal ? { signal: opts.signal } : undefined);\n }\n catch (err) {\n const message = err instanceof Error ? err.message : \"Unknown network error\";\n throw new FetchModelsError({ code: \"NETWORK\", message });\n }\n if (!res.ok) {\n let body = \"\";\n try {\n body = await res.text();\n }\n catch { }\n const snippet = body\n ? ` Body: ${body.slice(0, 256)}${body.length > 256 ? \"…\" : \"\"}`\n : \"\";\n throw new FetchModelsError({\n code: \"HTTP\",\n status: res.status,\n message: `Failed to fetch models.dev API (${res.status} ${res.statusText}).${snippet}`,\n });\n }\n let data;\n try {\n data = await res.json();\n }\n catch (err) {\n const message = err instanceof Error ? err.message : \"Invalid JSON\";\n throw new FetchModelsError({ code: \"PARSE\", message });\n }\n const catalog = data;\n const { provider, model } = opts;\n if (!provider && !model)\n return catalog;\n if (provider && !model)\n return catalog[provider];\n if (provider && model)\n return catalog[provider]?.models?.[model];\n // model only: search across providers\n const matches = [];\n if (!model)\n return matches;\n for (const [provKey, prov] of Object.entries(catalog)) {\n const m = prov?.models?.[model];\n if (m)\n matches.push({ provider: provKey, model: m });\n }\n return matches;\n}\n//# sourceMappingURL=index.js.map",
|
|
9
|
-
"import { fetchModels, type FetchLike } from 'tokenlens/fetch';\nimport type { ModelCatalog } from 'tokenlens';\nimport type { PluginStorage } from '../../../packages/core/src/plugin.types';\n\nexport const PRICE_SETTINGS_KEY = 'pricing:settings:v1';\nexport const PRICE_CACHE_KEY = 'pricing:catalog:v1';\nexport const PRICE_STATUS_KEY = 'pricing:status:v1';\nexport const PRICE_SOURCE = 'https://models.dev/api.json';\nexport interface PriceSettings {\n autoRefresh: boolean;\n intervalMinutes: number;\n timeoutSeconds: number;\n}\nexport interface PriceCache { version: 1; fetchedAt: number; catalog: ModelCatalog }\nexport interface PriceStatus {\n settings: PriceSettings;\n source: string;\n refreshing: boolean;\n lastAttemptAt: number | null;\n lastSuccessAt: number | null;\n nextRefreshAt: number | null;\n lastError: 'timeout' | 'network' | 'invalid_catalog' | 'storage' | null;\n consecutiveFailures: number;\n modelCount: number;\n providerCount: number;\n}\nexport const DEFAULT_PRICE_SETTINGS: PriceSettings = { autoRefresh: true, intervalMinutes: 60, timeoutSeconds: 15 };\n\nexport function parsePriceSettings(value: unknown): PriceSettings {\n if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error('invalid_input');\n const v = value as Record<string, unknown>;\n if (Object.keys(v).some(key => !['autoRefresh', 'intervalMinutes', 'timeoutSeconds'].includes(key))\n || typeof v.autoRefresh !== 'boolean'\n || !Number.isInteger(v.intervalMinutes) || (v.intervalMinutes as number) < 1 || (v.intervalMinutes as number) > 1440\n || !Number.isInteger(v.timeoutSeconds) || (v.timeoutSeconds as number) < 5 || (v.timeoutSeconds as number) > 60) {\n throw new Error('invalid_input');\n }\n return { autoRefresh: v.autoRefresh, intervalMinutes: v.intervalMinutes as number, timeoutSeconds: v.timeoutSeconds as number };\n}\n\n// Cache only direct providers with usable prices, preserving context tiers and cache prices.\nexport function pricedCatalog(value: unknown): ModelCatalog {\n if (!value || typeof value !== 'object') throw new Error('invalid_catalog');\n const input = value as ModelCatalog;\n const output: ModelCatalog = {};\n let count = 0;\n for (const id of ['openai', 'anthropic', 'google', 'xai']) {\n const provider = input[id];\n if (!provider?.models || typeof provider.models !== 'object') continue;\n const models: ModelCatalog[string]['models'] = {};\n for (const [modelId, model] of Object.entries(provider.models)) {\n const cost = model?.cost;\n if (!cost || typeof cost.input !== 'number' || !Number.isFinite(cost.input) || cost.input < 0\n || typeof cost.output !== 'number' || !Number.isFinite(cost.output) || cost.output < 0) continue;\n if (++count > 10_000) throw new Error('invalid_catalog');\n Object.defineProperty(models, modelId, { value: { id: modelId, name: model.name, cost }, enumerable: true });\n }\n if (Object.keys(models).length) output[id] = { id, name: provider.name, models } as ModelCatalog[string];\n }\n if (!count) throw new Error('invalid_catalog');\n return output;\n}\n\nexport interface PriceCatalogOptions {\n fetch?: FetchLike;\n now?: () => number;\n schedule?: (callback: () => void, delayMs: number) => ReturnType<typeof setTimeout>;\n cancel?: (timer: ReturnType<typeof setTimeout>) => void;\n}\n\n/** One control-process owner; workers consume the same persisted catalog. */\nexport class PriceCatalogManager {\n private state: PriceStatus = {\n settings: { ...DEFAULT_PRICE_SETTINGS }, source: PRICE_SOURCE, refreshing: false,\n lastAttemptAt: null, lastSuccessAt: null, nextRefreshAt: null, lastError: null,\n consecutiveFailures: 0, modelCount: 0, providerCount: 0,\n };\n private timer: ReturnType<typeof setTimeout> | undefined;\n private controller: AbortController | undefined;\n private inFlight: Promise<void> | undefined;\n private initialization: Promise<void> | undefined;\n private stopped = false;\n private readonly now: () => number;\n\n constructor(private readonly storage: PluginStorage, private readonly options: PriceCatalogOptions = {}) {\n this.now = options.now ?? Date.now;\n }\n\n async start(): Promise<void> {\n await (this.initialization ??= this.restore());\n }\n\n status(): PriceStatus { return structuredClone(this.state); }\n\n private async restore(): Promise<void> {\n const settings = await this.storage.get<unknown>(PRICE_SETTINGS_KEY);\n if (settings !== null) {\n try { this.state.settings = parsePriceSettings(settings); } catch { /* Recover invalid configuration with defaults. */ }\n }\n const previous = await this.storage.get<PriceStatus>(PRICE_STATUS_KEY);\n if (previous) {\n if (typeof previous.lastAttemptAt === 'number' && Number.isFinite(previous.lastAttemptAt)) this.state.lastAttemptAt = previous.lastAttemptAt;\n if (['timeout', 'network', 'invalid_catalog', 'storage'].includes(previous.lastError as string)) this.state.lastError = previous.lastError;\n if (Number.isSafeInteger(previous.consecutiveFailures) && previous.consecutiveFailures >= 0) this.state.consecutiveFailures = previous.consecutiveFailures;\n }\n const cache = await this.storage.get<PriceCache>(PRICE_CACHE_KEY);\n if (cache?.version === 1 && Number.isFinite(cache.fetchedAt)) {\n try {\n const catalog = pricedCatalog(cache.catalog);\n this.state.lastSuccessAt = cache.fetchedAt;\n this.count(catalog);\n } catch { this.state.lastError = 'invalid_catalog'; }\n }\n if (this.stopped) return;\n this.schedule();\n await this.persist();\n }\n\n async configure(settings: PriceSettings): Promise<PriceStatus> {\n await this.start();\n if (this.stopped) throw new Error('disposed');\n const parsed = parsePriceSettings(settings);\n await this.storage.set(PRICE_SETTINGS_KEY, parsed);\n this.state.settings = parsed;\n this.schedule();\n await this.persist();\n return this.status();\n }\n\n refresh(): Promise<void> {\n if (this.stopped) return Promise.resolve();\n if (this.inFlight) return this.inFlight;\n this.clearTimer();\n this.state.nextRefreshAt = null;\n this.state.refreshing = true;\n this.state.lastAttemptAt = this.now();\n const task = this.load().finally(() => {\n if (this.inFlight === task) this.inFlight = undefined;\n });\n this.inFlight = task;\n return task;\n }\n\n stop(): void {\n this.stopped = true;\n this.clearTimer();\n this.controller?.abort();\n }\n\n private count(catalog: ModelCatalog): void {\n this.state.providerCount = Object.keys(catalog).length;\n this.state.modelCount = Object.values(catalog).reduce((total, provider) => total + Object.keys(provider.models).length, 0);\n }\n\n private async load(): Promise<void> {\n const controller = new AbortController();\n this.controller = controller;\n let timeout: ReturnType<typeof setTimeout> | undefined;\n let onAbort: (() => void) | undefined;\n let timedOut = false;\n let phase: 'network' | 'storage' | 'invalid_catalog' = 'storage';\n try {\n await this.persist();\n if (this.stopped) return;\n phase = 'network';\n const failure = new Promise<never>((_, reject) => {\n onAbort = () => reject(new Error('aborted'));\n controller.signal.addEventListener('abort', onAbort, { once: true });\n timeout = setTimeout(() => { timedOut = true; controller.abort(); }, this.state.settings.timeoutSeconds * 1000);\n });\n const fetched = await Promise.race([\n fetchModels({ ...(this.options.fetch ? { fetch: this.options.fetch } : {}), signal: controller.signal }), failure,\n ]);\n if (this.stopped) return;\n phase = 'invalid_catalog';\n const catalog = pricedCatalog(fetched);\n const fetchedAt = Math.max(this.now(), (this.state.lastSuccessAt ?? -1) + 1);\n phase = 'storage';\n await this.storage.set(PRICE_CACHE_KEY, { version: 1, fetchedAt, catalog } satisfies PriceCache);\n if (this.stopped) return;\n this.state.lastSuccessAt = fetchedAt;\n this.count(catalog);\n this.state.lastError = null;\n this.state.consecutiveFailures = 0;\n } catch {\n if (this.stopped) return;\n this.state.lastError = timedOut ? 'timeout' : phase;\n this.state.consecutiveFailures++;\n } finally {\n if (timeout !== undefined) clearTimeout(timeout);\n if (onAbort) controller.signal.removeEventListener('abort', onAbort);\n if (this.controller === controller) this.controller = undefined;\n this.state.refreshing = false;\n if (!this.stopped) {\n this.schedule();\n try { await this.persist(); } catch { this.state.lastError = 'storage'; }\n }\n }\n }\n\n private clearTimer(): void {\n if (this.timer !== undefined) (this.options.cancel ?? clearTimeout)(this.timer);\n this.timer = undefined;\n }\n\n private schedule(): void {\n this.clearTimer();\n this.state.nextRefreshAt = null;\n if (this.stopped || this.state.refreshing || !this.state.settings.autoRefresh) return;\n const interval = this.state.settings.intervalMinutes * 60_000;\n const due = this.state.consecutiveFailures\n ? this.now() + Math.min(interval, 60_000 * Math.min(15, 2 ** Math.min(this.state.consecutiveFailures - 1, 4)))\n : this.state.lastSuccessAt === null ? this.now() : Math.max(this.now(), this.state.lastSuccessAt + interval);\n this.state.nextRefreshAt = due;\n this.timer = (this.options.schedule ?? setTimeout)(() => { void this.refresh(); }, Math.max(0, due - this.now()));\n }\n\n private persist(): Promise<void> { return this.storage.set(PRICE_STATUS_KEY, this.status()); }\n}\n",
|
|
10
|
-
"import type {\n ControlApiDeclaration,\n ControlApiHandlerContext,\n ControlHostContext,\n ControlPlugin,\n PluginControl,\n} from '../../../packages/core/src/plugin-control/contracts';\nimport {\n TokenStatsRepository,\n TokenStatsRepositoryError,\n TokenStatsRepositoryLimitError,\n type AggregateDto,\n type GroupByDimension,\n} from './repository';\nimport { PriceCatalogManager, parsePriceSettings, type PriceCatalogOptions } from './price-catalog';\nimport { TOKEN_STATS_RANGES } from '../../../packages/core/src/token-stats-window';\n\nconst MAX_RESPONSE_BYTES = 256 * 1024;\nconst MAX_PAGE_STATS_RESPONSE_BYTES = 4 * 1024 * 1024;\nconst VALID_GROUP_BY = ['model', 'time'] as const;\n\ntype ControlErrorCode =\n | 'disposed'\n | 'request_cancelled'\n | 'invalid_input'\n | 'invalid_persisted_value'\n | 'response_limit'\n | 'internal_error';\n\nclass ControlError extends Error {\n constructor(readonly code: ControlErrorCode) {\n super(code);\n this.name = 'TokenStatsControlError';\n }\n}\n\nfunction jsonResponse(value: unknown, status = 200, maxBytes = MAX_RESPONSE_BYTES): Response {\n const body = JSON.stringify(value);\n if (new TextEncoder().encode(body).byteLength > maxBytes) {\n return new Response(JSON.stringify({ error: 'response_limit' }), {\n status: 500,\n headers: { 'content-type': 'application/json; charset=utf-8' },\n });\n }\n return new Response(body, {\n status,\n headers: { 'content-type': 'application/json; charset=utf-8' },\n });\n}\n\nfunction errorResponse(error: unknown): Response {\n const code = error instanceof ControlError\n ? error.code\n : error instanceof TokenStatsRepositoryLimitError\n ? 'response_limit'\n : error instanceof TokenStatsRepositoryError\n ? 'invalid_persisted_value'\n : 'internal_error';\n const status = code === 'request_cancelled' || code === 'invalid_input' ? 400 : code === 'disposed' ? 409 : 500;\n return jsonResponse({ error: code }, status);\n}\n\nasync function readSettings(request: Request): Promise<unknown> {\n const reader = request.body?.getReader();\n if (!reader) throw new ControlError('invalid_input');\n const chunks: Uint8Array[] = [];\n let size = 0;\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n size += value.byteLength;\n if (size > 4096) { await reader.cancel(); throw new ControlError('invalid_input'); }\n chunks.push(value);\n }\n const bytes = new Uint8Array(size);\n let offset = 0;\n for (const chunk of chunks) { bytes.set(chunk, offset); offset += chunk.byteLength; }\n return JSON.parse(new TextDecoder().decode(bytes));\n } finally { reader.releaseLock(); }\n}\n\nfunction abortable<T>(promise: Promise<T>, requestSignal: AbortSignal, hostSignal: AbortSignal): Promise<T> {\n if (hostSignal.aborted) return Promise.reject(new ControlError('disposed'));\n if (requestSignal.aborted) return Promise.reject(new ControlError('request_cancelled'));\n\n return new Promise<T>((resolve, reject) => {\n let settled = false;\n const cleanup = () => {\n requestSignal.removeEventListener('abort', onRequestAbort);\n hostSignal.removeEventListener('abort', onHostAbort);\n };\n const onRequestAbort = () => {\n if (!settled) {\n settled = true;\n cleanup();\n reject(new ControlError('request_cancelled'));\n }\n };\n const onHostAbort = () => {\n if (!settled) {\n settled = true;\n cleanup();\n reject(new ControlError('disposed'));\n }\n };\n\n requestSignal.addEventListener('abort', onRequestAbort, { once: true });\n hostSignal.addEventListener('abort', onHostAbort, { once: true });\n promise.then(\n (value) => {\n if (!settled) {\n settled = true;\n cleanup();\n resolve(value);\n }\n },\n (error) => {\n if (!settled) {\n settled = true;\n cleanup();\n reject(error);\n }\n },\n );\n });\n}\n\nclass TokenStatsControl implements PluginControl {\n readonly api: readonly ControlApiDeclaration[];\n readonly rpc = [] as const;\n private readonly repository: TokenStatsRepository;\n private readonly pricing: PriceCatalogManager;\n private disposed = false;\n private readonly abortListener: () => void;\n\n constructor(private readonly host: ControlHostContext, options?: PriceCatalogOptions) {\n this.repository = new TokenStatsRepository(host.storage);\n this.pricing = new PriceCatalogManager(host.storage.uncached?.() ?? host.storage, options);\n this.abortListener = () => { this.dispose(); };\n if (host.signal.aborted) this.disposed = true;\n else host.signal.addEventListener('abort', this.abortListener, { once: true });\n this.api = this.buildApi();\n }\n\n private assertAlive(signal?: AbortSignal): void {\n if (this.disposed || this.host.signal.aborted) throw new ControlError('disposed');\n if (signal?.aborted) throw new ControlError('request_cancelled');\n }\n\n private buildApi(): readonly ControlApiDeclaration[] {\n const invoke = (handler: (context: ControlApiHandlerContext) => Promise<Response> | Response) =>\n async (context: ControlApiHandlerContext): Promise<Response> => {\n try {\n this.assertAlive(context.requestSignal);\n return await handler(context);\n } catch (error) {\n return errorResponse(error);\n }\n };\n\n return [{\n path: '/stats',\n methods: ['GET'],\n handler: 'getStats',\n invoke: invoke(async (context) => {\n if (context.request.method !== 'GET') {\n return new Response(JSON.stringify({ error: 'method_not_allowed' }), {\n status: 405,\n headers: { allow: 'GET', 'content-type': 'application/json; charset=utf-8' },\n });\n }\n this.assertAlive(context.requestSignal);\n const url = new URL(context.request.url);\n const rawRange = url.searchParams.get('range');\n const rawGroupBy = url.searchParams.get('groupBy');\n const timeZone = url.searchParams.get('timeZone') ?? undefined;\n const keyId = url.searchParams.get('keyId') ?? undefined;\n if (url.searchParams.getAll('range').length > 1\n || url.searchParams.getAll('groupBy').length > 1\n || url.searchParams.getAll('timeZone').length > 1\n || url.searchParams.getAll('keyId').length > 1\n || (keyId !== undefined && (!keyId || keyId.length > 128))\n || (rawRange !== null && !(TOKEN_STATS_RANGES as readonly string[]).includes(rawRange))\n || (rawGroupBy !== null && !(VALID_GROUP_BY as readonly string[]).includes(rawGroupBy))) {\n throw new ControlError('invalid_input');\n }\n if (timeZone !== undefined) {\n try {\n if (!timeZone || timeZone.length > 100) throw new Error('invalid time zone');\n new Intl.DateTimeFormat('en-US', { timeZone });\n } catch { throw new ControlError('invalid_input'); }\n }\n const range = rawRange ?? '24h';\n const groupBy = (rawGroupBy ?? 'model') as GroupByDimension;\n const payload = await abortable(\n this.repository.query(range, groupBy, Date.now(), timeZone, keyId),\n context.requestSignal,\n context.signal,\n );\n this.assertAlive(context.requestSignal);\n // Monthly per-model rows can exceed the dashboard's response budget.\n const maxBytes = ['1h', '12h', '24h'].includes(range) ? MAX_RESPONSE_BYTES : MAX_PAGE_STATS_RESPONSE_BYTES;\n return jsonResponse(payload as AggregateDto, 200, maxBytes);\n }),\n }, {\n path: '/pricing', methods: ['GET'], handler: 'getPricing',\n invoke: invoke(async () => {\n await this.pricing.start();\n return jsonResponse(this.pricing.status());\n }),\n }, {\n path: '/pricing/settings', methods: ['PUT'], handler: 'configurePricing',\n invoke: invoke(async (context) => {\n let settings;\n try {\n settings = parsePriceSettings(await readSettings(context.request));\n } catch { throw new ControlError('invalid_input'); }\n this.assertAlive(context.requestSignal);\n return jsonResponse(await this.pricing.configure(settings));\n }),\n }, {\n path: '/pricing/refresh', methods: ['POST'], handler: 'refreshPricing',\n invoke: invoke(async () => {\n await this.pricing.start();\n void this.pricing.refresh();\n return jsonResponse(this.pricing.status(), 202);\n }),\n }];\n }\n\n async start(): Promise<void> {\n this.assertAlive();\n await this.pricing.start();\n }\n\n dispose(): void {\n if (this.disposed) return;\n this.disposed = true;\n this.pricing.stop();\n this.host.signal.removeEventListener('abort', this.abortListener);\n }\n}\n\nexport function createControl(context: ControlHostContext, options?: PriceCatalogOptions): PluginControl {\n return new TokenStatsControl(context, options);\n}\n\nexport default { createControl } satisfies ControlPlugin;\n"
|
|
8
|
+
"import type { PluginStorage } from '../../../packages/core/src/plugin.types';\n\n/** Pricing aliases never rewrite a request or the recorded model name. */\nexport interface PriceModelMapping { source: string; provider: string; model: string }\nexport interface PriceModelOption { provider: string; providerName: string; model: string; name: string }\nexport const PRICE_MODEL_MAPPINGS_KEY = 'pricing:model-mappings:v1';\nexport const MAX_PRICE_MODEL_MAPPINGS = 100;\n\n/** SQLite KV get() is best-effort and hides failures; pricing aliases need strict reads. */\nexport async function readPriceModelMappings(storage: PluginStorage): Promise<PriceModelMapping[]> {\n if (!storage.observation) return parsePriceModelMappings(await storage.get(PRICE_MODEL_MAPPINGS_KEY) ?? []);\n return storage.observation.withDatabase(db => {\n const row = db.query<{ value: string; ttl: number | null }, [string, string]>(\n 'SELECT value, ttl FROM plugin_storage WHERE plugin_name = ? AND key = ?',\n ).get('token-stats', PRICE_MODEL_MAPPINGS_KEY);\n if (!row || (row.ttl !== null && row.ttl < Math.floor(Date.now() / 1000))) return [];\n return parsePriceModelMappings(JSON.parse(row.value));\n });\n}\n\nexport function isUnchangedPriceModelMapping(mapping: PriceModelMapping, existing: readonly PriceModelMapping[]): boolean {\n return existing.some(item => item.source === mapping.source && item.provider === mapping.provider && item.model === mapping.model);\n}\n\nexport function parsePriceModelMappings(value: unknown): PriceModelMapping[] {\n if (!Array.isArray(value) || value.length > MAX_PRICE_MODEL_MAPPINGS) throw new Error('invalid_input');\n const sources = new Set<string>();\n return value.map(item => {\n if (!item || typeof item !== 'object' || Array.isArray(item)\n || Object.keys(item).some(key => !['source', 'provider', 'model'].includes(key))) throw new Error('invalid_input');\n const { source, provider, model } = item;\n for (const [text, limit] of [[source, 256], [provider, 128], [model, 256]] as const) {\n if (typeof text !== 'string' || !text.trim() || text !== text.trim() || text.length > limit\n || /[\\u0000-\\u001f\\u007f]/.test(text)) throw new Error('invalid_input');\n }\n if (sources.has(source)) throw new Error('invalid_input');\n sources.add(source);\n return { source, provider, model };\n });\n}\n",
|
|
9
|
+
"import type {\n PluginStorage,\n TokenStatsAttempt,\n TokenStatsMetricName,\n TokenStatsMeteringStorage,\n TokenStatsSnapshotMetrics,\n TokenStatsRange,\n} from '../../../packages/core/src/plugin.types';\nimport type { CanonicalTokenAccountingEventV2 } from '@jeffusion/bungee-llms/plugin-api';\n// The control artifact needs only authority names, not the worker conversion runtime.\nconst TOKEN_ACCOUNTING_AUTHORITIES = ['official', 'local', 'heuristic', 'partial', 'none'] as const satisfies readonly CanonicalTokenAccountingEventV2['inputAuthority'][];\nimport { SQLiteTokenStatsMetering } from './storage';\nimport { TOKEN_STATS_RANGES, TOKEN_STATS_RETENTION_MS } from '../../../packages/core/src/token-stats-window';\nimport { PRICE_MODEL_MAPPINGS_KEY, readPriceModelMappings, type PriceModelMapping } from './model-mappings';\n\nexport type GroupByDimension = 'model' | 'time';\ntype TokenAccountingAuthority = typeof TOKEN_ACCOUNTING_AUTHORITIES[number];\nexport type CanonicalEvent = CanonicalTokenAccountingEventV2;\n\nexport interface AuthorityBreakdownDto {\n input: Record<TokenAccountingAuthority, number>;\n output: Record<TokenAccountingAuthority, number>;\n}\n\nexport interface GroupedAggregateDto {\n dimension: string;\n bucketStartMs?: number;\n inputTokens: number;\n outputTokens: number;\n officialInputTokens: number;\n officialOutputTokens: number;\n estimatedInputTokens: number;\n estimatedOutputTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n partialOutputs: number;\n logicalRequests: number;\n upstreamAttempts: number;\n observationIncompleteAttempts: number;\n estimatedCostUsd: number | null;\n authorityBreakdown: AuthorityBreakdownDto;\n}\n\nexport interface AggregateDto extends Omit<GroupedAggregateDto, 'dimension' | 'bucketStartMs' | 'inputTokens' | 'outputTokens'> {\n /** Sticky evidence of dropped or failed reporting, shared across worker/control processes. */\n reportingIncomplete: boolean;\n groupBy: GroupByDimension;\n asOfMs: number;\n bucketMs?: number;\n bucketStarts?: number[];\n bucketEndMs?: number;\n totalInputTokens: number;\n totalOutputTokens: number;\n data: GroupedAggregateDto[];\n}\n\nexport class TokenStatsRepositoryError extends Error {\n constructor(message: string) { super(message); this.name = 'TokenStatsRepositoryError'; }\n}\n\nexport class TokenStatsRepositoryLimitError extends TokenStatsRepositoryError {}\n\nexport interface ClientModelPage {\n /** Distinct raw client/attempt model names, exactly as recorded (original case). */\n models: string[];\n total: number;\n page: number;\n pageSize: number;\n}\n\nexport const MAX_CLIENT_MODEL_PAGE_SIZE = 100;\nexport const MAX_CLIENT_MODEL_PAGE = 400;\nconst CLIENT_MODEL_KEYWORD_MAX = 256;\n\nexport const REPORTING_INCOMPLETE_KEY = 'reporting:incomplete';\n\ntype MeteringLogger = { onFailure?(): void; warn(message: string, metadata?: object): void; error(message: string, metadata?: object): void };\ntype AttemptTask = () => TokenStatsAttempt | undefined | Promise<TokenStatsAttempt | undefined>;\ntype QueuedAttempt = { metering: TokenStatsMeteringStorage; task: AttemptTask; logger: MeteringLogger };\n\nconst MAX_PENDING_ATTEMPTS = 256;\nconst LOG_INTERVAL_MS = 60_000;\nconst pendingAttempts: QueuedAttempt[] = [];\nlet pendingCount = 0;\nlet drainTimer: ReturnType<typeof setTimeout> | undefined;\nlet draining = false;\nlet lastDropLogAt = 0;\nlet lastFailureLogAt = 0;\n\nfunction logRateLimited(logger: MeteringLogger, kind: 'drop' | 'failure', error?: unknown): void {\n try { logger.onFailure?.(); } catch { /* failure reporting must not affect proxy flow */ }\n const now = Date.now();\n if (kind === 'drop') {\n if (now - lastDropLogAt < LOG_INTERVAL_MS) return;\n lastDropLogAt = now;\n try { logger.warn('Token stats attempt queue full; dropping metering rows', { capacity: MAX_PENDING_ATTEMPTS }); } catch { /* logging must not affect proxy flow */ }\n return;\n }\n if (now - lastFailureLogAt < LOG_INTERVAL_MS) return;\n lastFailureLogAt = now;\n try {\n logger.error('Token stats attempt processing failed; dropping metering row', {\n error: error instanceof Error ? error.message : error === undefined ? 'attempt task returned no row' : String(error),\n });\n } catch { /* logging must not affect proxy flow */ }\n}\n\nfunction scheduleDrain(): void {\n if (drainTimer !== undefined || draining) return;\n drainTimer = setTimeout(() => { drainTimer = undefined; void drainOneAttempt(); }, 0);\n}\n\nasync function drainOneAttempt(): Promise<void> {\n if (draining) return;\n const item = pendingAttempts.shift();\n if (!item) return;\n draining = true;\n try {\n try {\n const row = await item.task();\n if (row === undefined) {\n logRateLimited(item.logger, 'failure');\n } else {\n await item.metering.recordAttempt(row);\n }\n } catch (error) {\n logRateLimited(item.logger, 'failure', error);\n }\n } finally {\n pendingCount--;\n draining = false;\n if (pendingAttempts.length) scheduleDrain();\n }\n}\n\nconst METRIC_FIELDS: readonly TokenStatsMetricName[] = [\n 'inputTokens', 'outputTokens', 'officialInputTokens', 'officialOutputTokens',\n 'estimatedInputTokens', 'estimatedOutputTokens', 'cacheReadTokens', 'cacheWriteTokens',\n 'partialOutputs', 'logicalRequests', 'upstreamAttempts', 'observationIncompleteAttempts',\n 'inputAuthorityOfficial', 'inputAuthorityLocal', 'inputAuthorityHeuristic', 'inputAuthorityPartial', 'inputAuthorityNone',\n 'outputAuthorityOfficial', 'outputAuthorityLocal', 'outputAuthorityHeuristic', 'outputAuthorityPartial', 'outputAuthorityNone',\n];\n\nfunction emptyMetrics(): TokenStatsSnapshotMetrics {\n return { ...Object.fromEntries(METRIC_FIELDS.map((key) => [key, 0])) as Record<TokenStatsMetricName, number>, estimatedCostUsd: null };\n}\n\nfunction emptyAuthorityBreakdown(): AuthorityBreakdownDto {\n const empty = () => Object.fromEntries(TOKEN_ACCOUNTING_AUTHORITIES.map((authority) => [authority, 0])) as Record<TokenAccountingAuthority, number>;\n return { input: empty(), output: empty() };\n}\n\nfunction metricsToDto(metrics: TokenStatsSnapshotMetrics): Omit<GroupedAggregateDto, 'dimension'> {\n const authorityBreakdown = emptyAuthorityBreakdown();\n for (const authority of TOKEN_ACCOUNTING_AUTHORITIES) {\n authorityBreakdown.input[authority] = metrics[`inputAuthority${authority[0]!.toUpperCase()}${authority.slice(1)}` as TokenStatsMetricName];\n authorityBreakdown.output[authority] = metrics[`outputAuthority${authority[0]!.toUpperCase()}${authority.slice(1)}` as TokenStatsMetricName];\n }\n return {\n inputTokens: metrics.inputTokens,\n outputTokens: metrics.outputTokens,\n officialInputTokens: metrics.officialInputTokens,\n officialOutputTokens: metrics.officialOutputTokens,\n estimatedInputTokens: metrics.estimatedInputTokens,\n estimatedOutputTokens: metrics.estimatedOutputTokens,\n cacheReadTokens: metrics.cacheReadTokens,\n cacheWriteTokens: metrics.cacheWriteTokens,\n partialOutputs: metrics.partialOutputs,\n logicalRequests: metrics.logicalRequests,\n upstreamAttempts: metrics.upstreamAttempts,\n observationIncompleteAttempts: metrics.observationIncompleteAttempts,\n estimatedCostUsd: metrics.estimatedCostUsd,\n authorityBreakdown,\n };\n}\n\nfunction sourceFor(value: number | undefined, authority: CanonicalTokenAccountingEventV2['inputAuthority']): TokenStatsAttempt['input_source'] {\n if (!Number.isSafeInteger(value) || value! < 0) return 'unknown';\n if (authority === 'official') return 'usage';\n if (authority === 'partial') return 'partial';\n return authority === 'none' ? 'unknown' : 'estimated';\n}\n\nexport function attemptRowFromEvent(\n event: CanonicalEvent,\n finishedAtMs: number,\n observationIncomplete: boolean,\n model: string,\n): TokenStatsAttempt {\n const inputSource = sourceFor(event.inputTokens, event.inputAuthority);\n const outputSource = sourceFor(event.outputTokens, event.outputAuthority);\n return {\n attempt_id: event.attemptId,\n request_id: event.requestId,\n finished_at_ms: finishedAtMs,\n route_id: event.routeId || 'unknown',\n upstream_id: event.upstreamId || 'unknown',\n provider: event.provider || 'unknown',\n outcome: event.outcome,\n model,\n input_tokens: inputSource === 'unknown' ? null : event.inputTokens!,\n output_tokens: outputSource === 'unknown' ? null : event.outputTokens!,\n input_source: inputSource,\n output_source: outputSource,\n cache_read_tokens: Number.isSafeInteger(event.cacheReadTokens) && event.cacheReadTokens! >= 0 ? event.cacheReadTokens! : null,\n cache_write_tokens: Number.isSafeInteger(event.cacheWriteTokens) && event.cacheWriteTokens! >= 0 ? event.cacheWriteTokens! : null,\n cost_usd: null,\n observation_incomplete: observationIncomplete,\n };\n}\n\nexport class TokenStatsRepository {\n private readonly metering: TokenStatsMeteringStorage;\n\n constructor(private readonly storage: PluginStorage) {\n if (!storage.metering && !storage.observation) throw new TokenStatsRepositoryError('token-stats metering storage is required');\n this.metering = storage.metering ?? new SQLiteTokenStatsMetering(storage.observation!);\n }\n\n /** Defers synchronous task work to drain; a task can still occupy the EventLoop. */\n enqueueAttempt(task: AttemptTask, logger: MeteringLogger): boolean {\n if (pendingCount >= MAX_PENDING_ATTEMPTS) {\n logRateLimited(logger, 'drop');\n return false;\n }\n pendingAttempts.push({ metering: this.metering, task, logger });\n pendingCount++;\n scheduleDrain();\n return true;\n }\n\n async query(range: string, groupBy: GroupByDimension, asOfMs = Date.now(), timeZone?: string, keyId?: string): Promise<AggregateDto> {\n if (!(TOKEN_STATS_RANGES as readonly string[]).includes(range)) throw new TokenStatsRepositoryError('invalid token-stats range');\n if (groupBy !== 'model' && groupBy !== 'time') {\n throw new TokenStatsRepositoryError('invalid token-stats groupBy');\n }\n if (!Number.isSafeInteger(asOfMs) || asOfMs < 0) throw new TokenStatsRepositoryError('invalid token-stats asOfMs');\n const snapshot = await this.metering.queryWindowSnapshot({ asOfMs, range: range as TokenStatsRange, groupBy, timeZone, keyId });\n const total = metricsToDto(snapshot.all);\n const { inputTokens, outputTokens, ...summary } = total;\n return {\n reportingIncomplete: await (this.storage.uncached?.() ?? this.storage).get(REPORTING_INCOMPLETE_KEY) === true,\n groupBy,\n asOfMs,\n ...summary,\n totalInputTokens: inputTokens,\n totalOutputTokens: outputTokens,\n ...(snapshot.bucketMs === undefined ? {} : { bucketMs: snapshot.bucketMs }),\n ...(snapshot.bucketStarts === undefined ? {} : { bucketStarts: snapshot.bucketStarts }),\n ...(snapshot.bucketEndMs === undefined ? {} : { bucketEndMs: snapshot.bucketEndMs }),\n data: snapshot.data.map((row) => ({\n dimension: row.dimension,\n ...(row.bucketStartMs === undefined ? {} : { bucketStartMs: row.bucketStartMs }),\n ...metricsToDto(row.metrics),\n })).sort(groupBy === 'model'\n ? (a, b) => b.inputTokens + b.outputTokens - a.inputTokens - a.outputTokens\n || b.upstreamAttempts - a.upstreamAttempts || a.dimension.localeCompare(b.dimension)\n : (a, b) => a.bucketStartMs! - b.bucketStartMs! || a.dimension.localeCompare(b.dimension)),\n };\n }\n\n /**\n * Distinct real client model names within the retention window, independent of\n * the dashboard's current time-range filter or Top-N truncation. No synthetic\n * rows are inserted; a storage failure propagates instead of returning an empty\n * page. Bounded and fully reachable through paging.\n */\n async listClientModels(input: { keyword?: string; page?: number; pageSize?: number } = {}): Promise<ClientModelPage> {\n const pageSize = Math.max(1, Math.min(MAX_CLIENT_MODEL_PAGE_SIZE, Math.trunc(input.pageSize ?? 50)));\n const page = Math.max(1, Math.trunc(input.page ?? 1));\n if (!Number.isSafeInteger(page) || page > MAX_CLIENT_MODEL_PAGE) throw new TokenStatsRepositoryError('invalid token-stats page');\n const keyword = input.keyword;\n if (keyword !== undefined && (typeof keyword !== 'string' || keyword.length > CLIENT_MODEL_KEYWORD_MAX)) {\n throw new TokenStatsRepositoryError('invalid token-stats keyword');\n }\n const observation = this.storage.observation;\n if (observation === undefined) throw new TokenStatsRepositoryError('token-stats observation storage is required');\n const since = Date.now() - TOKEN_STATS_RETENTION_MS;\n const hasKeyword = keyword !== undefined && keyword.length > 0;\n const escaped = hasKeyword ? keyword.replace(/[\\\\%_]/g, character => `\\\\${character}`) : null;\n return observation.withDatabase((db) => {\n const countSql = hasKeyword\n ? \"SELECT COUNT(DISTINCT model) AS total FROM token_stats_attempts WHERE finished_at_ms >= ? AND model LIKE ? ESCAPE '\\\\'\"\n : 'SELECT COUNT(DISTINCT model) AS total FROM token_stats_attempts WHERE finished_at_ms >= ?';\n const totalRow = db.query<{ total: number }, (number | string)[]>(countSql)\n .get(...(hasKeyword ? [since, `%${escaped}%`] : [since]));\n const total = Number(totalRow?.total ?? 0);\n const pageSql = hasKeyword\n ? \"SELECT DISTINCT model FROM token_stats_attempts WHERE finished_at_ms >= ? AND model LIKE ? ESCAPE '\\\\' ORDER BY model ASC LIMIT ? OFFSET ?\"\n : 'SELECT DISTINCT model FROM token_stats_attempts WHERE finished_at_ms >= ? ORDER BY model ASC LIMIT ? OFFSET ?';\n const rows = db.query<{ model: string }, (number | string)[]>(pageSql)\n .all(...(hasKeyword ? [since, `%${escaped}%`, pageSize, (page - 1) * pageSize] : [since, pageSize, (page - 1) * pageSize]));\n return {\n models: rows.map(row => String(row.model)),\n total: Number.isSafeInteger(total) && total >= 0 ? total : 0,\n page,\n pageSize,\n };\n });\n }\n\n /** Price aliases are token-stats business state, read/written through this repository. */\n async mappings(): Promise<PriceModelMapping[]> {\n return readPriceModelMappings(this.storage);\n }\n\n async configureMappings(mappings: PriceModelMapping[]): Promise<void> {\n await this.storage.set(PRICE_MODEL_MAPPINGS_KEY, mappings);\n }\n}\n",
|
|
10
|
+
"import type {\n ControlApiDeclaration,\n ControlApiHandlerContext,\n ControlHostContext,\n ControlPlugin,\n PluginControl,\n} from '../../../packages/core/src/plugin-control/contracts';\nimport { MODELS_DEV_CATALOG_CONTRACT_VERSION, MODELS_DEV_CATALOG_SERVICE_ID, MODELS_DEV_SOURCE_URL, type ModelsDevCatalogService } from '../../models-dev/contract';\nimport {\n MAX_CLIENT_MODEL_PAGE,\n MAX_CLIENT_MODEL_PAGE_SIZE,\n TokenStatsRepository,\n TokenStatsRepositoryError,\n TokenStatsRepositoryLimitError,\n type AggregateDto,\n type GroupByDimension,\n} from './repository';\nimport { TOKEN_STATS_RANGES } from '../../../packages/core/src/token-stats-window';\nimport { parsePriceModelMappings, isUnchangedPriceModelMapping, type PriceModelOption } from './model-mappings';\n\nconst MAX_RESPONSE_BYTES = 256 * 1024;\nconst MAX_PAGE_STATS_RESPONSE_BYTES = 4 * 1024 * 1024;\nconst VALID_GROUP_BY = ['model', 'time'] as const;\n\ntype ControlErrorCode =\n | 'disposed'\n | 'request_cancelled'\n | 'invalid_input'\n | 'invalid_persisted_value'\n | 'response_limit'\n | 'catalog_unavailable'\n | 'storage_unavailable'\n | 'internal_error';\n\nclass ControlError extends Error {\n constructor(readonly code: ControlErrorCode) {\n super(code);\n this.name = 'TokenStatsControlError';\n }\n}\n\nfunction jsonResponse(value: unknown, status = 200, maxBytes = MAX_RESPONSE_BYTES): Response {\n const body = JSON.stringify(value);\n if (new TextEncoder().encode(body).byteLength > maxBytes) {\n return new Response(JSON.stringify({ error: 'response_limit' }), {\n status: 500,\n headers: { 'content-type': 'application/json; charset=utf-8' },\n });\n }\n return new Response(body, {\n status,\n headers: { 'content-type': 'application/json; charset=utf-8' },\n });\n}\n\nfunction errorResponse(error: unknown): Response {\n const code = error instanceof ControlError\n ? error.code\n : error instanceof TokenStatsRepositoryLimitError\n ? 'response_limit'\n : error instanceof TokenStatsRepositoryError\n ? 'invalid_persisted_value'\n : 'internal_error';\n const status = code === 'request_cancelled' || code === 'invalid_input' ? 400\n : code === 'disposed' ? 409\n : code === 'catalog_unavailable' || code === 'storage_unavailable' ? 503\n : 500;\n return jsonResponse({ error: code }, status);\n}\n\nasync function readSettings(request: Request, maxBytes = 4096): Promise<unknown> {\n const reader = request.body?.getReader();\n if (!reader) throw new ControlError('invalid_input');\n const chunks: Uint8Array[] = [];\n let size = 0;\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n size += value.byteLength;\n if (size > maxBytes) { await reader.cancel(); throw new ControlError('invalid_input'); }\n chunks.push(value);\n }\n const bytes = new Uint8Array(size);\n let offset = 0;\n for (const chunk of chunks) { bytes.set(chunk, offset); offset += chunk.byteLength; }\n return JSON.parse(new TextDecoder().decode(bytes));\n } finally { reader.releaseLock(); }\n}\n\nfunction abortable<T>(promise: Promise<T>, requestSignal: AbortSignal, hostSignal: AbortSignal): Promise<T> {\n if (hostSignal.aborted) return Promise.reject(new ControlError('disposed'));\n if (requestSignal.aborted) return Promise.reject(new ControlError('request_cancelled'));\n return new Promise<T>((resolve, reject) => {\n let settled = false;\n const cleanup = () => {\n requestSignal.removeEventListener('abort', onRequestAbort);\n hostSignal.removeEventListener('abort', onHostAbort);\n };\n const onRequestAbort = () => { if (!settled) { settled = true; cleanup(); reject(new ControlError('request_cancelled')); } };\n const onHostAbort = () => { if (!settled) { settled = true; cleanup(); reject(new ControlError('disposed')); } };\n requestSignal.addEventListener('abort', onRequestAbort, { once: true });\n hostSignal.addEventListener('abort', onHostAbort, { once: true });\n promise.then(\n (value) => { if (!settled) { settled = true; cleanup(); resolve(value); } },\n (error) => { if (!settled) { settled = true; cleanup(); reject(error); } },\n );\n });\n}\n\nfunction parseModelQuery(request: Request): { provider?: string; search?: string; page?: number; pageSize?: number } | null {\n const params = new URL(request.url).searchParams;\n for (const key of ['provider', 'search', 'page', 'pageSize']) if (params.getAll(key).length > 1) return null;\n const provider = params.get('provider') ?? undefined;\n const search = params.get('search') ?? undefined;\n const page = params.get('page') === null ? 1 : Number(params.get('page'));\n const pageSize = params.get('pageSize') === null ? 50 : Number(params.get('pageSize'));\n if (!Number.isSafeInteger(page) || page < 1\n || !Number.isSafeInteger(pageSize) || pageSize < 1 || pageSize > MAX_CLIENT_MODEL_PAGE_SIZE) return null;\n return { ...(provider === undefined ? {} : { provider }), ...(search === undefined ? {} : { search }), page, pageSize };\n}\n\nclass TokenStatsControl implements PluginControl {\n readonly api: readonly ControlApiDeclaration[];\n readonly rpc = [] as const;\n private readonly repository: TokenStatsRepository;\n private disposed = false;\n private readonly abortListener: () => void;\n\n constructor(private readonly host: ControlHostContext) {\n this.repository = new TokenStatsRepository(host.storage);\n this.abortListener = () => { this.dispose(); };\n if (host.signal.aborted) this.disposed = true;\n else host.signal.addEventListener('abort', this.abortListener, { once: true });\n this.api = this.buildApi();\n }\n\n private assertAlive(signal?: AbortSignal): void {\n if (this.disposed || this.host.signal.aborted) throw new ControlError('disposed');\n if (signal?.aborted) throw new ControlError('request_cancelled');\n }\n\n private catalogService(): ModelsDevCatalogService {\n const services = this.host.services;\n if (services === undefined) throw new ControlError('catalog_unavailable');\n try {\n return services.consume<ModelsDevCatalogService>(\n 'models-dev', MODELS_DEV_CATALOG_SERVICE_ID, MODELS_DEV_CATALOG_CONTRACT_VERSION,\n );\n } catch { throw new ControlError('catalog_unavailable'); }\n }\n\n private buildApi(): readonly ControlApiDeclaration[] {\n const invoke = (handler: (context: ControlApiHandlerContext) => Promise<Response> | Response) =>\n async (context: ControlApiHandlerContext): Promise<Response> => {\n try {\n this.assertAlive(context.requestSignal);\n return await handler(context);\n } catch (error) {\n return errorResponse(error);\n }\n };\n\n return [{\n path: '/stats', methods: ['GET'], handler: 'getStats',\n invoke: invoke(async (context) => {\n if (context.request.method !== 'GET') {\n return new Response(JSON.stringify({ error: 'method_not_allowed' }), {\n status: 405,\n headers: { allow: 'GET', 'content-type': 'application/json; charset=utf-8' },\n });\n }\n this.assertAlive(context.requestSignal);\n const url = new URL(context.request.url);\n const rawRange = url.searchParams.get('range');\n const rawGroupBy = url.searchParams.get('groupBy');\n const timeZone = url.searchParams.get('timeZone') ?? undefined;\n const keyId = url.searchParams.get('keyId') ?? undefined;\n if (url.searchParams.getAll('range').length > 1\n || url.searchParams.getAll('groupBy').length > 1\n || url.searchParams.getAll('timeZone').length > 1\n || url.searchParams.getAll('keyId').length > 1\n || (keyId !== undefined && (!keyId || keyId.length > 128))\n || (rawRange !== null && !(TOKEN_STATS_RANGES as readonly string[]).includes(rawRange))\n || (rawGroupBy !== null && !(VALID_GROUP_BY as readonly string[]).includes(rawGroupBy))) {\n throw new ControlError('invalid_input');\n }\n if (timeZone !== undefined) {\n try {\n if (!timeZone || timeZone.length > 100) throw new Error('invalid time zone');\n new Intl.DateTimeFormat('en-US', { timeZone });\n } catch { throw new ControlError('invalid_input'); }\n }\n const range = rawRange ?? '24h';\n const groupBy = (rawGroupBy ?? 'model') as GroupByDimension;\n const payload = await abortable(\n this.repository.query(range, groupBy, Date.now(), timeZone, keyId),\n context.requestSignal,\n context.signal,\n );\n this.assertAlive(context.requestSignal);\n const maxBytes = ['1h', '12h', '24h'].includes(range) ? MAX_RESPONSE_BYTES : MAX_PAGE_STATS_RESPONSE_BYTES;\n return jsonResponse(payload as AggregateDto, 200, maxBytes);\n }),\n }, {\n path: '/pricing', methods: ['GET'], handler: 'getPricing',\n invoke: invoke(async () => {\n const status = this.catalogService().status();\n return jsonResponse({ ...status, source: MODELS_DEV_SOURCE_URL });\n }),\n }, {\n path: '/pricing/models', methods: ['GET'], handler: 'getPricingModels',\n invoke: invoke(async (context) => {\n const query = parseModelQuery(context.request);\n if (query === null) return jsonResponse({ error: 'invalid_input' }, 400);\n const result = this.catalogService().modelOptions(query);\n const models: PriceModelOption[] = result.models.map(model => ({\n provider: model.provider, providerName: model.providerName, model: model.model, name: model.name,\n }));\n return jsonResponse({ models, total: result.total, page: result.page, pageSize: result.pageSize }, 200, MAX_PAGE_STATS_RESPONSE_BYTES);\n }),\n }, {\n path: '/pricing/mappings', methods: ['GET'], handler: 'getPricingMappings',\n invoke: invoke(async () => jsonResponse({ mappings: await this.repository.mappings() })),\n }, {\n path: '/pricing/mappings', methods: ['PUT'], handler: 'configurePricingMappings',\n invoke: invoke(async (context) => {\n let mappings;\n try { mappings = parsePriceModelMappings(await readSettings(context.request, MAX_RESPONSE_BYTES)); }\n catch { throw new ControlError('invalid_input'); }\n const service = this.catalogService();\n const existing = await this.repository.mappings();\n if (mappings.some(mapping => service.resolveModel({ model: mapping.model, pricingProvider: mapping.provider }) === null\n && !isUnchangedPriceModelMapping(mapping, existing))) throw new ControlError('invalid_input');\n this.assertAlive(context.requestSignal);\n await this.repository.configureMappings(mappings);\n return jsonResponse({ mappings });\n }),\n }, {\n // Deliverable: real client/attempt model names for the free-input picker.\n path: '/models', methods: ['GET'], handler: 'getClientModels',\n invoke: invoke(async (context) => {\n const query = parseModelQuery(context.request);\n if (query === null) return jsonResponse({ error: 'invalid_input' }, 400);\n let page;\n try {\n page = await this.repository.listClientModels({\n ...(query.search === undefined ? {} : { keyword: query.search }),\n page: query.page,\n pageSize: query.pageSize,\n });\n } catch (error) {\n if (error instanceof TokenStatsRepositoryError) throw new ControlError('storage_unavailable');\n throw error;\n }\n this.assertAlive(context.requestSignal);\n return jsonResponse(page);\n }),\n }];\n }\n\n async start(): Promise<void> {\n this.assertAlive();\n }\n\n dispose(): void {\n if (this.disposed) return;\n this.disposed = true;\n this.host.signal.removeEventListener('abort', this.abortListener);\n }\n}\n\nexport function createControl(context: ControlHostContext): PluginControl {\n return new TokenStatsControl(context);\n}\n\nexport default { createControl } satisfies ControlPlugin;\n"
|
|
11
11
|
],
|
|
12
|
-
"mappings": "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",
|
|
13
|
-
"debugId": "
|
|
12
|
+
"mappings": "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",
|
|
13
|
+
"debugId": "9E6A0268F9DCEF3464756E2164756E21",
|
|
14
14
|
"names": []
|
|
15
15
|
}
|