{"version":3,"file":"netlify-DDJM4IYB.cjs","names":["MastraModelGateway","InMemoryServerCache","MastraError","MASTRA_USER_AGENT","createOpenAI","createGoogleGenerativeAI","createAnthropic","createOpenAICompatible"],"sources":["../src/llm/model/gateways/netlify.ts"],"sourcesContent":["import { createAnthropic } from '@ai-sdk/anthropic-v6';\nimport { createGoogleGenerativeAI } from '@ai-sdk/google-v6';\nimport { createOpenAICompatible } from '@ai-sdk/openai-compatible-v6';\nimport { createOpenAI } from '@ai-sdk/openai-v6';\nimport { InMemoryServerCache } from '../../../cache/inmemory.js';\nimport { MastraError } from '../../../error/index.js';\nimport { MastraModelGateway } from './base.js';\nimport type { ProviderConfig, GatewayLanguageModel } from './base.js';\nimport { MASTRA_USER_AGENT } from './constants.js';\n\ninterface NetlifyProviderResponse {\n  token_env_var: string;\n  url_env_var: string;\n  models: string[];\n}\ninterface NetlifyResponse {\n  providers: Record<string, NetlifyProviderResponse>;\n}\n\ninterface NetlifyTokenResponse {\n  token: string;\n  url: string;\n  expires_at: number;\n}\n\ninterface CachedToken {\n  token: string;\n  url: string;\n  expiresAt: number;\n}\n\ninterface TokenData {\n  token: string;\n  url: string;\n}\n\nexport class NetlifyGateway extends MastraModelGateway {\n  readonly id = 'netlify';\n  readonly name = 'Netlify AI Gateway';\n  private tokenCache = new InMemoryServerCache();\n\n  async fetchProviders(): Promise<Record<string, ProviderConfig>> {\n    const response = await fetch('https://api.netlify.com/api/v1/ai-gateway/providers');\n    if (!response.ok) {\n      throw new Error(`Failed to fetch from Netlify: ${response.statusText}`);\n    }\n    const data = (await response.json()) as NetlifyResponse;\n    const config: ProviderConfig = {\n      apiKeyEnvVar: ['NETLIFY_TOKEN', 'NETLIFY_SITE_ID'],\n      apiKeyHeader: 'Authorization',\n      name: `Netlify`,\n      gateway: `netlify`,\n      models: [],\n      docUrl: 'https://docs.netlify.com/build/ai-gateway/overview/',\n    };\n    // Convert Netlify format to our standard format\n    for (const [providerId, provider] of Object.entries(data.providers)) {\n      for (const model of provider.models) {\n        config.models.push(`${providerId}/${model}`);\n      }\n    }\n    // Return with gateway ID as key - registry generator will detect this and avoid doubling the prefix\n    return { netlify: config };\n  }\n\n  async buildUrl(routerId: string, envVars?: typeof process.env): Promise<string> {\n    // Check for Netlify site ID first (for token exchange)\n    const siteId = envVars?.['NETLIFY_SITE_ID'] || process.env['NETLIFY_SITE_ID'];\n    const netlifyToken = envVars?.['NETLIFY_TOKEN'] || process.env['NETLIFY_TOKEN'];\n\n    if (!netlifyToken) {\n      throw new MastraError({\n        id: 'NETLIFY_GATEWAY_NO_TOKEN',\n        domain: 'LLM',\n        category: 'UNKNOWN',\n        text: `Missing NETLIFY_TOKEN environment variable required for model: ${routerId}`,\n      });\n    }\n\n    if (!siteId) {\n      throw new MastraError({\n        id: 'NETLIFY_GATEWAY_NO_SITE_ID',\n        domain: 'LLM',\n        category: 'UNKNOWN',\n        text: `Missing NETLIFY_SITE_ID environment variable required for model: ${routerId}`,\n      });\n    }\n\n    try {\n      const tokenData = await this.getOrFetchToken(siteId, netlifyToken);\n      return tokenData.url.endsWith(`/`) ? tokenData.url.substring(0, tokenData.url.length - 1) : tokenData.url;\n    } catch (error) {\n      throw new MastraError({\n        id: 'NETLIFY_GATEWAY_TOKEN_ERROR',\n        domain: 'LLM',\n        category: 'UNKNOWN',\n        text: `Failed to get Netlify AI Gateway token for model ${routerId}: ${error instanceof Error ? error.message : String(error)}`,\n      });\n    }\n  }\n\n  /**\n   * Get cached token or fetch a new site-specific AI Gateway token from Netlify\n   */\n  private async getOrFetchToken(siteId: string, netlifyToken: string): Promise<TokenData> {\n    const cacheKey = `netlify-token:${siteId}:${netlifyToken}`;\n\n    // Check cache first\n    const cached = (await this.tokenCache.get(cacheKey)) as CachedToken | undefined;\n    if (cached && cached.expiresAt > Date.now() / 1000 + 60) {\n      // Return cached token if it won't expire in the next minute\n      return { token: cached.token, url: cached.url };\n    }\n\n    // Fetch new token\n    const response = await fetch(`https://api.netlify.com/api/v1/sites/${siteId}/ai-gateway/token`, {\n      method: 'GET',\n      headers: {\n        Authorization: `Bearer ${netlifyToken}`,\n      },\n    });\n\n    if (!response.ok) {\n      const error = await response.text();\n      throw new Error(`Failed to get Netlify AI Gateway token: ${response.status} ${error}`);\n    }\n\n    const tokenResponse = (await response.json()) as NetlifyTokenResponse;\n\n    // Cache the token - InMemoryServerCache will handle the TTL\n    await this.tokenCache.set(cacheKey, {\n      token: tokenResponse.token,\n      url: tokenResponse.url,\n      expiresAt: tokenResponse.expires_at,\n    });\n\n    return { token: tokenResponse.token, url: tokenResponse.url };\n  }\n\n  /**\n   * Get cached token or fetch a new site-specific AI Gateway token from Netlify\n   */\n  async getApiKey(modelId: string): Promise<string> {\n    const siteId = process.env['NETLIFY_SITE_ID'];\n    const netlifyToken = process.env['NETLIFY_TOKEN'];\n\n    if (!netlifyToken) {\n      throw new MastraError({\n        id: 'NETLIFY_GATEWAY_NO_TOKEN',\n        domain: 'LLM',\n        category: 'UNKNOWN',\n        text: `Missing NETLIFY_TOKEN environment variable required for model: ${modelId}`,\n      });\n    }\n\n    if (!siteId) {\n      throw new MastraError({\n        id: 'NETLIFY_GATEWAY_NO_SITE_ID',\n        domain: 'LLM',\n        category: 'UNKNOWN',\n        text: `Missing NETLIFY_SITE_ID environment variable required for model: ${modelId}`,\n      });\n    }\n\n    try {\n      return (await this.getOrFetchToken(siteId, netlifyToken)).token;\n    } catch (error) {\n      throw new MastraError({\n        id: 'NETLIFY_GATEWAY_TOKEN_ERROR',\n        domain: 'LLM',\n        category: 'UNKNOWN',\n        text: `Failed to get Netlify AI Gateway token for model ${modelId}: ${error instanceof Error ? error.message : String(error)}`,\n      });\n    }\n  }\n\n  async resolveLanguageModel({\n    modelId,\n    providerId,\n    apiKey,\n    headers,\n  }: {\n    modelId: string;\n    providerId: string;\n    apiKey: string;\n    headers?: Record<string, string>;\n  }): Promise<GatewayLanguageModel> {\n    const baseURL = await this.buildUrl(`${providerId}/${modelId}`);\n\n    const mastraHeaders = { 'User-Agent': MASTRA_USER_AGENT, ...headers };\n\n    switch (providerId) {\n      case 'openai':\n        return createOpenAI({ apiKey, baseURL, headers: mastraHeaders }).responses(modelId);\n      case 'gemini':\n        return createGoogleGenerativeAI({\n          baseURL: `${baseURL}/v1beta/`,\n          apiKey,\n          headers: {\n            'user-agent': 'google-genai-sdk/',\n            ...mastraHeaders,\n          },\n        }).chat(modelId);\n      case 'anthropic':\n        return createAnthropic({\n          apiKey,\n          baseURL: `${baseURL}/v1/`,\n          headers: {\n            'anthropic-version': '2023-06-01',\n            ...mastraHeaders,\n          },\n        })(modelId);\n      default:\n        return createOpenAICompatible({\n          name: providerId,\n          apiKey,\n          baseURL,\n          headers: mastraHeaders,\n          supportsStructuredOutputs: true,\n        }).chatModel(modelId);\n    }\n  }\n}\n"],"mappings":"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"}