UNPKG

@mastra/core

Version:

Mastra is a framework for building AI-powered applications and agents with a modern TypeScript stack.

1 lines 12.5 kB
{"version":3,"sources":["../src/llm/model/gateways/netlify.ts"],"names":["MastraModelGateway","InMemoryServerCache","MastraError","createOpenAI","createGoogleGenerativeAI","createAnthropic","createOpenAICompatible"],"mappings":"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","file":"chunk-IWU4YSYT.cjs","sourcesContent":["import { createAnthropic } from '@ai-sdk/anthropic-v5';\nimport { createGoogleGenerativeAI } from '@ai-sdk/google-v5';\nimport { createOpenAICompatible } from '@ai-sdk/openai-compatible-v5';\nimport { createOpenAI } from '@ai-sdk/openai-v5';\nimport type { LanguageModelV2 } from '@ai-sdk/provider-v5';\nimport { InMemoryServerCache } from '../../../cache/inmemory.js';\nimport { MastraError } from '../../../error/index.js';\nimport { MastraModelGateway } from './base.js';\nimport type { ProviderConfig } from './base.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<LanguageModelV2> {\n const baseURL = await this.buildUrl(`${providerId}/${modelId}`);\n\n switch (providerId) {\n case 'openai':\n return createOpenAI({ apiKey, baseURL, headers }).responses(modelId);\n case 'gemini':\n return createGoogleGenerativeAI({\n baseURL: `${baseURL}/v1beta/`,\n apiKey,\n headers: {\n 'user-agent': 'google-genai-sdk/',\n ...(headers ? headers : {}),\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 'user-agent': 'anthropic/',\n ...(headers ? headers : {}),\n },\n })(modelId);\n default:\n return createOpenAICompatible({ name: providerId, apiKey, baseURL, supportsStructuredOutputs: true }).chatModel(\n modelId,\n );\n }\n }\n}\n"]}