{"version":3,"sources":["../src/llm/model/registry-generator.ts"],"names":["fs","path"],"mappings":"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","file":"registry-generator-VNYH6GDH.cjs","sourcesContent":["/**\n * Shared provider registry generation logic\n * Used by both the CLI generation script and runtime refresh\n */\n\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport type { MastraModelGateway, ProviderConfig } from './gateways/base.js';\n\n/**\n * Write a file atomically using the write-to-temp-then-rename pattern.\n * This prevents file corruption when multiple processes write to the same file concurrently.\n *\n * The rename operation is atomic on POSIX systems when source and destination\n * are on the same filesystem.\n *\n * @param filePath - The target file path\n * @param content - The content to write\n * @param encoding - The encoding to use (default: 'utf-8')\n */\nexport async function atomicWriteFile(\n  filePath: string,\n  content: string,\n  encoding: BufferEncoding = 'utf-8',\n): Promise<void> {\n  // Create a unique temp file name using PID, timestamp, and random suffix to avoid collisions\n  const randomSuffix = Math.random().toString(36).substring(2, 15);\n  const tempPath = `${filePath}.${process.pid}.${Date.now()}.${randomSuffix}.tmp`;\n\n  try {\n    // Write to temp file first\n    await fs.writeFile(tempPath, content, encoding);\n\n    // Atomically rename temp file to target path\n    // This is atomic on POSIX when both paths are on the same filesystem\n    await fs.rename(tempPath, filePath);\n  } catch (error) {\n    // Clean up temp file if it exists\n    try {\n      await fs.unlink(tempPath);\n    } catch {\n      // Ignore cleanup errors\n    }\n    throw error;\n  }\n}\n\n/**\n * Fetch providers from all gateways with retry logic\n * @param gateways - Array of gateway instances to fetch from\n * @returns Object containing providers and models records\n */\nexport async function fetchProvidersFromGateways(\n  gateways: MastraModelGateway[],\n): Promise<{ providers: Record<string, ProviderConfig>; models: Record<string, string[]> }> {\n  const enabledGateways: MastraModelGateway[] = [];\n\n  for (const gateway of gateways) {\n    if (await gateway.shouldEnable()) {\n      enabledGateways.push(gateway);\n    }\n  }\n\n  const allProviders: Record<string, ProviderConfig> = {};\n  const allModels: Record<string, string[]> = {};\n\n  const maxRetries = 3;\n\n  for (const gateway of enabledGateways) {\n    let lastError: Error | null = null;\n\n    for (let attempt = 1; attempt <= maxRetries; attempt++) {\n      try {\n        const providers = await gateway.fetchProviders();\n\n        // models.dev is a provider registry, not a true gateway - don't prefix its providers\n        const isProviderRegistry = gateway.id === 'models.dev';\n\n        for (const [providerId, config] of Object.entries(providers)) {\n          // For true gateways, use gateway.id as prefix (e.g., \"netlify/anthropic\")\n          // Special case: if providerId matches gateway.id, it's a unified gateway (e.g., azure-openai returning {azure-openai: {...}})\n          // In this case, use just the gateway ID to avoid duplication (azure-openai, not azure-openai/azure-openai)\n          const typeProviderId = isProviderRegistry\n            ? providerId\n            : providerId === gateway.id\n              ? gateway.id\n              : `${gateway.id}/${providerId}`;\n\n          allProviders[typeProviderId] = config;\n          // Sort models alphabetically for consistent ordering\n          allModels[typeProviderId] = config.models.sort();\n        }\n\n        lastError = null;\n        break; // Success, exit retry loop\n      } catch (error) {\n        lastError = error instanceof Error ? error : new Error(String(error));\n\n        if (attempt < maxRetries) {\n          // Wait before retrying (exponential backoff)\n          const delayMs = Math.min(1000 * Math.pow(2, attempt - 1), 5000);\n          await new Promise(resolve => setTimeout(resolve, delayMs));\n        }\n      }\n    }\n\n    // If all retries failed, throw the last error\n    if (lastError) {\n      throw lastError;\n    }\n  }\n\n  return { providers: allProviders, models: allModels };\n}\n\n/**\n * Generate TypeScript type definitions content\n * @param models - Record of provider IDs to model arrays\n * @returns Generated TypeScript type definitions as a string\n */\nexport function generateTypesContent(models: Record<string, string[]>): string {\n  const providerModelsEntries = Object.entries(models)\n    .map(([provider, modelList]) => {\n      const modelsList = modelList.map(m => `'${m}'`);\n\n      // Quote provider key if it's not a valid JavaScript identifier\n      // Valid identifiers must start with a letter, underscore, or dollar sign\n      const needsQuotes = !/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(provider);\n      const providerKey = needsQuotes ? `'${provider}'` : provider;\n\n      // Format array based on length (prettier printWidth: 120)\n      const singleLine = `  readonly ${providerKey}: readonly [${modelsList.join(', ')}];`;\n\n      // If single line exceeds 120 chars, format as multi-line\n      if (singleLine.length > 120) {\n        const formattedModels = modelList.map(m => `    '${m}',`).join('\\n');\n        return `  readonly ${providerKey}: readonly [\\n${formattedModels}\\n  ];`;\n      }\n\n      return singleLine;\n    })\n    .join('\\n');\n\n  return `/**\n * THIS FILE IS AUTO-GENERATED - DO NOT EDIT\n * Generated from model gateway providers\n */\n\n/**\n * Provider models mapping type\n * This is derived from the JSON data and provides type-safe access\n */\nexport type ProviderModelsMap = {\n${providerModelsEntries}\n};\n\n/**\n * Union type of all registered provider IDs\n */\nexport type Provider = keyof ProviderModelsMap;\n\n/**\n * Provider models mapping interface\n */\nexport interface ProviderModels {\n  [key: string]: string[];\n}\n\n/**\n * OpenAI-compatible model ID type\n * Dynamically derived from ProviderModelsMap\n * Full provider/model paths (e.g., \"openai/gpt-4o\", \"anthropic/claude-3-5-sonnet-20241022\")\n */\nexport type ModelRouterModelId =\n  | {\n      [P in Provider]: \\`\\${P}/\\${ProviderModelsMap[P][number]}\\`;\n    }[Provider]\n  | \\`mastra/\\${ProviderModelsMap['openrouter'][number]}\\`\n  | (string & {});\n\n/**\n * Extract the model part from a ModelRouterModelId for a specific provider\n * Dynamically derived from ProviderModelsMap\n * Example: ModelForProvider<'openai'> = 'gpt-4o' | 'gpt-4-turbo' | ...\n */\nexport type ModelForProvider<P extends Provider> = ProviderModelsMap[P][number];\n`;\n}\n\n/**\n * Write registry files to disk (JSON and .d.ts)\n * @param jsonPath - Path to write the JSON file\n * @param typesPath - Path to write the .d.ts file\n * @param providers - Provider configurations\n * @param models - Model lists by provider\n */\nexport async function writeRegistryFiles(\n  jsonPath: string,\n  typesPath: string,\n  providers: Record<string, ProviderConfig>,\n  models: Record<string, string[]>,\n): Promise<void> {\n  // 0. Ensure directories exist\n  const jsonDir = path.dirname(jsonPath);\n  const typesDir = path.dirname(typesPath);\n  await fs.mkdir(jsonDir, { recursive: true });\n  await fs.mkdir(typesDir, { recursive: true });\n\n  // 1. Write JSON file atomically to prevent corruption from concurrent writes\n  const registryData = {\n    providers,\n    models,\n    version: '1.0.0',\n  };\n\n  await atomicWriteFile(jsonPath, JSON.stringify(registryData, null, 2), 'utf-8');\n\n  // 2. Generate .d.ts file with type-only declarations (also atomic)\n  const typeContent = generateTypesContent(models);\n  await atomicWriteFile(typesPath, typeContent, 'utf-8');\n}\n"]}