@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
@@ -0,0 +1,16 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../plugins/models-dev/contract.ts", "../../../../../plugins/models-dev/server/model-names.ts", "../../../../../plugins/models-dev/server/catalog.ts", "../../../../../plugins/models-dev/server/download.ts", "../../../../../plugins/models-dev/server/local.ts", "../../../../../plugins/models-dev/server/store.ts", "../../../../../plugins/models-dev/server/control.ts"],
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",
6
+ "/** Name-only heuristics: prices always come from the current catalog. */\nfunction resourceName(name: string): string {\n return name.replace(/^(?:projects\\/[^/]+\\/locations\\/[^/]+\\/)?publishers\\/google\\/models\\//, '')\n .replace(/^models\\//, '');\n}\n\nfunction claudeVersion(name: string): string {\n return name.replace(/^(claude-(?:(?:opus|sonnet|haiku)-)?\\d+)-(\\d+)(?=-|$)/, '$1.$2');\n}\n\nfunction withoutDate(name: string): string {\n return name.replace(/-(?:\\d{8}|\\d{4}-\\d{2}-\\d{2})$/, '');\n}\n\nfunction withoutEffort(name: string): string {\n return name.replace(/-(?:minimal|low|medium|high|xhigh)$/, '');\n}\n\nfunction withoutPreview(name: string): string {\n return name.replace(/-(?:latest|preview|exp)$/, '');\n}\n\n/** At most 32 candidates, including combined date/effort suffixes. */\nexport function estimateNames(model: string): readonly string[] {\n const names = new Set([model.trim().toLowerCase()]);\n const transforms = [resourceName, claudeVersion, withoutDate, withoutEffort, withoutPreview];\n for (const name of names) {\n for (const transform of transforms) {\n const candidate = transform(name);\n if (candidate && names.size < 32) names.add(candidate);\n }\n }\n return [...names];\n}\n\nexport function canonicalModelName(model: string): string {\n return claudeVersion(resourceName(model.trim().toLowerCase()));\n}\n\nexport function modelFamily(model: string): string {\n let name = canonicalModelName(model);\n // Each pass removes a suffix; the length bound also bounds this loop.\n for (;;) {\n const next = withoutPreview(withoutEffort(withoutDate(name)));\n if (next === name) return name;\n name = next;\n }\n}\n\nexport function modelDate(model: string): string {\n return model.toLowerCase().match(/-(\\d{8}|\\d{4}-\\d{2}-\\d{2})(?:-(?:minimal|low|medium|high|xhigh|latest|preview|exp))*$/)?.[1]?.replaceAll('-', '') ?? '';\n}\n\nexport function originalLab(model: string): string | null {\n const name = resourceName(model.trim().toLowerCase());\n if (/^(?:gpt-|o\\d+(?:-|$))/.test(name)) return 'openai';\n if (name.startsWith('claude-')) return 'anthropic';\n if (name.startsWith('gemini-')) return 'google';\n if (name.startsWith('grok-')) return 'xai';\n return null;\n}\n",
7
+ "/**\n * Internal catalog representation for models-dev.\n *\n * It is derived from the full models.dev JSON with no trimming: providers without\n * price data are kept, every model field stays addressable and `provider.api` is\n * preserved for URL-based provider resolution. This module is provider-internal;\n * consumers only see the public `contract.ts` service.\n */\n\nimport type {\n ModelsDevCatalogStatus,\n ModelsDevCatalogService,\n ModelsDevContextTier,\n ModelsDevModelMatch,\n ModelsDevModelOption,\n ModelsDevModelPage,\n ModelsDevProviderMatch,\n ModelsDevProviderSummary,\n} from '../contract';\nimport { canonicalModelName, estimateNames, modelDate, modelFamily, originalLab } from './model-names';\n\nexport const MAX_PROVIDERS = 4_096;\nexport const MAX_MODELS_PER_PROVIDER = 16_384;\nexport const MAX_MODEL_OPTION_PAGE_SIZE = 100;\n/** Bounded full-catalog scan budget (the real catalog has ~8.4k models). */\nexport const MAX_RESOLVE_CANDIDATES = 20_000;\n\nexport interface NormalizedPrice {\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\ninterface CatalogModel {\n readonly id: string;\n readonly name: string;\n readonly price: NormalizedPrice | null;\n /** Raw model entry, retained so every original field stays reachable. */\n readonly raw: unknown;\n}\n\ninterface CatalogProvider {\n readonly id: string;\n readonly name: string;\n readonly api: string | null;\n readonly apiHost: string | null;\n readonly apiPathSegments: readonly string[] | null;\n readonly models: Map<string, CatalogModel>;\n readonly lowerModels: ReadonlyMap<string, CatalogModel | null>;\n readonly familyModels: ReadonlyMap<string, CatalogModel>;\n readonly raw: unknown;\n}\n\nexport interface CatalogIndex {\n readonly version: number;\n readonly fetchedAt: number;\n readonly providers: readonly CatalogProvider[];\n readonly byProvider: ReadonlyMap<string, CatalogProvider>;\n readonly modelCount: number;\n readonly exactModels: ReadonlyMap<string, ModelsDevModelMatch | null>;\n readonly lowerModels: ReadonlyMap<string, ModelsDevModelMatch | null>;\n readonly familyModels: ReadonlyMap<string, ModelsDevModelMatch | null>;\n readonly byApiHost: ReadonlyMap<string, readonly CatalogProvider[]>;\n}\n\nexport interface CatalogRecord {\n readonly version: number;\n readonly fetchedAt: number;\n readonly catalog: unknown;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction finiteNonNegative(value: unknown): number | null {\n return typeof value === 'number' && Number.isFinite(value) && value >= 0 ? value : null;\n}\n\nfunction contextTier(cost: unknown, minimumInputTokens: number): ModelsDevContextTier | null {\n if (!isRecord(cost) || !Number.isSafeInteger(minimumInputTokens) || minimumInputTokens < 0) return null;\n const input = finiteNonNegative(cost.input);\n const output = finiteNonNegative(cost.output);\n if (input === null || output === null) return null;\n return Object.freeze({ minimumInputTokens, input, output,\n cacheRead: finiteNonNegative(cost.cache_read), cacheWrite: finiteNonNegative(cost.cache_write) });\n}\n\nfunction contextTiers(cost: Record<string, unknown>): readonly ModelsDevContextTier[] {\n if (Array.isArray(cost.tiers) && cost.tiers.length > 0) {\n const tiers: ModelsDevContextTier[] = [];\n const thresholds = new Set<number>();\n for (const value of cost.tiers) {\n const tier = isRecord(value) && isRecord(value.tier)\n && (value.tier.type === undefined || value.tier.type === 'context')\n ? contextTier(value, value.tier.size as number) : null;\n if (tier === null || thresholds.has(tier.minimumInputTokens)) { tiers.length = 0; break; }\n thresholds.add(tier.minimumInputTokens);\n tiers.push(tier);\n }\n if (tiers.length > 0) return Object.freeze(tiers.sort((a, b) => a.minimumInputTokens - b.minimumInputTokens));\n }\n // Legacy over-200k is strictly greater, represented as an inclusive integer band.\n const legacy = contextTier(cost.context_over_200k, 200_001);\n return Object.freeze(legacy === null ? [] : [legacy]);\n}\n\n/** Preserve base prices and canonical context bands, using legacy output only as fallback. */\nexport function normalizePrice(cost: unknown): NormalizedPrice | null {\n if (!isRecord(cost)) return null;\n const input = finiteNonNegative(cost.input);\n const output = finiteNonNegative(cost.output);\n if (input === null || output === null) return null;\n const tiered = 'tiers' in cost || 'context_over_200k' in cost;\n return Object.freeze({\n input,\n output,\n cacheRead: finiteNonNegative(cost.cache_read),\n cacheWrite: finiteNonNegative(cost.cache_write),\n tiered,\n contextTiers: contextTiers(cost),\n });\n}\n\n/** Split an API base into lowercase host + path segments; `${...}` segments are wildcards. */\nfunction parseApiBase(api: unknown): { host: string; pathSegments: string[] } | null {\n if (typeof api !== 'string' || api.length === 0 || api.length > 2_048) return null;\n let parsed: URL;\n try { parsed = new URL(api.replace(/\\$\\{[^}]*\\}/g, 'wildcard')); } catch { return null; }\n const host = parsed.hostname.toLowerCase();\n if (!host) return null;\n const pathSegments = parsed.pathname.split('/').filter(Boolean).map(segment => segment.toLowerCase());\n return { host, pathSegments };\n}\n\nfunction pathMatches(template: readonly string[], request: readonly string[]): boolean {\n if (template.length > request.length) return false;\n for (let index = 0; index < template.length; index += 1) {\n if (template[index] !== '*' && template[index] !== request[index]) return false;\n }\n return true;\n}\n\nfunction nameIndexes(models: ReadonlyMap<string, CatalogModel>): Pick<CatalogProvider, 'lowerModels' | 'familyModels'> {\n const lowerModels = new Map<string, CatalogModel | null>();\n const familyModels = new Map<string, CatalogModel>();\n for (const model of models.values()) {\n if (model.price === null) continue;\n for (const lower of new Set([model.id.toLowerCase(), canonicalModelName(model.id)])) {\n lowerModels.set(lower, lowerModels.has(lower) ? null : model);\n }\n const family = modelFamily(model.id);\n const current = familyModels.get(family);\n // A canonical undated base wins; otherwise newest dated version, then stable ID.\n const rank = (entry: CatalogModel): string => `${canonicalModelName(entry.id) === family ? '1' : '0'}:${modelDate(entry.id)}`;\n if (current === undefined || rank(model) > rank(current)\n || (rank(model) === rank(current) && model.id < current.id)) familyModels.set(family, model);\n }\n return { lowerModels, familyModels };\n}\n\n/** Build all lookup indexes on refresh, never in the synchronous request path. */\nexport function buildCatalogIndex(record: CatalogRecord): CatalogIndex {\n if (!isRecord(record.catalog)) throw new Error('models-dev catalog record is invalid');\n const providers: CatalogProvider[] = [];\n const byProvider = new Map<string, CatalogProvider>();\n let modelCount = 0;\n for (const [providerKey, providerValue] of Object.entries(record.catalog)) {\n if (!isRecord(providerValue)) continue;\n if (providers.length >= MAX_PROVIDERS) throw new Error('models-dev catalog exceeds the provider budget');\n const id = typeof providerValue.id === 'string' && providerValue.id.trim() ? providerValue.id.trim() : providerKey.trim();\n if (!id || id.length > 256) continue;\n const name = typeof providerValue.name === 'string' && providerValue.name.trim() ? providerValue.name.trim() : id;\n const parsedApi = parseApiBase(providerValue.api);\n const models = new Map<string, CatalogModel>();\n if (isRecord(providerValue.models)) {\n for (const [modelKey, modelValue] of Object.entries(providerValue.models)) {\n if (!isRecord(modelValue)) continue;\n if (models.size >= MAX_MODELS_PER_PROVIDER) throw new Error('models-dev catalog exceeds the model budget');\n const modelId = typeof modelValue.id === 'string' && modelValue.id.trim() ? modelValue.id.trim() : modelKey.trim();\n if (!modelId || modelId.length > 512) continue;\n const modelName = typeof modelValue.name === 'string' && modelValue.name.trim() ? modelValue.name.trim() : modelId;\n models.set(modelId, Object.freeze({ id: modelId, name: modelName, price: normalizePrice(modelValue.cost), raw: modelValue }));\n modelCount += 1;\n }\n }\n const provider: CatalogProvider = Object.freeze({\n id, name, api: typeof providerValue.api === 'string' ? providerValue.api : null,\n apiHost: parsedApi?.host ?? null,\n apiPathSegments: parsedApi === null ? null : Object.freeze(parsedApi.pathSegments.map(segment => segment.includes('wildcard') ? '*' : segment)),\n models, ...nameIndexes(models), raw: providerValue,\n });\n providers.push(provider);\n if (!byProvider.has(id)) byProvider.set(id, provider);\n }\n providers.sort((left, right) => left.id.localeCompare(right.id));\n const exactModels = new Map<string, ModelsDevModelMatch | null>();\n const lowerModels = new Map<string, ModelsDevModelMatch | null>();\n const familyModels = new Map<string, ModelsDevModelMatch | null>();\n const byApiHost = new Map<string, CatalogProvider[]>();\n for (const provider of providers) {\n if (provider.apiHost !== null) {\n const sameHost = byApiHost.get(provider.apiHost) ?? [];\n sameHost.push(provider);\n byApiHost.set(provider.apiHost, sameHost);\n }\n for (const model of provider.models.values()) {\n const match = catalogModelIn(provider, model.id);\n if (match === null) continue;\n exactModels.set(model.id, exactModels.has(model.id) ? null : match);\n const lower = model.id.toLowerCase();\n lowerModels.set(lower, lowerModels.has(lower) ? null : match);\n }\n for (const [family, model] of provider.familyModels) {\n familyModels.set(family, familyModels.has(family) ? null : catalogModelIn(provider, model.id));\n }\n }\n for (const providers of byApiHost.values()) Object.freeze(providers);\n return Object.freeze({ version: record.version, fetchedAt: record.fetchedAt, providers: Object.freeze(providers), byProvider, modelCount, exactModels, lowerModels, familyModels, byApiHost });\n}\n\nexport function emptyStatus(): ModelsDevCatalogStatus {\n return Object.freeze({ state: 'empty', version: null, fetchedAt: null, providerCount: 0, modelCount: 0, error: null });\n}\n\nexport function statusOf(index: CatalogIndex | null, state: 'ready' | 'stale' | 'failed', error: string | null): ModelsDevCatalogStatus {\n if (index === null) return Object.freeze({ state: error === null ? 'empty' : 'failed', version: null, fetchedAt: null, providerCount: 0, modelCount: 0, error });\n return Object.freeze({ state, version: index.version, fetchedAt: index.fetchedAt, providerCount: index.providers.length, modelCount: index.modelCount, error });\n}\n\n/** One real upstream URL resolved through the full catalog's `provider.api`. */\nexport function resolveProviderFromUrl(index: CatalogIndex | null, rawUrl: string): ModelsDevProviderMatch | null {\n if (index === null || typeof rawUrl !== 'string' || rawUrl.length === 0 || rawUrl.length > 8_192) return null;\n let parsed: URL;\n try { parsed = new URL(rawUrl); } catch { return null; }\n const host = parsed.hostname.toLowerCase();\n const segments = parsed.pathname.split('/').filter(Boolean).map(segment => segment.toLowerCase());\n const matches: string[] = [];\n for (const provider of index.byApiHost.get(host) ?? []) {\n if (provider.apiHost !== host || provider.apiPathSegments === null) continue;\n if (!pathMatches(provider.apiPathSegments, segments)) continue;\n matches.push(provider.id);\n if (matches.length > 1) return null; // Ambiguity is never guessed.\n }\n return matches.length === 1 ? Object.freeze({ provider: matches[0]! }) : null;\n}\n\nfunction catalogModelIn(provider: CatalogProvider, modelId: string): ModelsDevModelMatch | null {\n const model = provider.models.get(modelId);\n if (model === undefined || model.price === null) return null;\n return Object.freeze({\n provider: provider.id, model: model.id,\n input: model.price.input, output: model.price.output,\n cacheRead: model.price.cacheRead, cacheWrite: model.price.cacheWrite,\n tiered: model.price.tiered,\n contextTiers: model.price.contextTiers,\n });\n}\n\nfunction providerPrefix(model: string): { provider: string; modelId: string } | null {\n const colon = model.indexOf(':');\n const slash = model.indexOf('/');\n const index = [colon, slash].filter(value => value > 0).sort((left, right) => left - right)[0];\n if (index === undefined) return null;\n const provider = model.slice(0, index);\n const modelId = model.slice(index + 1);\n return provider && modelId ? { provider, modelId } : null;\n}\n\n/**\n * Exact, unambiguous resolution. Priority: explicit catalog provider hint\n * (resolved from the hint itself or the URL), a known provider prefix, then a\n * UNIQUE exact model match across the catalog. Case-sensitive throughout.\n */\nexport function resolveModelInCatalog(index: CatalogIndex | null, input: Parameters<ModelsDevCatalogService['resolveModel']>[0]): ModelsDevModelMatch | null {\n if (index === null || typeof input.model !== 'string' || input.model.length === 0 || input.model.length > 512) return null;\n if (input.mode === 'estimate') return resolveEstimate(index, input);\n const model = input.model;\n const hintProvider = typeof input.pricingProvider === 'string' && input.pricingProvider.length > 0 && input.pricingProvider.length <= 512\n ? input.pricingProvider\n : undefined;\n\n if (hintProvider !== undefined) {\n const direct = index.byProvider.get(hintProvider);\n if (direct !== undefined) {\n // An explicit provider that does not carry the model is unknown, not a cue\n // to guess another provider.\n return catalogModelIn(direct, model);\n }\n if (hintProvider.includes('://') || hintProvider.includes('/')) {\n const resolved = resolveProviderFromUrl(index, hintProvider);\n return resolved === null ? null : catalogModelIn(index.byProvider.get(resolved.provider)!, model);\n }\n // An explicit provider that is not in the catalog is unknown, never guessed.\n return null;\n }\n\n if (input.url !== undefined && input.url.length > 0) {\n const resolved = resolveProviderFromUrl(index, input.url);\n if (resolved !== null) return catalogModelIn(index.byProvider.get(resolved.provider)!, model);\n }\n\n const prefixed = providerPrefix(model);\n if (prefixed !== null) {\n const provider = index.byProvider.get(prefixed.provider);\n if (provider !== undefined) {\n const match = catalogModelIn(provider, prefixed.modelId);\n if (match !== null) return match;\n }\n }\n\n return index.exactModels.get(model) ?? null;\n}\n\nfunction estimateIn(provider: CatalogProvider, model: string): ModelsDevModelMatch | null {\n const exact = catalogModelIn(provider, model);\n if (exact !== null) return exact;\n for (const name of estimateNames(model)) {\n const candidate = provider.lowerModels.get(name);\n if (candidate) return catalogModelIn(provider, candidate.id);\n }\n const family = provider.familyModels.get(modelFamily(model));\n return family === undefined ? null : catalogModelIn(provider, family.id);\n}\n\nfunction resolveEstimate(index: CatalogIndex, input: Parameters<ModelsDevCatalogService['resolveModel']>[0]): ModelsDevModelMatch | null {\n const model = input.model.trim();\n if (!model) return null;\n const hint = input.pricingProvider;\n const direct = hint ? index.byProvider.get(hint) : undefined;\n if (direct !== undefined) return estimateIn(direct, model);\n // Metering carries a URL in pricingProvider; only directory IDs are binding.\n const hintIsUrl = typeof hint === 'string' && (hint.includes('://') || hint.includes('/'));\n if (hint && !hintIsUrl) {\n const provider = index.byProvider.get(hint);\n return provider === undefined ? null : estimateIn(provider, model);\n }\n const prefixed = providerPrefix(model);\n if (prefixed !== null) {\n const provider = index.byProvider.get(prefixed.provider.toLowerCase());\n if (provider !== undefined) return estimateIn(provider, prefixed.modelId);\n }\n const url = hintIsUrl ? hint! : input.url;\n if (url) {\n const resolved = resolveProviderFromUrl(index, url);\n if (resolved !== null) {\n const match = estimateIn(index.byProvider.get(resolved.provider)!, model);\n if (match !== null) return match;\n }\n }\n const exact = index.exactModels.get(model);\n if (exact) return exact;\n const lower = index.lowerModels.get(model.toLowerCase());\n if (lower) return lower;\n const lab = originalLab(model);\n if (lab !== null) {\n const provider = index.byProvider.get(lab);\n return provider === undefined ? null : estimateIn(provider, model);\n }\n // Unknown labs may still have one uniquely identified normalized catalog entry.\n for (const name of estimateNames(model)) {\n const match = index.lowerModels.get(name);\n if (match) return match;\n }\n return index.familyModels.get(modelFamily(model)) ?? null;\n}\n\nexport function providerSummaries(index: CatalogIndex | null): readonly ModelsDevProviderSummary[] {\n if (index === null) return Object.freeze([]);\n return Object.freeze(index.providers.map(provider => Object.freeze({\n provider: provider.id, name: provider.name, api: provider.api, modelCount: provider.models.size,\n })));\n}\n\nexport function modelOptions(index: CatalogIndex | null, input: { provider?: string; search?: string; page?: number; pageSize?: number } = {}): ModelsDevModelPage {\n const pageSize = Math.min(Math.max(1, Math.trunc(input.pageSize ?? 50)), MAX_MODEL_OPTION_PAGE_SIZE);\n const requestedPage = Math.max(1, Math.trunc(input.page ?? 1));\n if (index === null) return Object.freeze({ models: Object.freeze([]), total: 0, page: 1, pageSize });\n const providerFilter = input.provider;\n const search = input.search;\n const needle = typeof search === 'string' && search.length > 0 ? search.toLocaleLowerCase() : null;\n const providers = providerFilter === undefined ? index.providers : index.providers.filter(provider => provider.id === providerFilter);\n const matchesSearch = (provider: CatalogProvider, model: CatalogModel): boolean => needle === null\n || `${model.id}\\n${model.name}\\n${provider.id}\\n${provider.name}`.toLocaleLowerCase().includes(needle);\n let total = 0;\n for (const provider of providers) {\n if (needle === null) total += provider.models.size;\n else for (const model of provider.models.values()) if (matchesSearch(provider, model)) total++;\n if (total > MAX_RESOLVE_CANDIDATES) throw new Error('models-dev model option scan exceeded the budget');\n }\n const lastPage = Math.max(1, Math.ceil(total / pageSize));\n const page = Math.min(requestedPage, lastPage);\n let skip = (page - 1) * pageSize;\n const models: ModelsDevModelOption[] = [];\n for (const provider of providers) {\n if (needle === null && skip >= provider.models.size) { skip -= provider.models.size; continue; }\n for (const model of provider.models.values()) {\n if (!matchesSearch(provider, model)) continue;\n if (skip > 0) { skip--; continue; }\n models.push({ provider: provider.id, providerName: provider.name, model: model.id, name: model.name });\n if (models.length === pageSize) break;\n }\n if (models.length === pageSize) break;\n }\n return Object.freeze({ models: Object.freeze(models), total, page, pageSize });\n}\n",
8
+ "/**\n * models-dev upstream download. This is the ONLY place that touches\n * `https://models.dev/api.json`; every other consumer reads the loaded catalog.\n * The full body is bounded and parsed as-is (no field trimming).\n */\n\nimport { MODELS_DEV_SOURCE_URL } from '../contract';\n\nexport const MAX_CATALOG_BODY_BYTES = 16 * 1024 * 1024;\nexport const DEFAULT_DOWNLOAD_TIMEOUT_SECONDS = 15;\n\nexport interface DownloadCatalogInput {\n readonly signal?: AbortSignal;\n readonly fetch?: typeof fetch;\n readonly url?: string;\n readonly maxBytes?: number;\n}\n\nasync function readBoundedBody(response: Response, maxBytes: number, signal?: AbortSignal): Promise<string> {\n if (signal?.aborted) throw new Error('catalog download cancelled');\n const contentLength = Number(response.headers.get('content-length'));\n if (Number.isFinite(contentLength) && contentLength > maxBytes) {\n await response.body?.cancel();\n throw new Error('catalog body limit exceeded');\n }\n if (response.body === null) return '';\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let total = 0;\n try {\n for (;;) {\n if (signal?.aborted) throw new Error('catalog download cancelled');\n const part = await reader.read();\n if (part.done) break;\n total += part.value.byteLength;\n if (total > maxBytes) {\n await reader.cancel();\n throw new Error('catalog body limit exceeded');\n }\n chunks.push(part.value);\n }\n } finally {\n reader.releaseLock();\n }\n const body = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) { body.set(chunk, offset); offset += chunk.byteLength; }\n return new TextDecoder().decode(body);\n}\n\n/** Download and parse the full catalog. Throws on transport/shape failure. */\nexport async function downloadModelsDevCatalog(input: DownloadCatalogInput = {}): Promise<unknown> {\n const url = input.url ?? MODELS_DEV_SOURCE_URL;\n const maxBytes = input.maxBytes ?? MAX_CATALOG_BODY_BYTES;\n const response = await (input.fetch ?? globalThis.fetch)(url, {\n ...(input.signal === undefined ? {} : { signal: input.signal }),\n headers: { accept: 'application/json' },\n });\n if (!response.ok) throw new Error(`catalog download failed with status ${response.status}`);\n const body = await readBoundedBody(response, maxBytes, input.signal);\n if (input.signal?.aborted) throw new Error('catalog download cancelled');\n const parsed: unknown = JSON.parse(body);\n if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) throw new Error('catalog payload is invalid');\n return parsed;\n}\n",
9
+ "/**\n * models-dev in-process read view. The view is the ONLY object exposed through the\n * public local service; it never performs I/O. The provider's own durable snapshot\n * body is owned by the Host snapshot store (`services.snapshot.store()`), never by\n * an in-plugin fallback.\n */\n\nimport { createHash } from 'node:crypto';\nimport type { PluginChannelSnapshotRead } from '../../../packages/core/src/plugin-services/peer-channel-hub';\nimport type {\n ModelsDevCatalogService,\n ModelsDevCatalogStatus,\n ModelsDevModelMatch,\n ModelsDevModelPage,\n ModelsDevProviderMatch,\n ModelsDevProviderSummary,\n} from '../contract';\nimport {\n buildCatalogIndex,\n emptyStatus,\n modelOptions,\n providerSummaries,\n resolveModelInCatalog,\n resolveProviderFromUrl,\n statusOf,\n type CatalogIndex,\n} from './catalog';\nimport { parseCatalogRecord } from './store';\nimport type { CatalogRecord } from './catalog';\n\nexport interface SnapshotSource {\n readonly descriptor: {\n readonly owner: string; readonly epoch: number; readonly version: number; readonly schemaVersion: number;\n readonly digest: `sha256:${string}`; readonly size: number; readonly chunkBytes: number;\n };\n read(offset: number, length: number): Promise<Uint8Array>;\n retain?(): void;\n release?(): void;\n}\n\n/** Read-only view over the loaded catalog. Mutations are whole-index swaps. */\nexport class CatalogView implements ModelsDevCatalogService {\n #index: CatalogIndex | null = null;\n #state: 'empty' | 'ready' | 'stale' | 'failed' = 'empty';\n #error: string | null = null;\n\n apply(index: CatalogIndex, state: 'ready' | 'stale' = 'ready', error: string | null = null): void {\n this.#index = index;\n this.#state = state;\n this.#error = error;\n }\n\n /** A failed refresh keeps the last valid index and only records the error. */\n fail(error: string): void {\n this.#error = error;\n this.#state = this.#index === null ? 'failed' : 'stale';\n }\n\n loaded(): boolean { return this.#index !== null; }\n\n status(): ModelsDevCatalogStatus {\n return this.#index === null && this.#state === 'empty' ? emptyStatus() : statusOf(this.#index, this.#state === 'empty' ? 'ready' : this.#state, this.#error);\n }\n\n providers(): readonly ModelsDevProviderSummary[] { return providerSummaries(this.#index); }\n\n modelOptions(input?: { provider?: string; search?: string; page?: number; pageSize?: number }): ModelsDevModelPage {\n return modelOptions(this.#index, input);\n }\n\n resolveModel(input: Parameters<ModelsDevCatalogService['resolveModel']>[0]): ModelsDevModelMatch | null {\n return resolveModelInCatalog(this.#index, input);\n }\n\n resolveProvider(input: { url: string }): ModelsDevProviderMatch | null {\n return resolveProviderFromUrl(this.#index, input.url);\n }\n}\n\n/** Plain, own-property service object (the service facade only exposes own enumerable keys). */\nexport function catalogServiceOf(view: CatalogView): ModelsDevCatalogService {\n return {\n status: () => view.status(),\n providers: () => view.providers(),\n modelOptions: (input) => view.modelOptions(input),\n resolveModel: (input) => view.resolveModel(input),\n resolveProvider: (input) => view.resolveProvider(input),\n };\n}\n\n/** Shared content validation for the persisted control source and verified worker view. */\nexport function decodeCatalogSnapshot(bytes: Uint8Array, version: number): CatalogRecord {\n const record = parseCatalogRecord(JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(bytes)));\n if (record.version !== version) throw new Error('catalog_version_mismatch');\n return record;\n}\n\nexport async function readCatalogSnapshot(source: SnapshotSource): Promise<CatalogRecord> {\n const { size, chunkBytes, digest, version } = source.descriptor;\n if (!Number.isSafeInteger(size) || size < 1 || size > 32 * 1024 * 1024\n || !Number.isSafeInteger(chunkBytes) || chunkBytes < 1) throw new Error('catalog_snapshot_size');\n source.retain?.();\n try {\n const bytes = new Uint8Array(size);\n for (let offset = 0; offset < size; offset += chunkBytes) {\n const length = Math.min(chunkBytes, size - offset);\n const chunk = await source.read(offset, length);\n if (chunk.byteLength !== length) throw new Error('catalog_snapshot_truncated');\n bytes.set(chunk, offset);\n }\n if (`sha256:${createHash('sha256').update(bytes).digest('hex')}` !== digest) throw new Error('catalog_snapshot_digest');\n return decodeCatalogSnapshot(bytes, version);\n } finally { source.release?.(); }\n}\n\n/** Apply only a complete Host-verified snapshot; a failed read never clears the prior view. */\nexport function reconcileCatalogView(snapshot: PluginChannelSnapshotRead | null, view: CatalogView): 'applied' | 'unchanged' | 'failed' {\n try {\n if (snapshot === null) {\n if (!view.loaded()) return 'unchanged';\n view.fail('catalog_missing');\n return 'failed';\n }\n const currentVersion = view.status().version;\n if (currentVersion !== null && currentVersion >= snapshot.descriptor.version) return 'unchanged';\n const record = decodeCatalogSnapshot(snapshot.bytes, snapshot.descriptor.version);\n const index = buildCatalogIndex(record);\n view.apply(index, 'ready', null);\n return 'applied';\n } catch (error) {\n view.fail(error instanceof Error ? error.message.slice(0, 64) : 'catalog_read_failed');\n return 'failed';\n }\n}\n",
10
+ "/**\n * Small private settings/status records and a one-time legacy catalog reader.\n * Catalog bodies and their versions are owned exclusively by the Host snapshot store.\n *\n * No consumer may import this module or read these keys.\n */\n\nimport type { PluginStorage } from '../../../packages/core/src/plugin.types';\nimport type { CatalogRecord } from './catalog';\n\nexport const MODELS_DEV_SETTINGS_KEY = 'catalog:settings:v2';\nexport const MODELS_DEV_CATALOG_KEY = 'catalog:v1';\nexport const MODELS_DEV_STATUS_KEY = 'catalog:status:v1';\n\nexport interface ModelsDevSettings {\n autoRefresh: boolean;\n intervalHours: number;\n timeoutSeconds: number;\n}\nexport const DEFAULT_MODELS_DEV_SETTINGS: ModelsDevSettings = { autoRefresh: true, intervalHours: 24, timeoutSeconds: 15 };\n\nexport interface ModelsDevPersistedStatus {\n lastAttemptAt: number | null;\n lastSuccessAt: number | null;\n lastError: string | null;\n consecutiveFailures: number;\n}\n\nexport function parseModelsDevSettings(value: unknown): ModelsDevSettings {\n if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error('invalid_input');\n const record = value as Record<string, unknown>;\n if (Object.keys(record).some(key => !['autoRefresh', 'intervalHours', 'timeoutSeconds'].includes(key))\n || typeof record.autoRefresh !== 'boolean'\n || !Number.isInteger(record.intervalHours) || (record.intervalHours as number) < 1 || (record.intervalHours as number) > 24\n || !Number.isInteger(record.timeoutSeconds) || (record.timeoutSeconds as number) < 5 || (record.timeoutSeconds as number) > 120) {\n throw new Error('invalid_input');\n }\n return { autoRefresh: record.autoRefresh, intervalHours: record.intervalHours as number, timeoutSeconds: record.timeoutSeconds as number };\n}\n\nexport function parsePersistedStatus(value: unknown): ModelsDevPersistedStatus {\n const empty: ModelsDevPersistedStatus = { lastAttemptAt: null, lastSuccessAt: null, lastError: null, consecutiveFailures: 0 };\n if (!value || typeof value !== 'object' || Array.isArray(value)) return empty;\n const record = value as Record<string, unknown>;\n const numberOrNull = (candidate: unknown): number | null => typeof candidate === 'number' && Number.isFinite(candidate) && candidate >= 0 ? candidate : null;\n return {\n lastAttemptAt: numberOrNull(record.lastAttemptAt),\n lastSuccessAt: numberOrNull(record.lastSuccessAt),\n lastError: typeof record.lastError === 'string' && record.lastError.length > 0 && record.lastError.length <= 64 ? record.lastError : null,\n consecutiveFailures: Number.isSafeInteger(record.consecutiveFailures) && (record.consecutiveFailures as number) >= 0 ? record.consecutiveFailures as number : 0,\n };\n}\n\n/** Strict read helper: SQL/JSON failures propagate; only a real absence is `undefined`. */\nasync function strictRead(storage: PluginStorage, key: string): Promise<unknown | undefined> {\n if (typeof storage.readStrict === 'function') {\n const result = await storage.readStrict<unknown>(key);\n return result.found ? result.value : undefined;\n }\n const value = await storage.get<unknown>(key);\n return value === null ? undefined : value;\n}\n\nexport async function readModelsDevSettings(storage: PluginStorage): Promise<ModelsDevSettings> {\n const stored = await strictRead(storage, MODELS_DEV_SETTINGS_KEY);\n // Absence uses defaults; an existing but unreadable value propagates (never a\n // silent default that could mask a storage fault).\n if (stored === undefined) return { ...DEFAULT_MODELS_DEV_SETTINGS };\n return parseModelsDevSettings(stored);\n}\n\nexport async function writeModelsDevSettings(storage: PluginStorage, settings: ModelsDevSettings): Promise<void> {\n await storage.set(MODELS_DEV_SETTINGS_KEY, settings);\n}\n\n/**\n * Strict catalog read. `readStrict` is required: the legacy `get` swallows SQL and\n * JSON errors, which would turn a storage failure into a fabricated \"no catalog\".\n */\nexport async function readCatalogRecord(storage: PluginStorage): Promise<CatalogRecord | null> {\n if (typeof storage.readStrict !== 'function') throw new Error('models-dev requires strict plugin storage reads');\n const result = await storage.readStrict<unknown>(MODELS_DEV_CATALOG_KEY);\n if (!result.found) return null;\n return parseCatalogRecord(result.value);\n}\n\nexport function parseCatalogRecord(value: unknown): CatalogRecord {\n if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error('models-dev catalog record is invalid');\n const record = value as Record<string, unknown>;\n if (!Number.isSafeInteger(record.version) || (record.version as number) < 1\n || typeof record.fetchedAt !== 'number' || !Number.isFinite(record.fetchedAt) || record.fetchedAt < 0\n || record.catalog === null || typeof record.catalog !== 'object' || Array.isArray(record.catalog)) {\n throw new Error('models-dev catalog record is invalid');\n }\n return { version: record.version as number, fetchedAt: record.fetchedAt as number, catalog: record.catalog };\n}\n\nexport async function readPersistedStatus(storage: PluginStorage): Promise<ModelsDevPersistedStatus> {\n const stored = await strictRead(storage, MODELS_DEV_STATUS_KEY);\n return stored === undefined ? parsePersistedStatus(undefined) : parsePersistedStatus(stored);\n}\n\nexport async function writePersistedStatus(storage: PluginStorage, status: ModelsDevPersistedStatus): Promise<void> {\n await (storage.uncached?.() ?? storage).set(MODELS_DEV_STATUS_KEY, status);\n}\n",
11
+ "/**\n * models-dev control plugin: the single network writer, refresh scheduler and\n * private persistence owner of the models.dev catalog. It publishes the versioned\n * snapshot and the control-process local read service, and exposes the management\n * HTTP API (settings/status/refresh/queries). No other component downloads.\n */\n\nimport type {\n ControlApiDeclaration,\n ControlApiHandlerContext,\n ControlHostContext,\n ControlPlugin,\n PluginControl,\n} from '../../../packages/core/src/plugin-control/contracts';\nimport type { PluginStorage } from '../../../packages/core/src/plugin.types';\nimport {\n MODELS_DEV_CATALOG_SERVICE_ID,\n MODELS_DEV_CATALOG_CONTRACT_VERSION,\n MODELS_DEV_CATALOG_SNAPSHOT_CONTRACT,\n MODELS_DEV_SOURCE_URL,\n} from '../contract';\nimport { buildCatalogIndex } from './catalog';\nimport { downloadModelsDevCatalog } from './download';\nimport { CatalogView, catalogServiceOf, readCatalogSnapshot, type SnapshotSource } from './local';\nimport {\n DEFAULT_MODELS_DEV_SETTINGS, parseModelsDevSettings, readCatalogRecord, readModelsDevSettings, readPersistedStatus,\n writeModelsDevSettings, writePersistedStatus,\n type ModelsDevPersistedStatus, type ModelsDevSettings,\n} from './store';\n\nconst MAX_RESPONSE_BYTES = 256 * 1024;\nconst MAX_PAGE_RESPONSE_BYTES = 4 * 1024 * 1024;\nconst MAX_QUERY_BYTES = 512;\nconst MAX_PAGE = 400;\n\nexport interface ModelsDevCatalogManagerOptions {\n fetch?: typeof fetch;\n now?: () => number;\n schedule?: (callback: () => void, delayMs: number) => ReturnType<typeof setTimeout>;\n cancel?: (timer: ReturnType<typeof setTimeout>) => void;\n}\n\ninterface CatalogPublisher {\n publish(version: number, bytes: Uint8Array): void;\n current(): SnapshotSource | null;\n}\n\ninterface ManagerStatus {\n source: string;\n /** Availability of the current catalog view, separate from service publication. */\n state: 'empty' | 'ready' | 'stale' | 'failed';\n settings: ModelsDevSettings;\n refreshing: boolean;\n lastAttemptAt: number | null;\n lastSuccessAt: number | null;\n nextRefreshAt: number | null;\n lastError: string | null;\n consecutiveFailures: number;\n modelCount: number;\n providerCount: number;\n /** Published data version; `null` before the first successful load. */\n version: number | null;\n}\n\n/**\n * One control-process owner. The atomic Host snapshot is the only catalog truth.\n * Small status metadata may fail independently without undoing a committed catalog.\n */\nexport class ModelsDevCatalogManager {\n readonly view = new CatalogView();\n private settings: ModelsDevSettings = { ...DEFAULT_MODELS_DEV_SETTINGS };\n private status: ModelsDevPersistedStatus = { lastAttemptAt: null, lastSuccessAt: null, lastError: null, consecutiveFailures: 0 };\n private refreshing = false;\n private nextRefreshAt: number | null = null;\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 publisher: CatalogPublisher, private readonly options: ModelsDevCatalogManagerOptions = {}) {\n this.now = options.now ?? Date.now;\n }\n\n async start(): Promise<void> {\n await (this.initialization ??= this.restore());\n }\n\n statusSnapshot(): ManagerStatus {\n const catalog = this.view.status();\n return {\n source: MODELS_DEV_SOURCE_URL, state: catalog.state, settings: { ...this.settings }, refreshing: this.refreshing,\n lastAttemptAt: this.status.lastAttemptAt, lastSuccessAt: this.status.lastSuccessAt,\n nextRefreshAt: this.nextRefreshAt, lastError: this.status.lastError, consecutiveFailures: this.status.consecutiveFailures,\n modelCount: catalog.modelCount, providerCount: catalog.providerCount, version: catalog.version,\n };\n }\n\n async configure(settings: ModelsDevSettings): Promise<ManagerStatus> {\n await this.start();\n if (this.stopped) throw new Error('disposed');\n const parsed = parseModelsDevSettings(settings);\n await writeModelsDevSettings(this.storage, parsed);\n this.settings = parsed;\n this.schedule();\n return this.statusSnapshot();\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.nextRefreshAt = null;\n this.refreshing = true;\n this.status.lastAttemptAt = this.now();\n const task = this.load().finally(() => { if (this.inFlight === task) this.inFlight = undefined; });\n this.inFlight = task;\n return task;\n }\n\n async stop(): Promise<void> {\n this.stopped = true;\n this.clearTimer();\n this.controller?.abort();\n await Promise.allSettled([this.initialization, this.inFlight].filter((task): task is Promise<void> => task !== undefined));\n }\n\n private async restore(): Promise<void> {\n // Strict reads: a real SQL/parse failure must surface as an explicit error and\n // must never be silently downgraded to \"no settings/catalog\" (which a consumer\n // could misread as a fresh, priced catalog).\n try {\n this.settings = await readModelsDevSettings(this.storage);\n } catch {\n this.status.lastError = 'storage';\n }\n try {\n this.status = { ...this.status, ...await readPersistedStatus(this.storage) };\n } catch {\n this.status.lastError = 'storage';\n }\n try {\n let source = this.publisher.current();\n // A legacy KV is read ONLY before the first valid snapshot, never as a corruption fallback.\n if (source === null) {\n const legacy = await readCatalogRecord(this.storage);\n if (legacy !== null) {\n buildCatalogIndex(legacy);\n this.publisher.publish(legacy.version, new TextEncoder().encode(JSON.stringify(legacy)));\n source = this.publisher.current();\n }\n }\n const record = source === null ? null : await readCatalogSnapshot(source);\n if (record !== null) {\n const index = buildCatalogIndex(record);\n this.view.apply(index, this.status.lastError === null ? 'ready' : 'stale', this.status.lastError);\n this.status.lastSuccessAt = record.fetchedAt;\n } else {\n this.status.lastSuccessAt = null;\n }\n } catch {\n this.view.fail('snapshot');\n this.status.lastError = 'snapshot';\n }\n if (this.stopped) return;\n this.schedule();\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' | 'snapshot' | 'invalid_catalog' = 'storage';\n try {\n // Observability metadata is not a prerequisite for updating the catalog.\n try { await writePersistedStatus(this.storage, this.status); } catch { this.status.lastError = 'storage'; }\n if (this.stopped) return;\n phase = 'network';\n const failure = new Promise<never>((_resolve, reject) => {\n onAbort = () => reject(new Error('aborted'));\n controller.signal.addEventListener('abort', onAbort, { once: true });\n timeout = (this.options.schedule ?? setTimeout)(() => { timedOut = true; controller.abort(); }, this.settings.timeoutSeconds * 1000);\n });\n const catalog = await Promise.race([\n downloadModelsDevCatalog({ ...(this.options.fetch ? { fetch: this.options.fetch } : {}), signal: controller.signal }),\n failure,\n ]);\n if (this.stopped) return;\n phase = 'invalid_catalog';\n const version = (this.publisher.current()?.descriptor.version ?? 0) + 1;\n if (!Number.isSafeInteger(version)) throw new Error('catalog_version_overflow');\n const fetchedAt = Math.max(this.now(), (this.status.lastSuccessAt ?? -1) + 1);\n const record = { version, fetchedAt, catalog };\n // Validate the payload BEFORE any durable write, so an unreadable catalog is\n // never published nor persisted.\n const index = buildCatalogIndex(record);\n // The single atomic visibility point includes metadata and catalog bytes.\n phase = 'snapshot';\n this.publisher.publish(version, new TextEncoder().encode(JSON.stringify(record)));\n if (this.stopped) return;\n this.view.apply(index, 'ready', null);\n this.status.lastSuccessAt = fetchedAt;\n this.status.lastError = null;\n this.status.consecutiveFailures = 0;\n } catch (error) {\n if (this.stopped) return;\n this.status.lastError = timedOut ? 'timeout' : phase === 'invalid_catalog' ? 'invalid_catalog' : phase;\n this.status.consecutiveFailures += 1;\n // A failed refresh (network/snapshot/storage) keeps the last valid view.\n this.view.fail(this.status.lastError);\n } finally {\n if (timeout !== undefined) (this.options.cancel ?? clearTimeout)(timeout);\n if (onAbort) controller.signal.removeEventListener('abort', onAbort);\n if (this.controller === controller) this.controller = undefined;\n this.refreshing = false;\n if (!this.stopped) {\n this.schedule();\n try { await writePersistedStatus(this.storage, this.status); }\n catch { this.status.lastError = 'storage'; this.view.fail('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.nextRefreshAt = null;\n if (this.stopped || this.refreshing || !this.settings.autoRefresh) return;\n const interval = this.settings.intervalHours * 60 * 60 * 1000;\n const due = this.status.consecutiveFailures\n ? this.now() + Math.min(interval, 60_000 * Math.min(15, 2 ** Math.min(this.status.consecutiveFailures - 1, 4)))\n : this.status.lastSuccessAt === null ? this.now() : Math.max(this.now(), this.status.lastSuccessAt + interval);\n this.nextRefreshAt = due;\n this.timer = (this.options.schedule ?? setTimeout)(() => { void this.refresh(); }, Math.max(0, due - this.now()));\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' }), { status: 500, headers: { 'content-type': 'application/json; charset=utf-8' } });\n }\n return new Response(body, { status, headers: { 'content-type': 'application/json; charset=utf-8' } });\n}\n\nasync function readBody(request: Request, maxBytes: number): Promise<unknown> {\n const reader = request.body?.getReader();\n if (!reader) throw new Error('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 Error('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\nclass ModelsDevControl implements PluginControl {\n readonly api: readonly ControlApiDeclaration[];\n readonly rpc = [] as const;\n private disposed = false;\n private readonly manager: ModelsDevCatalogManager;\n private readonly store: { publish(version: number, body: unknown | Uint8Array): unknown; current(): SnapshotSource | null; version(version: number): SnapshotSource | null };\n private readonly abortListener: () => void;\n\n constructor(private readonly host: ControlHostContext, options?: ModelsDevCatalogManagerOptions) {\n // The provider MUST obtain the Host's durable, chunked snapshot store. A host\n // without that capability is refused explicitly: there is no in-plugin fallback\n // storage that would hide a missing durable capability.\n const snapshot = host.services?.snapshot;\n if (snapshot === undefined || typeof snapshot.store !== 'function') {\n throw new Error('models-dev requires a durable host snapshot store capability');\n }\n const store = snapshot.store({ id: 'models-dev.catalog.v1', schemaVersion: 1, maxVersions: 3, maxBytes: 32 * 1024 * 1024 });\n if (store === null) throw new Error('models-dev requires a durable host snapshot store capability');\n this.store = store;\n this.manager = new ModelsDevCatalogManager(host.storage.uncached?.() ?? host.storage, {\n publish: (version, bytes) => { store.publish(version, bytes); }, current: () => store.current(),\n }, options);\n this.abortListener = () => { void this.dispose(); };\n if (host.signal.aborted) this.disposed = true;\n else host.signal.addEventListener('abort', this.abortListener, { once: true });\n snapshot.provide(MODELS_DEV_CATALOG_SNAPSHOT_CONTRACT, {\n current: () => this.store.current(),\n version: (version: number) => this.store.version(version),\n });\n if (host.services !== undefined) {\n host.services.publish(MODELS_DEV_CATALOG_SERVICE_ID, MODELS_DEV_CATALOG_CONTRACT_VERSION, catalogServiceOf(this.manager.view));\n }\n this.api = this.buildApi();\n }\n\n private assertAlive(signal?: AbortSignal): void {\n if (this.disposed || this.host.signal.aborted) throw new Error('disposed');\n if (signal?.aborted) throw new Error('request_cancelled');\n }\n\n private buildApi(): readonly ControlApiDeclaration[] {\n const invoke = (handler: (context: ControlApiHandlerContext) => Promise<Response> | Response) => async (context: ControlApiHandlerContext) => {\n try {\n this.assertAlive(context.requestSignal);\n return await handler(context);\n } catch (error) {\n return jsonResponse({ error: error instanceof Error && error.message === 'invalid_input' ? 'invalid_input' : 'internal_error' }, 500);\n }\n };\n return [{\n path: '/catalog/status', methods: ['GET'], handler: 'getCatalogStatus',\n invoke: invoke(async () => { await this.manager.start(); return jsonResponse(this.manager.statusSnapshot()); }),\n }, {\n path: '/catalog/providers', methods: ['GET'], handler: 'getCatalogProviders',\n invoke: invoke(async () => jsonResponse({ providers: this.manager.view.providers() }, 200, MAX_PAGE_RESPONSE_BYTES)),\n }, {\n path: '/catalog/models', methods: ['GET'], handler: 'getCatalogModels',\n invoke: invoke(async (context) => {\n const query = parseModelQuery(context.request);\n if (query === null) return jsonResponse({ error: 'invalid_query' }, 400);\n await this.manager.start();\n return jsonResponse(this.manager.view.modelOptions(query), 200, MAX_PAGE_RESPONSE_BYTES);\n }),\n }, {\n path: '/catalog/settings', methods: ['PUT'], handler: 'configureCatalog',\n invoke: invoke(async (context) => {\n let settings: ModelsDevSettings;\n try { settings = parseModelsDevSettings(await readBody(context.request, 4096)); }\n catch { return jsonResponse({ error: 'invalid_input' }, 400); }\n return jsonResponse(await this.manager.configure(settings));\n }),\n }, {\n path: '/catalog/refresh', methods: ['POST'], handler: 'refreshCatalog',\n invoke: invoke(async () => {\n await this.manager.start();\n void this.manager.refresh();\n return jsonResponse(this.manager.statusSnapshot(), 202);\n }),\n }];\n }\n\n async start(): Promise<void> {\n this.assertAlive();\n await this.manager.start();\n }\n\n async dispose(): Promise<void> {\n if (this.disposed) return;\n this.disposed = true;\n const stopped = this.manager.stop();\n this.host.signal.removeEventListener('abort', this.abortListener);\n await stopped;\n }\n}\n\nfunction parseModelQuery(request: Request): { provider?: string; search?: string; page?: number } | null {\n const params = new URL(request.url).searchParams;\n const encoder = new TextEncoder();\n for (const key of ['provider', 'search', 'page']) if (params.getAll(key).length > 1) return null;\n const provider = params.get('provider') ?? undefined;\n const search = params.get('search') ?? undefined;\n const rawPage = params.get('page');\n const page = rawPage === null ? 1 : Number(rawPage);\n if ((provider !== undefined && encoder.encode(provider).byteLength > MAX_QUERY_BYTES)\n || (search !== undefined && encoder.encode(search).byteLength > MAX_QUERY_BYTES)\n || !Number.isSafeInteger(page) || page < 1 || page > MAX_PAGE) return null;\n return { provider, search, page };\n}\n\nexport function createControl(context: ControlHostContext, options?: ModelsDevCatalogManagerOptions): PluginControl {\n return new ModelsDevControl(context, options);\n}\n\nexport default { createControl } satisfies ControlPlugin;\n"
12
+ ],
13
+ "mappings": "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",
14
+ "debugId": "0376174D0A69321964756E2164756E21",
15
+ "names": []
16
+ }