import assert from "node:assert/strict"; import { readFileSync } from "node:fs"; import test from "node:test"; const catalog = readFileSync(new URL("../src/lib/model-catalog.ts", import.meta.url), "utf8"); const mastraModel = readFileSync(new URL("../src/mastra/model.ts", import.meta.url), "utf8"); const routes = Object.fromEntries( ["reports", "onboarding", "birth-time-guide", "consult"].map((name) => [ name, readFileSync(new URL(`../src/app/api/${name}/route.ts`, import.meta.url), "utf8"), ]), ); test("runtime catalog is database-only and reads encrypted provider credentials", () => { assert.match(catalog, /queryAdminRows/); assert.match(catalog, /p\.encrypted_api_key/); assert.match(catalog, /decryptModelProviderApiKey\(\{ encryptedApiKey: row\.encrypted_api_key \}\)/); assert.match(catalog, /v\.status='published' and v\.enabled and p\.enabled/); assert.doesNotMatch( `${catalog}\n${mastraModel}`, /LLM_MODELS_JSON|LLM_BASE_URL|LLM_MODEL|LLM_DEFAULT_MODEL_ID|LLM_PROVIDER_ID|MASTRA_MODEL|OPENAI_API_KEY|ANTHROPIC_API_KEY|DEEPSEEK_API_KEY|LLM_API_KEY|MODEL_PROVIDER_[A-Z0-9_]+_API_KEY|secret_ref|secretRef/, ); }); test("database rows map to native OpenAI, native Anthropic, and pinned compatible Mastra configs", () => { assert.match(catalog, /providerId: "openai", modelId: row\.provider_model\.replace\(\/\^openai/); assert.match(catalog, /providerId: "anthropic", modelId: row\.provider_model\.replace\(\/\^anthropic/); assert.match(catalog, /providerId: row\.provider_code, modelId: row\.provider_model, url:/); assert.match(catalog, /assertAllowedModelProviderUrl\(row\.base_url \?\? ""\)/); assert.match(catalog, /apiKey/); assert.match(catalog, /function publicModel[\s\S]*creditCost: model\.creditCost, isDefault: model\.isDefault/); assert.doesNotMatch(catalog, /publicModel[\s\S]{0,240}(apiKey|encrypted_api_key|base_url)/); }); test("catalog cache is short-lived and failure stays fail-closed without env fallback", () => { assert.match(catalog, /const cacheTtlMs = 15_000/); assert.match(catalog, /expiresAt: Date\.now\(\) \+ cacheTtlMs/); assert.match(catalog, /database_model_catalog_unavailable/); assert.match(catalog, /database_model_catalog_empty/); assert.match(catalog, /default_model_unavailable/); assert.match(catalog, /const defaults = models\.filter\(\(model\) => model\.isDefault\)/); assert.match(catalog, /defaults\.length === 1/); }); test("session model resolution is async and pins published or retired database versions", () => { assert.match(catalog, /export async function resolveSessionLanguageModel/); assert.match(catalog, /c\.model_id=\$1 and v\.version=\$2 and v\.status in \('published','retired'\)/); assert.match(catalog, /return await readVersion\(modelId, configVersion\)/); assert.match(routes.consult, /await resolveSessionLanguageModel\(\s*chatSession\.model_id,\s*chatSession\.model_config_version/); assert.match(routes.consult, /if \(!sessionModel\)[\s\S]*status: 503/); assert.doesNotMatch(routes.consult, /languageModelConfigurationMessage/); }); test("reports, onboarding, and birth-time guide resolve the database catalog before creating agents", () => { for (const name of ["reports", "onboarding", "birth-time-guide"] as const) { assert.match(routes[name], /await loadLanguageModelCatalog\(\)/, `${name} must await the DB catalog`); assert.match(routes[name], /catalog\.models\.find/, `${name} must select from resolved DB models`); } assert.match(routes.reports, /createPersonalReportAgent\(model/); assert.match(routes.onboarding, /getOnboardingAgent\(model\)/); assert.match(routes["birth-time-guide"], /getBirthTimeGuideAgent\(model\)/); });