UNPKG

@ai-sdk/google

Version:
439 lines (385 loc) 13.2 kB
import type { EmbeddingModelV4, Experimental_BatchLanguageModelV4 as BatchLanguageModelV4, Experimental_VideoModelV4, FilesV4, ImageModelV4, LanguageModelV4, ProviderV4, Experimental_RealtimeFactoryV4 as RealtimeFactoryV4, Experimental_RealtimeFactoryV4GetTokenOptions as RealtimeFactoryV4GetTokenOptions, SpeechModelV4, Experimental_SpeechTranslationModelV4 as SpeechTranslationModelV4, TranscriptionModelV4, } from '@ai-sdk/provider'; import { generateId, loadApiKey, withoutTrailingSlash, withUserAgentSuffix, type FetchFunction, type WebSocketConstructor, } from '@ai-sdk/provider-utils'; import { VERSION } from './version'; import { GoogleEmbeddingModel } from './google-embedding-model'; import type { GoogleEmbeddingModelId } from './google-embedding-model-options'; import { GoogleBatchLanguageModel } from './google-batch'; import type { GoogleModelId } from './google-language-model-options'; import { googleTools } from './google-tools'; import type { GoogleImageSettings, GoogleImageModelId, } from './google-image-settings'; import { GoogleImageModel } from './google-image-model'; import { GoogleFiles } from './google-files'; import { GoogleVideoModel } from './google-video-model'; import type { GoogleVideoModelId } from './google-video-settings'; import { GoogleSpeechModel } from './google-speech-model'; import type { GoogleSpeechModelId } from './google-speech-model-options'; import { GoogleInteractionsLanguageModel, type GoogleInteractionsModelInput, } from './interactions/google-interactions-language-model'; import type { GoogleInteractionsModelId } from './interactions/google-interactions-language-model-options'; import type { GoogleInteractionsAgentName } from './interactions/google-interactions-agent'; import { GoogleRealtimeModel } from './realtime/google-realtime-model'; import { GoogleTranscriptionModel } from './transcription/google-transcription-model'; import type { GoogleTranscriptionModelId } from './transcription/google-transcription-model-options'; import { GoogleSpeechTranslationModel } from './speech-translation/google-speech-translation-model'; import type { GoogleSpeechTranslationModelId } from './speech-translation/google-speech-translation-model-options'; const DEFAULT_BASE_URL = 'https://generativelanguage.googleapis.com/v1beta'; const googleFilesUrlPattern = /^https:\/\/generativelanguage\.googleapis\.com\/v1beta\/files\/.*$/; export interface GoogleProvider extends ProviderV4 { (modelId: GoogleModelId): BatchLanguageModelV4; languageModel(modelId: GoogleModelId): BatchLanguageModelV4; chat(modelId: GoogleModelId): BatchLanguageModelV4; /** * Creates a model for image generation. */ image( modelId: GoogleImageModelId, settings?: GoogleImageSettings, ): ImageModelV4; /** * @deprecated Use `chat()` instead. */ generativeAI(modelId: GoogleModelId): BatchLanguageModelV4; /** * Creates a model for text embeddings. */ embedding(modelId: GoogleEmbeddingModelId): EmbeddingModelV4; /** * Creates a model for text embeddings. */ embeddingModel(modelId: GoogleEmbeddingModelId): EmbeddingModelV4; /** * @deprecated Use `embedding` instead. */ textEmbedding(modelId: GoogleEmbeddingModelId): EmbeddingModelV4; /** * @deprecated Use `embeddingModel` instead. */ textEmbeddingModel(modelId: GoogleEmbeddingModelId): EmbeddingModelV4; /** * Creates a model for video generation. */ video(modelId: GoogleVideoModelId): Experimental_VideoModelV4; /** * Creates a model for video generation. */ videoModel(modelId: GoogleVideoModelId): Experimental_VideoModelV4; /** * Creates an experimental model for streaming speech translation. */ translation( modelId: GoogleSpeechTranslationModelId, ): SpeechTranslationModelV4; /** * Creates an experimental model for streaming speech translation. */ speechTranslationModel( modelId: GoogleSpeechTranslationModelId, ): SpeechTranslationModelV4; /** * Creates a model for speech generation (text-to-speech). */ speech(modelId: GoogleSpeechModelId): SpeechModelV4; /** * Creates a model for speech generation (text-to-speech). */ speechModel(modelId: GoogleSpeechModelId): SpeechModelV4; /** * Creates a model for transcription (speech-to-text). Unary models * (e.g. `gemini-3.5-transcribe`) transcribe audio files; live models * (e.g. `gemini-3.5-transcribe-live`) stream transcription over the * Gemini Live API WebSocket via `experimental_streamTranscribe`. */ transcription(modelId: GoogleTranscriptionModelId): TranscriptionModelV4; /** * Creates a model for transcription (speech-to-text). */ transcriptionModel(modelId: GoogleTranscriptionModelId): TranscriptionModelV4; files(): FilesV4; /** * Creates a language model targeting the Gemini Interactions API * (`POST /v1beta/interactions`). Pass: * - a model ID (string), * - `{ agent: <name> }` to use a known Gemini agent preset, or * - `{ managedAgent: <name> }` to use a user-defined agent created via * the `/v1beta/agents` endpoint. */ interactions( modelIdOrAgent: | GoogleInteractionsModelId | { agent: GoogleInteractionsAgentName } | { managedAgent: string }, ): LanguageModelV4; experimental_realtime: RealtimeFactoryV4; tools: typeof googleTools; } export interface GoogleProviderSettings { /** * Use a different URL prefix for API calls, e.g. to use proxy servers. * The default prefix is `https://generativelanguage.googleapis.com/v1beta`. */ baseURL?: string; /** * API key that is being send using the `x-goog-api-key` header. * It defaults to the `GOOGLE_GENERATIVE_AI_API_KEY` environment variable. */ apiKey?: string; /** * Custom headers to include in the requests. */ headers?: Record<string, string | undefined>; /** * Custom fetch implementation. You can use it as a middleware to intercept requests, * or to provide a custom fetch implementation for e.g. testing. */ fetch?: FetchFunction; /** * Optional function to generate a unique ID for each request. */ generateId?: () => string; /** * Custom WebSocket implementation. This is useful for testing or for * runtimes that need a WebSocket constructor with header support. */ webSocket?: WebSocketConstructor; /** * Custom provider name * Defaults to 'google.generative-ai'. */ name?: string; } const supportedExternalUrlMediaTypes = [ 'text/html', 'text/css', 'text/plain', 'text/xml', 'text/csv', 'text/rtf', 'text/javascript', 'application/json', 'application/pdf', 'image/bmp', 'image/jpeg', 'image/png', 'image/webp', 'video/mp4', 'video/mpeg', 'video/quicktime', 'video/avi', 'video/x-flv', 'video/mpg', 'video/webm', 'video/wmv', 'video/3gpp', ]; const externalHttpsUrlPattern = /^https:\/\/.*$/; function supportsExternalFileUrls(modelId: string) { return /(^|\/)gemini-/.test(modelId) && !/(^|\/)gemini-2\.0/.test(modelId); } /** * Create a Google provider instance. */ export function createGoogle( options: GoogleProviderSettings = {}, ): GoogleProvider { const baseURL = withoutTrailingSlash(options.baseURL) ?? DEFAULT_BASE_URL; const providerName = options.name ?? 'google.generative-ai'; const getHeaders = () => withUserAgentSuffix( { 'x-goog-api-key': loadApiKey({ apiKey: options.apiKey, environmentVariableName: 'GOOGLE_GENERATIVE_AI_API_KEY', description: 'Google Generative AI', }), ...options.headers, }, `ai-sdk/google/${VERSION}`, ); const createChatModel = (modelId: GoogleModelId) => new GoogleBatchLanguageModel(modelId, { provider: providerName, baseURL, headers: getHeaders, generateId: options.generateId ?? generateId, supportedUrls: () => ({ '*': [ // Default Google Generative Language "files" endpoint // e.g. https://generativelanguage.googleapis.com/v1beta/files/... googleFilesUrlPattern, // Configured Google Generative Language "files" endpoint new RegExp(`^${baseURL}/files/.*$`), // YouTube URLs (public or unlisted videos) new RegExp( `^https://(?:www\\.)?youtube\\.com/watch\\?v=[\\w-]+(?:&[\\w=&.-]*)?$`, ), new RegExp(`^https://youtu\\.be/[\\w-]+(?:\\?[\\w=&.-]*)?$`), ], ...(supportsExternalFileUrls(modelId) ? Object.fromEntries( supportedExternalUrlMediaTypes.map(mediaType => [ mediaType, [externalHttpsUrlPattern], ]), ) : {}), }), fetch: options.fetch, }); const createEmbeddingModel = (modelId: GoogleEmbeddingModelId) => new GoogleEmbeddingModel(modelId, { provider: providerName, baseURL, headers: getHeaders, fetch: options.fetch, }); const createImageModel = ( modelId: GoogleImageModelId, settings: GoogleImageSettings = {}, ) => new GoogleImageModel(modelId, settings, { provider: providerName, baseURL, headers: getHeaders, fetch: options.fetch, }); const createFiles = () => new GoogleFiles({ provider: providerName, baseURL, headers: getHeaders, fetch: options.fetch, }); const createVideoModel = (modelId: GoogleVideoModelId) => new GoogleVideoModel(modelId, { provider: providerName, baseURL, headers: getHeaders, fetch: options.fetch, generateId: options.generateId ?? generateId, }); const createRealtimeModel = (modelId: string) => new GoogleRealtimeModel(modelId, { provider: `${providerName}.realtime`, baseURL, headers: getHeaders, fetch: options.fetch, }); const createSpeechTranslationModel = ( modelId: GoogleSpeechTranslationModelId, ) => new GoogleSpeechTranslationModel(modelId, { provider: `${providerName}.speech-translation`, baseURL, headers: getHeaders, webSocket: options.webSocket, }); const createSpeechModel = (modelId: GoogleSpeechModelId) => new GoogleSpeechModel(modelId, { provider: `${providerName}.speech`, baseURL, headers: getHeaders, fetch: options.fetch, }); const createTranscriptionModel = (modelId: GoogleTranscriptionModelId) => new GoogleTranscriptionModel(modelId, { provider: `${providerName}.transcription`, baseURL, headers: getHeaders, fetch: options.fetch, webSocket: options.webSocket, }); const experimentalRealtimeFactory = Object.assign( (modelId: string) => createRealtimeModel(modelId), { getToken: async (tokenOptions: RealtimeFactoryV4GetTokenOptions) => { const model = createRealtimeModel(tokenOptions.model); const secret = await model.doCreateClientSecret({ sessionConfig: tokenOptions.sessionConfig, expiresAfterSeconds: tokenOptions.expiresAfterSeconds, }); return { token: secret.token, url: secret.url, expiresAt: secret.expiresAt, }; }, }, ) as RealtimeFactoryV4; const createInteractionsModel = ( modelIdOrAgent: | GoogleInteractionsModelId | { agent: GoogleInteractionsAgentName } | { managedAgent: string }, ) => new GoogleInteractionsLanguageModel( modelIdOrAgent as GoogleInteractionsModelInput, { provider: `${providerName}.interactions`, baseURL, headers: getHeaders, generateId: options.generateId ?? generateId, fetch: options.fetch, }, ); const provider = function (modelId: GoogleModelId) { if (new.target) { throw new Error( 'The Google Generative AI model function cannot be called with the new keyword.', ); } return createChatModel(modelId); }; provider.specificationVersion = 'v4' as const; provider.languageModel = createChatModel; provider.chat = createChatModel; provider.generativeAI = createChatModel; provider.embedding = createEmbeddingModel; provider.embeddingModel = createEmbeddingModel; provider.textEmbedding = createEmbeddingModel; provider.textEmbeddingModel = createEmbeddingModel; provider.image = createImageModel; provider.imageModel = createImageModel; provider.video = createVideoModel; provider.videoModel = createVideoModel; provider.experimental_realtime = experimentalRealtimeFactory; provider.files = createFiles; provider.speech = createSpeechModel; provider.speechModel = createSpeechModel; provider.transcription = createTranscriptionModel; provider.transcriptionModel = createTranscriptionModel; provider.translation = createSpeechTranslationModel; provider.speechTranslationModel = createSpeechTranslationModel; provider.interactions = createInteractionsModel; provider.tools = googleTools; return provider as GoogleProvider; } /** * Default Google Generative AI provider instance. */ export const google = createGoogle();