@jeffusion/bungee-core 5.9.0 → 5.11.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 (53) hide show
  1. package/dist/main.js +31348 -17337
  2. package/dist/plugins/ai-transformer/index.js.map +2 -2
  3. package/dist/plugins/anthropic-request-sanitizer/index.js.map +2 -2
  4. package/dist/plugins/anthropic-tool-name-transformer/index.js.map +2 -2
  5. package/dist/plugins/chatgpt-oauth/control.js +513 -1
  6. package/dist/plugins/chatgpt-oauth/control.js.map +12 -4
  7. package/dist/plugins/chatgpt-oauth/index.js +511 -4
  8. package/dist/plugins/chatgpt-oauth/index.js.map +13 -5
  9. package/dist/plugins/chatgpt-oauth/manifest.json +19 -0
  10. package/dist/plugins/deepseek-reasoning-fix/index.js.map +2 -2
  11. package/dist/plugins/key-access/control.js.map +1 -1
  12. package/dist/plugins/key-access/index.js.map +3 -3
  13. package/dist/plugins/key-access/ingress.js.map +1 -1
  14. package/dist/plugins/key-rate-limit/index.js.map +2 -2
  15. package/dist/plugins/local-accounts/control.js +68 -18
  16. package/dist/plugins/local-accounts/control.js.map +4 -4
  17. package/dist/plugins/local-accounts/index.js.map +2 -2
  18. package/dist/plugins/local-accounts/manifest.json +48 -2
  19. package/dist/plugins/local-accounts/ui/Settings.svelte +73 -1
  20. package/dist/plugins/model-mapping/control.js +72 -17741
  21. package/dist/plugins/model-mapping/control.js.map +6 -58
  22. package/dist/plugins/model-mapping/index.js +32 -17433
  23. package/dist/plugins/model-mapping/index.js.map +6 -58
  24. package/dist/plugins/model-mapping/manifest.json +30 -14
  25. package/dist/plugins/models-dev/control.js +1042 -0
  26. package/dist/plugins/models-dev/control.js.map +16 -0
  27. package/dist/plugins/models-dev/index.js +15418 -0
  28. package/dist/plugins/models-dev/index.js.map +134 -0
  29. package/dist/plugins/models-dev/manifest.json +199 -0
  30. package/dist/plugins/models-dev/ui/ModelsDevSettings.svelte +120 -0
  31. package/dist/plugins/openai-messages-to-chat/index.js.map +2 -2
  32. package/dist/plugins/signature-repair/index.js.map +2 -2
  33. package/dist/plugins/token-budget/control.js +524 -9
  34. package/dist/plugins/token-budget/control.js.map +12 -4
  35. package/dist/plugins/token-budget/index.js +519 -12
  36. package/dist/plugins/token-budget/index.js.map +13 -6
  37. package/dist/plugins/token-budget/manifest.json +16 -2
  38. package/dist/plugins/token-metering/index.js +93 -2
  39. package/dist/plugins/token-metering/index.js.map +12 -6
  40. package/dist/plugins/token-stats/control.js +174 -312
  41. package/dist/plugins/token-stats/control.js.map +7 -7
  42. package/dist/plugins/token-stats/index.js +283 -486
  43. package/dist/plugins/token-stats/index.js.map +16 -12
  44. package/dist/plugins/token-stats/manifest.json +99 -12
  45. package/dist/plugins/token-stats/ui/ClientModelPicker.svelte +76 -0
  46. package/dist/plugins/token-stats/ui/PriceModelPicker.svelte +87 -0
  47. package/dist/plugins/token-stats/ui/TokenStatsSettings.svelte +136 -80
  48. package/dist/plugins/token-stats/ui/client-model-search.test.ts +58 -0
  49. package/dist/plugins/token-stats/ui/client-model-search.ts +16 -0
  50. package/dist/plugins/token-stats/ui/model-search.ts +45 -0
  51. package/dist/plugins/token-stats/ui/pricing-catalog.test.ts +114 -0
  52. package/dist/plugins/token-stats/ui/pricing-catalog.ts +17 -0
  53. package/package.json +2 -2
@@ -14823,7 +14823,98 @@ function definePlugin(plugin) {
14823
14823
  return plugin;
14824
14824
  }
14825
14825
 
14826
+ // packages/core/src/plugin-services/host-rpc.ts
14827
+ import { AsyncLocalStorage } from "async_hooks";
14828
+
14829
+ // packages/core/src/plugin-services/wire-contract.ts
14830
+ var RPC_JSON_MAX_BYTES = 64 * 1024;
14831
+ var RPC_CONTRACT_MAX_BYTES = 256 * 1024;
14832
+ var RPC_CALL_PURPOSES = new Set(["bootstrap", "background", "management", "request", "attempt"]);
14833
+ var RPC_COMMAND_DEDUPLICATION = new Set(["local-transaction", "external-contract", "none"]);
14834
+ var RPC_COMMAND_POLICY_KEYS = new Set(["deduplication", "resultRetentionMs", "quotaBytes", "maxResultBytes"]);
14835
+
14836
+ // packages/core/src/plugin-services/rpc-runtime.ts
14837
+ var PROCESSES = new Set(["control", "worker", "ingress"]);
14838
+ var SCOPES = new Set(["global", "binding"]);
14839
+ var PURPOSES = new Set(["bootstrap", "background", "management", "request", "attempt"]);
14840
+ var ENDPOINTS = new WeakMap;
14841
+ var REVOKED = new WeakMap;
14842
+
14843
+ // packages/core/src/plugin-services/host-rpc.ts
14844
+ var SERVICE_ERROR_MESSAGES = {
14845
+ unauthorized: "RPC call is not authorized",
14846
+ not_ready: "RPC endpoint is not ready",
14847
+ retired: "RPC endpoint is retiring",
14848
+ revoked: "RPC endpoint generation was revoked",
14849
+ unsupported_method: "RPC method is not published",
14850
+ wrong_purpose: "RPC method is not published for this purpose",
14851
+ invalid_input: "RPC input is not valid",
14852
+ invalid_output: "RPC output is not valid",
14853
+ invalid_operation_id: "RPC command operation id is invalid",
14854
+ overloaded: "RPC runtime is at capacity",
14855
+ cancelled: "RPC call was cancelled",
14856
+ timeout: "RPC call deadline exceeded",
14857
+ unknown: "RPC command outcome is unknown",
14858
+ capability_unavailable: "RPC command execution is unavailable",
14859
+ closed: "RPC runtime is closed",
14860
+ failed: "RPC call failed",
14861
+ conflict: "RPC command identity conflicts with an existing record",
14862
+ expired: "RPC command result has expired",
14863
+ pending: "RPC command is still pending",
14864
+ rejected: "RPC command was rejected",
14865
+ missing: "RPC command has no stored result",
14866
+ storage_failure: "RPC command storage failed",
14867
+ deadlock: "RPC call chain would deadlock",
14868
+ call_depth_exceeded: "RPC call depth exceeded",
14869
+ undeclared: "RPC service is not declared by the manifest",
14870
+ unavailable: "RPC service is unavailable",
14871
+ ambiguous_placement: "RPC service placement is ambiguous",
14872
+ invalid_registration: "RPC registration is invalid"
14873
+ };
14874
+ var SERVICE_ERROR_CODES = new Set(Object.keys(SERVICE_ERROR_MESSAGES));
14875
+ var EMPTY_OPTIONS = Object.freeze({});
14876
+ var FRAME_STORE = new AsyncLocalStorage;
14877
+ var CALLEE_INFO = new WeakMap;
14878
+ // packages/core/src/plugin-services/peer-channel-protocol.ts
14879
+ var CHANNEL_REQUEST_MAX_BYTES = 4 * 1024;
14880
+ var CHANNEL_RESULT_MAX_BYTES = 60 * 1024;
14881
+ var CHANNEL_MAX_CHUNK_BYTES = 60 * 1024;
14882
+ var PLUGIN_CHANNEL_LANES = Object.freeze(["event", "snapshot", "stream"]);
14883
+ var ERROR_CODES = new Set([
14884
+ "unavailable",
14885
+ "ambiguous",
14886
+ "unauthorized",
14887
+ "invalid",
14888
+ "overloaded",
14889
+ "expired",
14890
+ "conflict",
14891
+ "gap",
14892
+ "truncated",
14893
+ "rejected",
14894
+ "cancelled",
14895
+ "closed",
14896
+ "unknown",
14897
+ "failed"
14898
+ ]);
14899
+ var RPC_CALL_PURPOSES2 = new Set(["bootstrap", "background", "management", "request", "attempt"]);
14900
+
14901
+ // packages/core/src/plugin-services/peer-channel-hub.ts
14902
+ var CHANNEL_MAX_TRANSFER_BUFFER_BYTES = 4 * CHANNEL_MAX_CHUNK_BYTES;
14903
+ var CHANNEL_MAX_TOTAL_BUFFER_BYTES = 16 * CHANNEL_MAX_CHUNK_BYTES;
14904
+ var CHANNEL_STREAM_MAX_TOTAL_BYTES = 64 * 1024 * 1024;
14905
+ var CHANNEL_STREAM_MAX_CREDIT_BYTES = 8 * CHANNEL_MAX_CHUNK_BYTES;
14906
+ var CHANNEL_STREAM_DEFAULT_CREDIT_BYTES = 4 * CHANNEL_MAX_CHUNK_BYTES;
14907
+ var CHANNEL_SNAPSHOT_MAX_BYTES = 64 * 1024 * 1024;
14908
+ var CHANNEL_EVENT_MAX_PAYLOAD_BYTES = 60 * 1024;
14909
+ var EMPTY = new Uint8Array(0);
14910
+ var HANDLE_REGISTRATIONS = new WeakMap;
14911
+
14912
+ // packages/core/src/plugin-services/snapshot-store.ts
14913
+ var DEFAULT_CHUNK_BYTES = 60 * 1024;
14914
+ var SNAPSHOT_FAMILY_REFS = new Map;
14915
+
14826
14916
  // packages/core/src/plugin-services.ts
14917
+ var CHANNEL_KINDS = new Set(["events", "snapshot", "stream"]);
14827
14918
  var TOKEN_METERING_SERVICE_ID = "token-metering.v1";
14828
14919
  var TOKEN_METERING_CONTRACT_VERSION = 1;
14829
14920
  var TOKEN_PRICING_SERVICE_ID = "token-stats.pricing.v1";
@@ -15089,6 +15180,38 @@ function withReportingWriteTimeout(db, operation) {
15089
15180
  }
15090
15181
  }
15091
15182
 
15183
+ // plugins/token-stats/server/model-mappings.ts
15184
+ var PRICE_MODEL_MAPPINGS_KEY = "pricing:model-mappings:v1";
15185
+ var MAX_PRICE_MODEL_MAPPINGS = 100;
15186
+ async function readPriceModelMappings(storage) {
15187
+ if (!storage.observation)
15188
+ return parsePriceModelMappings(await storage.get(PRICE_MODEL_MAPPINGS_KEY) ?? []);
15189
+ return storage.observation.withDatabase((db) => {
15190
+ const row = db.query("SELECT value, ttl FROM plugin_storage WHERE plugin_name = ? AND key = ?").get("token-stats", PRICE_MODEL_MAPPINGS_KEY);
15191
+ if (!row || row.ttl !== null && row.ttl < Math.floor(Date.now() / 1000))
15192
+ return [];
15193
+ return parsePriceModelMappings(JSON.parse(row.value));
15194
+ });
15195
+ }
15196
+ function parsePriceModelMappings(value) {
15197
+ if (!Array.isArray(value) || value.length > MAX_PRICE_MODEL_MAPPINGS)
15198
+ throw new Error("invalid_input");
15199
+ const sources = new Set;
15200
+ return value.map((item) => {
15201
+ if (!item || typeof item !== "object" || Array.isArray(item) || Object.keys(item).some((key) => !["source", "provider", "model"].includes(key)))
15202
+ throw new Error("invalid_input");
15203
+ const { source, provider, model } = item;
15204
+ for (const [text, limit] of [[source, 256], [provider, 128], [model, 256]]) {
15205
+ if (typeof text !== "string" || !text.trim() || text !== text.trim() || text.length > limit || /[\u0000-\u001f\u007f]/.test(text))
15206
+ throw new Error("invalid_input");
15207
+ }
15208
+ if (sources.has(source))
15209
+ throw new Error("invalid_input");
15210
+ sources.add(source);
15211
+ return { source, provider, model };
15212
+ });
15213
+ }
15214
+
15092
15215
  // plugins/token-stats/server/repository.ts
15093
15216
  var TOKEN_ACCOUNTING_AUTHORITIES = ["official", "local", "heuristic", "partial", "none"];
15094
15217
 
@@ -15098,6 +15221,9 @@ class TokenStatsRepositoryError extends Error {
15098
15221
  this.name = "TokenStatsRepositoryError";
15099
15222
  }
15100
15223
  }
15224
+ var MAX_CLIENT_MODEL_PAGE_SIZE = 100;
15225
+ var MAX_CLIENT_MODEL_PAGE = 400;
15226
+ var CLIENT_MODEL_KEYWORD_MAX = 256;
15101
15227
  var REPORTING_INCOMPLETE_KEY = "reporting:incomplete";
15102
15228
  var MAX_PENDING_ATTEMPTS = 256;
15103
15229
  var LOG_INTERVAL_MS = 60000;
@@ -15237,504 +15363,130 @@ class TokenStatsRepository {
15237
15363
  })).sort(groupBy === "model" ? (a, b) => b.inputTokens + b.outputTokens - a.inputTokens - a.outputTokens || b.upstreamAttempts - a.upstreamAttempts || a.dimension.localeCompare(b.dimension) : (a, b) => a.bucketStartMs - b.bucketStartMs || a.dimension.localeCompare(b.dimension))
15238
15364
  };
15239
15365
  }
15240
- }
15241
-
15242
- // node_modules/@tokenlens/fetch/dist/index.js
15243
- class FetchModelsError extends Error {
15244
- code;
15245
- status;
15246
- constructor(opts) {
15247
- super(opts.message);
15248
- this.name = "FetchModelsError";
15249
- this.code = opts.code;
15250
- this.status = opts.status;
15251
- }
15252
- }
15253
- async function fetchModels(opts = {}) {
15254
- if (typeof opts === "string") {
15255
- return fetchModels({ provider: opts });
15256
- }
15257
- const url = opts.baseUrl ?? "https://models.dev/api.json";
15258
- const fetchImpl = opts.fetch ?? globalThis.fetch;
15259
- if (typeof fetchImpl !== "function") {
15260
- throw new FetchModelsError({
15261
- code: "UNAVAILABLE",
15262
- message: "No fetch implementation found. Pass a custom `fetch` in options or run on a platform with global fetch (Node 18+, modern browsers)."
15366
+ async listClientModels(input = {}) {
15367
+ const pageSize = Math.max(1, Math.min(MAX_CLIENT_MODEL_PAGE_SIZE, Math.trunc(input.pageSize ?? 50)));
15368
+ const page = Math.max(1, Math.trunc(input.page ?? 1));
15369
+ if (!Number.isSafeInteger(page) || page > MAX_CLIENT_MODEL_PAGE)
15370
+ throw new TokenStatsRepositoryError("invalid token-stats page");
15371
+ const keyword = input.keyword;
15372
+ if (keyword !== undefined && (typeof keyword !== "string" || keyword.length > CLIENT_MODEL_KEYWORD_MAX)) {
15373
+ throw new TokenStatsRepositoryError("invalid token-stats keyword");
15374
+ }
15375
+ const observation = this.storage.observation;
15376
+ if (observation === undefined)
15377
+ throw new TokenStatsRepositoryError("token-stats observation storage is required");
15378
+ const since = Date.now() - TOKEN_STATS_RETENTION_MS;
15379
+ const hasKeyword = keyword !== undefined && keyword.length > 0;
15380
+ const escaped = hasKeyword ? keyword.replace(/[\\%_]/g, (character) => `\\${character}`) : null;
15381
+ return observation.withDatabase((db) => {
15382
+ const countSql = hasKeyword ? "SELECT COUNT(DISTINCT model) AS total FROM token_stats_attempts WHERE finished_at_ms >= ? AND model LIKE ? ESCAPE '\\'" : "SELECT COUNT(DISTINCT model) AS total FROM token_stats_attempts WHERE finished_at_ms >= ?";
15383
+ const totalRow = db.query(countSql).get(...hasKeyword ? [since, `%${escaped}%`] : [since]);
15384
+ const total = Number(totalRow?.total ?? 0);
15385
+ const pageSql = hasKeyword ? "SELECT DISTINCT model FROM token_stats_attempts WHERE finished_at_ms >= ? AND model LIKE ? ESCAPE '\\' ORDER BY model ASC LIMIT ? OFFSET ?" : "SELECT DISTINCT model FROM token_stats_attempts WHERE finished_at_ms >= ? ORDER BY model ASC LIMIT ? OFFSET ?";
15386
+ const rows = db.query(pageSql).all(...hasKeyword ? [since, `%${escaped}%`, pageSize, (page - 1) * pageSize] : [since, pageSize, (page - 1) * pageSize]);
15387
+ return {
15388
+ models: rows.map((row) => String(row.model)),
15389
+ total: Number.isSafeInteger(total) && total >= 0 ? total : 0,
15390
+ page,
15391
+ pageSize
15392
+ };
15263
15393
  });
15264
15394
  }
15265
- let res;
15266
- try {
15267
- res = await fetchImpl(url, opts.signal ? { signal: opts.signal } : undefined);
15268
- } catch (err) {
15269
- const message = err instanceof Error ? err.message : "Unknown network error";
15270
- throw new FetchModelsError({ code: "NETWORK", message });
15395
+ async mappings() {
15396
+ return readPriceModelMappings(this.storage);
15271
15397
  }
15272
- if (!res.ok) {
15273
- let body = "";
15274
- try {
15275
- body = await res.text();
15276
- } catch {}
15277
- const snippet = body ? ` Body: ${body.slice(0, 256)}${body.length > 256 ? "\u2026" : ""}` : "";
15278
- throw new FetchModelsError({
15279
- code: "HTTP",
15280
- status: res.status,
15281
- message: `Failed to fetch models.dev API (${res.status} ${res.statusText}).${snippet}`
15282
- });
15398
+ async configureMappings(mappings) {
15399
+ await this.storage.set(PRICE_MODEL_MAPPINGS_KEY, mappings);
15283
15400
  }
15284
- let data;
15285
- try {
15286
- data = await res.json();
15287
- } catch (err) {
15288
- const message = err instanceof Error ? err.message : "Invalid JSON";
15289
- throw new FetchModelsError({ code: "PARSE", message });
15290
- }
15291
- const catalog = data;
15292
- const { provider, model } = opts;
15293
- if (!provider && !model)
15294
- return catalog;
15295
- if (provider && !model)
15296
- return catalog[provider];
15297
- if (provider && model)
15298
- return catalog[provider]?.models?.[model];
15299
- const matches = [];
15300
- if (!model)
15301
- return matches;
15302
- for (const [provKey, prov] of Object.entries(catalog)) {
15303
- const m = prov?.models?.[model];
15304
- if (m)
15305
- matches.push({ provider: provKey, model: m });
15306
- }
15307
- return matches;
15308
- }
15309
-
15310
- // node_modules/@tokenlens/helpers/dist/context.js
15311
- var TOKENS_PER_MILLION = 1e6;
15312
- function normalizeUsage(usage) {
15313
- if (!usage)
15314
- return { input: 0, output: 0, total: 0 };
15315
- if (typeof usage.input === "number" && typeof usage.output === "number") {
15316
- const u = usage;
15317
- return {
15318
- input: u.input,
15319
- output: u.output,
15320
- total: u.total ?? u.input + u.output
15321
- };
15322
- }
15323
- const ul = usage;
15324
- const inputCandidates = [
15325
- ul.input_tokens,
15326
- ul.prompt_tokens,
15327
- ul.promptTokens,
15328
- ul.inputTokens
15329
- ].filter((v) => typeof v === "number");
15330
- const outputCandidates = [
15331
- ul.output_tokens,
15332
- ul.completion_tokens,
15333
- ul.completionTokens,
15334
- ul.outputTokens
15335
- ].filter((v) => typeof v === "number");
15336
- const totalCandidates = [
15337
- ul.total_tokens,
15338
- ul.totalTokens,
15339
- ul.totalTokens
15340
- ].filter((v) => typeof v === "number");
15341
- const input = inputCandidates[0] ?? 0;
15342
- const output = outputCandidates[0] ?? 0;
15343
- const total = totalCandidates[0];
15344
- if (total !== undefined)
15345
- return { input, output, total };
15346
- return { input, output, total: input + output };
15347
- }
15348
- function breakdownTokens(usage) {
15349
- if (!usage)
15350
- return {
15351
- input: 0,
15352
- output: 0,
15353
- total: 0,
15354
- cacheReads: 0,
15355
- cacheWrites: 0,
15356
- reasoningTokens: 0
15357
- };
15358
- if (typeof usage.input === "number" && typeof usage.output === "number" && (("cacheReads" in usage) || ("cacheWrites" in usage) || ("total" in usage))) {
15359
- const u0 = usage;
15360
- return {
15361
- input: u0.input,
15362
- output: u0.output,
15363
- total: u0.total ?? u0.input + u0.output,
15364
- cacheReads: u0.cacheReads,
15365
- cacheWrites: u0.cacheWrites,
15366
- reasoningTokens: u0.reasoningTokens
15367
- };
15368
- }
15369
- const base = normalizeUsage(usage);
15370
- const u = usage;
15371
- const cacheReadCandidates = [
15372
- u.cache_read_input_tokens,
15373
- u.cache_read_tokens,
15374
- u.prompt_cache_hit_tokens,
15375
- u.prompt_tokens_details?.cached_tokens,
15376
- u.promptTokensDetails?.cachedTokens,
15377
- u.cachedInputTokens,
15378
- u.cacheReads
15379
- ].filter((v) => typeof v === "number");
15380
- const cacheWriteCandidates = [
15381
- u.cache_creation_input_tokens,
15382
- u.cache_creation_tokens,
15383
- u.prompt_cache_write_tokens,
15384
- u.promptTokensDetails?.cacheCreationTokens,
15385
- u.cacheWrites
15386
- ].filter((v) => typeof v === "number");
15387
- const cacheReads = cacheReadCandidates[0];
15388
- const cacheWrites = cacheWriteCandidates[0];
15389
- const reasoningCandidates = [u.reasoning_tokens, u.reasoningTokens].filter((v) => typeof v === "number");
15390
- const reasoningTokens = reasoningCandidates[0];
15391
- return { ...base, cacheReads, cacheWrites, reasoningTokens };
15392
- }
15393
- function estimateCost({ modelId, usage, catalog }) {
15394
- const model = resolveModelFromCatalog(modelId, catalog);
15395
- if (!model?.pricing)
15396
- return {};
15397
- const base = normalizeUsage(usage);
15398
- const breakdown = breakdownTokens(usage);
15399
- const inputUSD = model.pricing.inputPerMTokens !== undefined ? base.input / TOKENS_PER_MILLION * model.pricing.inputPerMTokens : undefined;
15400
- const outputUSD = model.pricing.outputPerMTokens !== undefined ? base.output / TOKENS_PER_MILLION * model.pricing.outputPerMTokens : undefined;
15401
- const reasoningUSD = model.pricing.reasoningPerMTokens !== undefined && typeof breakdown.reasoningTokens === "number" ? breakdown.reasoningTokens / TOKENS_PER_MILLION * model.pricing.reasoningPerMTokens : undefined;
15402
- const cacheReadUSD = model.pricing.cacheReadPerMTokens !== undefined && typeof breakdown.cacheReads === "number" ? breakdown.cacheReads / TOKENS_PER_MILLION * model.pricing.cacheReadPerMTokens : undefined;
15403
- const cacheWriteUSD = model.pricing.cacheWritePerMTokens !== undefined && typeof breakdown.cacheWrites === "number" ? breakdown.cacheWrites / TOKENS_PER_MILLION * model.pricing.cacheWritePerMTokens : undefined;
15404
- const totalParts = [
15405
- inputUSD,
15406
- outputUSD,
15407
- reasoningUSD,
15408
- cacheReadUSD,
15409
- cacheWriteUSD
15410
- ].filter((v) => typeof v === "number");
15411
- const totalUSD = totalParts.length ? totalParts.reduce((a, b) => a + b, 0) : undefined;
15412
- return {
15413
- inputUSD,
15414
- outputUSD,
15415
- reasoningUSD,
15416
- cacheReadUSD,
15417
- cacheWriteUSD,
15418
- totalUSD
15419
- };
15420
- }
15421
- function resolveModelFromCatalog(idOrAlias, providers) {
15422
- if (!providers)
15423
- return;
15424
- const base = idOrAlias.trim().toLowerCase();
15425
- const candidates = [base];
15426
- if (base.includes("/")) {
15427
- const i = base.indexOf("/");
15428
- const p = base.slice(0, i);
15429
- const rest = base.slice(i + 1);
15430
- candidates.push(`${p}:${rest}`);
15431
- candidates.push(`${p}:${rest.replace(/(\d)\.(\d)/g, "$1-$2")}`);
15432
- }
15433
- if (base.includes(":")) {
15434
- const i = base.indexOf(":");
15435
- const p = base.slice(0, i);
15436
- const rest = base.slice(i + 1);
15437
- candidates.push(`${p}:${rest.replace(/(\d)\.(\d)/g, "$1-$2")}`);
15438
- }
15439
- if (!base.includes(":") && !base.includes("/")) {
15440
- candidates.push(base.replace(/(\d)\.(\d)/g, "$1-$2"));
15441
- }
15442
- for (const key of candidates) {
15443
- const idx = key.indexOf(":");
15444
- if (idx > 0) {
15445
- const providerKey = key.slice(0, idx);
15446
- const mid = key.slice(idx + 1);
15447
- for (const [provKey, prov] of iterateProviders(providers)) {
15448
- if (mid) {
15449
- const m = prov?.models?.[mid];
15450
- if (m && (provKey === providerKey || providerKey.length > 0))
15451
- return mapModelsDevEntry(provKey, mid, m, prov);
15452
- }
15453
- }
15454
- }
15455
- for (const [provKey, prov] of iterateProviders(providers)) {
15456
- const m = prov?.models?.[key];
15457
- if (m)
15458
- return mapModelsDevEntry(provKey, key, m, prov);
15459
- }
15460
- }
15461
- return;
15462
- }
15463
- function mapModelsDevEntry(provider, modelId, m, prov) {
15464
- const inputMods = Array.isArray(m?.modalities?.input) ? m.modalities?.input : [];
15465
- const outputMods = Array.isArray(m?.modalities?.output) ? m.modalities?.output : [];
15466
- const textIn = inputMods.includes("text");
15467
- const imageIn = inputMods.includes("image");
15468
- const textOut = outputMods.includes("text");
15469
- const combinedMax = typeof m?.limit?.context === "number" ? m.limit.context : undefined;
15470
- const inputMax = typeof m?.limit?.input === "number" ? m.limit.input : undefined;
15471
- const outputMax = typeof m?.limit?.output === "number" ? m.limit.output : undefined;
15472
- const pricing = m?.cost && (typeof m.cost.input === "number" || typeof m.cost.output === "number" || typeof m.cost.reasoning === "number" || typeof m.cost.cache_read === "number" || typeof m.cost.cache_write === "number") ? {
15473
- ...typeof m.cost.input === "number" ? { inputPerMTokens: m.cost.input } : {},
15474
- ...typeof m.cost.output === "number" ? { outputPerMTokens: m.cost.output } : {},
15475
- ...typeof m.cost.reasoning === "number" ? { reasoningPerMTokens: m.cost.reasoning } : {},
15476
- ...typeof m.cost.cache_read === "number" ? { cacheReadPerMTokens: m.cost.cache_read } : {},
15477
- ...typeof m.cost.cache_write === "number" ? { cacheWritePerMTokens: m.cost.cache_write } : {}
15478
- } : undefined;
15479
- return {
15480
- id: `${provider}:${modelId}`,
15481
- provider,
15482
- vendorId: modelId,
15483
- displayName: m?.name || modelId,
15484
- family: modelId,
15485
- status: "stable",
15486
- context: Object.fromEntries(Object.entries({ combinedMax, inputMax, outputMax }).filter(([, v]) => typeof v === "number")),
15487
- modalities: textIn || textOut || imageIn ? {
15488
- ...textIn && { textIn: true },
15489
- ...textOut && { textOut: true },
15490
- ...imageIn && { imageIn: true }
15491
- } : undefined,
15492
- pricing,
15493
- pricingSource: "models.dev",
15494
- aliases: [`${provider}/${modelId}`],
15495
- releasedAt: m?.release_date || undefined,
15496
- source: prov?.doc || prov.docs || "https://models.dev",
15497
- contextSource: prov?.doc || prov.docs || undefined,
15498
- verifiedAt: m?.last_updated || undefined
15499
- };
15500
- }
15501
- function* iterateProviders(providers) {
15502
- if (providers?.models) {
15503
- const p = providers;
15504
- const key = p.id || "provider";
15505
- yield [key, p];
15506
- return;
15507
- }
15508
- for (const [key, prov] of Object.entries(providers)) {
15509
- yield [key, prov];
15510
- }
15511
- }
15512
-
15513
- // node_modules/@tokenlens/helpers/dist/simple.js
15514
- function costFromUsage(args) {
15515
- const c = estimateCost({
15516
- modelId: args.id,
15517
- usage: args.usage,
15518
- catalog: args.catalog
15519
- });
15520
- return c.totalUSD;
15521
- }
15522
-
15523
- // plugins/token-stats/server/price-catalog.ts
15524
- var PRICE_CACHE_KEY = "pricing:catalog:v1";
15525
- var PRICE_STATUS_KEY = "pricing:status:v1";
15526
- function pricedCatalog(value) {
15527
- if (!value || typeof value !== "object")
15528
- throw new Error("invalid_catalog");
15529
- const input = value;
15530
- const output = {};
15531
- let count = 0;
15532
- for (const id of ["openai", "anthropic", "google", "xai"]) {
15533
- const provider = input[id];
15534
- if (!provider?.models || typeof provider.models !== "object")
15535
- continue;
15536
- const models = {};
15537
- for (const [modelId, model] of Object.entries(provider.models)) {
15538
- const cost = model?.cost;
15539
- if (!cost || typeof cost.input !== "number" || !Number.isFinite(cost.input) || cost.input < 0 || typeof cost.output !== "number" || !Number.isFinite(cost.output) || cost.output < 0)
15540
- continue;
15541
- if (++count > 1e4)
15542
- throw new Error("invalid_catalog");
15543
- Object.defineProperty(models, modelId, { value: { id: modelId, name: model.name, cost }, enumerable: true });
15544
- }
15545
- if (Object.keys(models).length)
15546
- output[id] = { id, name: provider.name, models };
15547
- }
15548
- if (!count)
15549
- throw new Error("invalid_catalog");
15550
- return output;
15551
15401
  }
15552
15402
 
15553
15403
  // plugins/token-stats/server/pricing.ts
15554
- var DIRECT_PROVIDERS = new Set(["openai", "anthropic", "google", "xai"]);
15555
- var DEFAULT_TIMEOUT_MS = 4000;
15556
- var DEFAULT_REFRESH_MS = 60 * 60 * 1000;
15557
- function isDirectProvider(value) {
15558
- return DIRECT_PROVIDERS.has(value);
15404
+ var TOKENS_PER_UNIT = 1e6;
15405
+ function isNonNegativeInteger(value) {
15406
+ return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
15559
15407
  }
15560
- function isNonNegativeNumber(value) {
15561
- return typeof value === "number" && Number.isFinite(value) && value >= 0;
15562
- }
15563
- function exactModel(model, providerHint, catalog) {
15564
- const delimiterIndex = [model.indexOf(":"), model.indexOf("/")].filter((index) => index > 0).sort((a, b) => a - b)[0];
15565
- const prefixedProvider = delimiterIndex === undefined ? undefined : model.slice(0, delimiterIndex);
15566
- const modelId = delimiterIndex === undefined ? model : model.slice(delimiterIndex + 1);
15567
- if (!modelId)
15568
- return;
15569
- if (prefixedProvider === undefined && providerHint === undefined) {
15570
- const matches = [...DIRECT_PROVIDERS].filter((provider) => catalog[provider]?.models?.[modelId]);
15571
- if (matches.length !== 1)
15572
- return;
15573
- const provider = matches[0];
15574
- return { provider, modelId, entry: catalog[provider].models[modelId] };
15575
- }
15576
- const provider = prefixedProvider ?? providerHint;
15577
- if (!provider || !isDirectProvider(provider) || !modelId)
15578
- return;
15579
- const entry = catalog[provider]?.models?.[modelId];
15580
- return entry ? { provider, modelId, entry } : undefined;
15581
- }
15582
- function hasTieredPricing(cost) {
15583
- return Object.keys(cost).some((key) => /context|tier|over_\d/i.test(key));
15584
- }
15585
- function calculateTokenStatsCost(catalog, input) {
15586
- const { model, inputTokens, outputTokens } = input;
15587
- if (!catalog || !model || !Number.isSafeInteger(inputTokens) || inputTokens < 0 || !Number.isSafeInteger(outputTokens) || outputTokens < 0)
15588
- return null;
15589
- const match = exactModel(model, input.provider, catalog);
15590
- if (!match)
15591
- return null;
15592
- const rawCost = match.entry.cost;
15593
- if (!rawCost || !isNonNegativeNumber(rawCost.input) || !isNonNegativeNumber(rawCost.output))
15594
- return null;
15595
- if (hasTieredPricing(rawCost) && inputTokens >= 200000)
15408
+ function costOf(match, input) {
15409
+ const inputTokens = input.inputTokens;
15410
+ const outputTokens = input.outputTokens;
15411
+ if (!isNonNegativeInteger(inputTokens) || !isNonNegativeInteger(outputTokens))
15596
15412
  return null;
15597
15413
  const cacheReads = input.cacheReadTokens ?? 0;
15598
15414
  const cacheWrites = input.cacheWriteTokens ?? 0;
15599
- if (!Number.isSafeInteger(cacheReads) || cacheReads < 0 || !Number.isSafeInteger(cacheWrites) || cacheWrites < 0 || cacheReads + cacheWrites > inputTokens)
15600
- return null;
15601
- if (cacheReads > 0 && !isNonNegativeNumber(rawCost.cache_read))
15415
+ if (!isNonNegativeInteger(cacheReads) || !isNonNegativeInteger(cacheWrites) || cacheReads + cacheWrites > inputTokens)
15602
15416
  return null;
15603
- if (cacheWrites > 0 && !isNonNegativeNumber(rawCost.cache_write))
15604
- return null;
15605
- const restrictedCatalog = {
15606
- [match.provider]: { ...catalog[match.provider], models: { [match.modelId]: match.entry } }
15607
- };
15608
- try {
15609
- const cost = costFromUsage({
15610
- id: `${match.provider}:${match.modelId}`,
15611
- catalog: restrictedCatalog,
15612
- usage: {
15613
- input: inputTokens - cacheReads - cacheWrites,
15614
- output: outputTokens,
15615
- ...cacheReads > 0 ? { cacheReads } : {},
15616
- ...cacheWrites > 0 ? { cacheWrites } : {}
15617
- }
15618
- });
15619
- return isNonNegativeNumber(cost) ? cost : null;
15620
- } catch {
15417
+ let rates = match;
15418
+ for (const tier of match.contextTiers ?? []) {
15419
+ if (inputTokens < tier.minimumInputTokens)
15420
+ break;
15421
+ rates = tier;
15422
+ }
15423
+ const cacheRead = rates.cacheRead ?? match.cacheRead ?? rates.input;
15424
+ const cacheWrite = rates.cacheWrite ?? match.cacheWrite ?? rates.input;
15425
+ const baseInput = inputTokens - cacheReads - cacheWrites;
15426
+ const total = baseInput * rates.input + outputTokens * rates.output + cacheReads * cacheRead + cacheWrites * cacheWrite;
15427
+ const cost = total / TOKENS_PER_UNIT;
15428
+ return Number.isFinite(cost) && cost >= 0 ? cost : null;
15429
+ }
15430
+ function calculateTokenStatsCost(catalog, input, mappings = []) {
15431
+ if (catalog === null || typeof input.model !== "string" || input.model.length === 0)
15621
15432
  return null;
15622
- }
15433
+ const mapping = mappings.find((item) => item.source === input.model);
15434
+ if (mapping !== undefined) {
15435
+ const target = catalog.resolveModel({ model: mapping.model, pricingProvider: mapping.provider });
15436
+ return target === null ? null : costOf(target, input);
15437
+ }
15438
+ const match = catalog.resolveModel({
15439
+ model: input.model,
15440
+ mode: "estimate",
15441
+ ...input.provider === undefined ? {} : { pricingProvider: input.provider },
15442
+ ...input.url === undefined ? {} : { url: input.url }
15443
+ });
15444
+ return match === null ? null : costOf(match, input);
15623
15445
  }
15624
15446
 
15625
15447
  class TokenStatsPricing {
15626
- options;
15627
15448
  catalog;
15628
- interval;
15629
- inFlight;
15630
- controller;
15631
- initialLoadStarted = false;
15632
- initialLoadReady = Promise.resolve();
15633
- cacheTimestamp = null;
15634
- constructor(options = {}) {
15635
- this.options = options;
15636
- }
15637
- start() {
15638
- if (this.options.storage) {
15639
- this.initialLoadReady = this.readCache();
15640
- return;
15641
- }
15642
- if (this.interval !== undefined)
15643
- return;
15644
- this.refresh();
15645
- this.interval = setInterval(() => {
15646
- this.refresh();
15647
- }, this.options.refreshMs ?? DEFAULT_REFRESH_MS);
15648
- }
15649
- stop() {
15650
- if (this.interval !== undefined)
15651
- clearInterval(this.interval);
15652
- this.interval = undefined;
15653
- this.controller?.abort();
15654
- }
15655
- async refresh() {
15656
- if (this.inFlight)
15657
- return this.inFlight;
15658
- const task = this.loadCatalog();
15659
- this.inFlight = task;
15660
- if (!this.initialLoadStarted) {
15661
- this.initialLoadStarted = true;
15662
- this.initialLoadReady = this.waitForInitialLoad(task);
15663
- }
15664
- try {
15665
- return await task;
15666
- } finally {
15667
- if (this.inFlight === task)
15668
- this.inFlight = undefined;
15669
- }
15449
+ mappings = [];
15450
+ constructor(catalog) {
15451
+ this.catalog = catalog;
15670
15452
  }
15671
- ready() {
15672
- if (this.options.storage)
15673
- return this.readCache();
15674
- return this.initialLoadReady;
15453
+ setMappings(mappings) {
15454
+ this.mappings = mappings;
15675
15455
  }
15676
- async readCache() {
15677
- try {
15678
- const status = await this.options.storage.get(PRICE_STATUS_KEY);
15679
- if (this.catalog && status?.lastSuccessAt === this.cacheTimestamp)
15680
- return;
15681
- const cache = await this.options.storage.get(PRICE_CACHE_KEY);
15682
- if (cache?.version !== 1 || !Number.isFinite(cache.fetchedAt) || cache.fetchedAt === this.cacheTimestamp)
15683
- return;
15684
- this.catalog = pricedCatalog(cache.catalog);
15685
- this.cacheTimestamp = cache.fetchedAt;
15686
- } catch {}
15456
+ hasMappings() {
15457
+ return this.mappings !== undefined;
15687
15458
  }
15688
15459
  estimate(input) {
15689
- return calculateTokenStatsCost(this.catalog, input);
15690
- }
15691
- async loadCatalog() {
15692
- const controller = new AbortController;
15693
- this.controller = controller;
15694
- let timeout;
15695
- try {
15696
- const fetch = fetchModels(this.options.fetch ? { fetch: this.options.fetch, signal: controller.signal } : { signal: controller.signal });
15697
- const timeoutFailure = new Promise((_resolve, reject) => {
15698
- timeout = setTimeout(() => {
15699
- controller.abort();
15700
- reject(new Error("TokenLens catalog request timed out"));
15701
- }, this.options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
15702
- });
15703
- const catalog = await Promise.race([fetch, timeoutFailure]);
15704
- if (!catalog || typeof catalog !== "object")
15705
- return false;
15706
- this.catalog = catalog;
15707
- return true;
15708
- } catch {
15709
- return false;
15710
- } finally {
15711
- if (timeout !== undefined)
15712
- clearTimeout(timeout);
15713
- if (this.controller === controller)
15714
- this.controller = undefined;
15715
- }
15460
+ if (this.mappings === undefined)
15461
+ return null;
15462
+ return calculateTokenStatsCost(this.catalog, input, this.mappings);
15716
15463
  }
15717
- async waitForInitialLoad(task) {
15718
- let timeout;
15719
- try {
15720
- await Promise.race([
15721
- task.then(() => {
15722
- return;
15723
- }, () => {
15724
- return;
15725
- }),
15726
- new Promise((resolve) => {
15727
- timeout = setTimeout(resolve, this.options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
15728
- })
15729
- ]);
15730
- } finally {
15731
- if (timeout !== undefined)
15732
- clearTimeout(timeout);
15733
- }
15464
+ ready() {
15465
+ return Promise.resolve();
15734
15466
  }
15735
15467
  }
15736
15468
 
15469
+ // plugins/models-dev/contract.ts
15470
+ var MODELS_DEV_CATALOG_SERVICE_ID = "models-dev.catalog.v1";
15471
+ var MODELS_DEV_CATALOG_CONTRACT_VERSION = 1;
15472
+ var MODELS_DEV_CATALOG_SNAPSHOT_ID = "models-dev.catalog.snapshot.v1";
15473
+ var MODELS_DEV_CATALOG_SNAPSHOT_CONTRACT_VERSION = 1;
15474
+ var MODELS_DEV_CATALOG_SNAPSHOT_SCHEMA = Object.freeze({
15475
+ type: "object",
15476
+ properties: {
15477
+ version: { type: "number", integer: true, minimum: 1 },
15478
+ fetchedAt: { type: "number", minimum: 0 },
15479
+ catalog: { type: "json", maxBytes: 32 * 1024 * 1024 }
15480
+ }
15481
+ });
15482
+ var MODELS_DEV_CATALOG_SNAPSHOT_CONTRACT = Object.freeze({
15483
+ id: MODELS_DEV_CATALOG_SNAPSHOT_ID,
15484
+ version: MODELS_DEV_CATALOG_SNAPSHOT_CONTRACT_VERSION,
15485
+ content: MODELS_DEV_CATALOG_SNAPSHOT_SCHEMA
15486
+ });
15487
+
15737
15488
  // plugins/token-stats/server/index.ts
15489
+ var MAPPING_REFRESH_INTERVAL_MS = 1e4;
15738
15490
  function rowFromResult(result) {
15739
15491
  const inputKnown = result.outcome === "completed" || result.inputSource === "official";
15740
15492
  const outputKnown = result.outcome === "completed" || result.outputSource === "official";
@@ -15767,14 +15519,7 @@ class TokenStatsPricingService {
15767
15519
  this.pricing = pricing;
15768
15520
  }
15769
15521
  canPrice = async (input) => {
15770
- await this.pricing.ready().catch(() => {});
15771
- const cost = this.pricing.estimate({
15772
- model: input.model,
15773
- provider: input.pricingProvider,
15774
- inputTokens: 0,
15775
- outputTokens: 0
15776
- });
15777
- return cost !== null && Number.isFinite(cost) && cost >= 0;
15522
+ return this.pricing.estimate({ model: input.model, provider: input.pricingProvider, inputTokens: 0, outputTokens: 0 }) !== null;
15778
15523
  };
15779
15524
  price = (result) => {
15780
15525
  const row = rowFromResult(result);
@@ -15793,7 +15538,6 @@ class TokenStatsPricingService {
15793
15538
  if (existing)
15794
15539
  return existing;
15795
15540
  const pending = Promise.resolve().then(async () => {
15796
- await this.pricing.ready().catch(() => {});
15797
15541
  const raw = this.pricing.estimate({
15798
15542
  model: result.model,
15799
15543
  provider: result.pricingProvider,
@@ -15812,16 +15556,48 @@ class TokenStatsPricingService {
15812
15556
  return pending;
15813
15557
  };
15814
15558
  }
15559
+
15560
+ class MappingCache {
15561
+ load;
15562
+ mappings = undefined;
15563
+ loadedAt = 0;
15564
+ inFlight = false;
15565
+ constructor(load) {
15566
+ this.load = load;
15567
+ }
15568
+ current() {
15569
+ return this.mappings;
15570
+ }
15571
+ async refresh(now = Date.now()) {
15572
+ if (this.inFlight)
15573
+ return;
15574
+ this.inFlight = true;
15575
+ try {
15576
+ this.mappings = await this.load();
15577
+ this.loadedAt = now;
15578
+ } catch {
15579
+ this.mappings = undefined;
15580
+ } finally {
15581
+ this.inFlight = false;
15582
+ }
15583
+ }
15584
+ maybeRefresh(now = Date.now()) {
15585
+ if (this.inFlight || now - this.loadedAt < MAPPING_REFRESH_INTERVAL_MS)
15586
+ return;
15587
+ this.refresh(now);
15588
+ }
15589
+ }
15815
15590
  var TokenStatsPlugin = definePlugin(class {
15816
15591
  pricingFactory;
15817
15592
  static name = "token-stats";
15818
- static version = "3.2.0";
15593
+ static version = "4.0.0";
15819
15594
  storage;
15820
15595
  logger;
15821
15596
  repository;
15822
15597
  pricing;
15823
15598
  reportingIncomplete = false;
15824
15599
  unsubscribe;
15600
+ mappingRefresh;
15825
15601
  markReportingIncomplete() {
15826
15602
  if (this.reportingIncomplete)
15827
15603
  return;
@@ -15844,19 +15620,34 @@ var TokenStatsPlugin = definePlugin(class {
15844
15620
  constructor(_config = {}, pricingFactory) {
15845
15621
  this.pricingFactory = pricingFactory;
15846
15622
  }
15623
+ applyMappings(mappings) {
15624
+ if (typeof this.pricing.setMappings === "function")
15625
+ this.pricing.setMappings(mappings);
15626
+ }
15847
15627
  async init(context) {
15848
15628
  if (!context.services)
15849
15629
  throw new Error("token-stats requires token-metering service");
15850
15630
  const metering = context.services.consume("token-metering", TOKEN_METERING_SERVICE_ID, TOKEN_METERING_CONTRACT_VERSION);
15631
+ let catalog = null;
15632
+ try {
15633
+ catalog = context.services.consume("models-dev", MODELS_DEV_CATALOG_SERVICE_ID, MODELS_DEV_CATALOG_CONTRACT_VERSION);
15634
+ } catch {
15635
+ catalog = null;
15636
+ }
15851
15637
  this.storage = context.storage.uncached?.() ?? context.storage;
15852
15638
  this.logger = context.logger;
15853
15639
  this.repository = new TokenStatsRepository(context.storage);
15854
- this.pricing = this.pricingFactory?.() ?? new TokenStatsPricing({ storage: this.storage });
15640
+ this.pricing = this.pricingFactory?.() ?? new TokenStatsPricing(catalog);
15641
+ const mappings = new MappingCache(() => this.repository.mappings());
15642
+ await mappings.refresh();
15643
+ this.applyMappings(mappings.current());
15855
15644
  const pricingService = new TokenStatsPricingService(this.pricing);
15856
15645
  context.services.publish(TOKEN_PRICING_SERVICE_ID, TOKEN_PRICING_CONTRACT_VERSION, { canPrice: pricingService.canPrice, price: pricingService.price });
15857
15646
  this.unsubscribe = metering.subscribe({
15858
15647
  onResult: (result) => {
15859
15648
  const row = rowFromResult(result);
15649
+ mappings.maybeRefresh();
15650
+ this.applyMappings(mappings.current());
15860
15651
  const price = pricingService.price(result);
15861
15652
  price.catch(() => {});
15862
15653
  const accepted = this.repository.enqueueAttempt(async () => {
@@ -15884,18 +15675,24 @@ var TokenStatsPlugin = definePlugin(class {
15884
15675
  this.markReportingIncomplete();
15885
15676
  }
15886
15677
  });
15678
+ this.mappingRefresh = setInterval(() => {
15679
+ mappings.refresh().then(() => this.applyMappings(mappings.current()));
15680
+ }, MAPPING_REFRESH_INTERVAL_MS);
15681
+ if (typeof this.mappingRefresh.unref === "function")
15682
+ this.mappingRefresh.unref();
15887
15683
  context.services.onDispose(() => {
15888
15684
  this.unsubscribe?.();
15889
15685
  this.unsubscribe = undefined;
15890
15686
  });
15891
- this.pricing.start();
15892
15687
  this.logger.info("TokenStatsPlugin initialized");
15893
15688
  }
15894
15689
  register(_hooks) {}
15895
15690
  async onDestroy() {
15896
15691
  this.unsubscribe?.();
15897
15692
  this.unsubscribe = undefined;
15898
- this.pricing?.stop();
15693
+ if (this.mappingRefresh !== undefined)
15694
+ clearInterval(this.mappingRefresh);
15695
+ this.mappingRefresh = undefined;
15899
15696
  this.logger?.info("TokenStatsPlugin destroyed");
15900
15697
  }
15901
15698
  });
@@ -15906,4 +15703,4 @@ export {
15906
15703
  server_default as default
15907
15704
  };
15908
15705
 
15909
- //# debugId=E23970FB349FF94664756E2164756E21
15706
+ //# debugId=667505D0D6B6158D64756E2164756E21