@tanstack/ai-gemini 0.10.7 → 0.10.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/esm/adapters/audio.d.ts +1 -1
  2. package/dist/esm/adapters/audio.js +3 -2
  3. package/dist/esm/adapters/audio.js.map +1 -1
  4. package/dist/esm/adapters/image.d.ts +1 -1
  5. package/dist/esm/adapters/image.js +13 -8
  6. package/dist/esm/adapters/image.js.map +1 -1
  7. package/dist/esm/adapters/text.d.ts +1 -1
  8. package/dist/esm/adapters/text.js +45 -25
  9. package/dist/esm/adapters/text.js.map +1 -1
  10. package/dist/esm/adapters/tts.d.ts +1 -1
  11. package/dist/esm/adapters/tts.js +6 -5
  12. package/dist/esm/adapters/tts.js.map +1 -1
  13. package/dist/esm/image/image-provider-options.js +3 -2
  14. package/dist/esm/image/image-provider-options.js.map +1 -1
  15. package/dist/esm/model-meta.d.ts +23 -1
  16. package/dist/esm/model-meta.js +5 -1
  17. package/dist/esm/model-meta.js.map +1 -1
  18. package/dist/esm/tools/code-execution-tool.js +3 -2
  19. package/dist/esm/tools/code-execution-tool.js.map +1 -1
  20. package/dist/esm/tools/computer-use-tool.d.ts +2 -2
  21. package/dist/esm/tools/computer-use-tool.js +15 -6
  22. package/dist/esm/tools/computer-use-tool.js.map +1 -1
  23. package/dist/esm/tools/file-search-tool.js +3 -2
  24. package/dist/esm/tools/file-search-tool.js.map +1 -1
  25. package/dist/esm/tools/function-declaration-tool.js +1 -2
  26. package/dist/esm/tools/function-declaration-tool.js.map +1 -1
  27. package/dist/esm/tools/google-maps-tool.js +3 -2
  28. package/dist/esm/tools/google-maps-tool.js.map +1 -1
  29. package/dist/esm/tools/google-search-retriveal-tool.js +3 -2
  30. package/dist/esm/tools/google-search-retriveal-tool.js.map +1 -1
  31. package/dist/esm/tools/google-search-tool.js +3 -2
  32. package/dist/esm/tools/google-search-tool.js.map +1 -1
  33. package/dist/esm/tools/url-context-tool.js +3 -2
  34. package/dist/esm/tools/url-context-tool.js.map +1 -1
  35. package/package.json +3 -3
  36. package/src/adapters/audio.ts +2 -2
  37. package/src/adapters/image.ts +13 -6
  38. package/src/adapters/text.ts +69 -37
  39. package/src/adapters/tts.ts +7 -6
  40. package/src/image/image-provider-options.ts +3 -2
  41. package/src/model-meta.ts +43 -0
  42. package/src/tools/code-execution-tool.ts +3 -3
  43. package/src/tools/computer-use-tool.ts +18 -7
  44. package/src/tools/file-search-tool.ts +3 -3
  45. package/src/tools/function-declaration-tool.ts +1 -2
  46. package/src/tools/google-maps-tool.ts +3 -3
  47. package/src/tools/google-search-retriveal-tool.ts +3 -3
  48. package/src/tools/google-search-tool.ts +3 -3
  49. package/src/tools/url-context-tool.ts +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"tts.js","sources":["../../../src/adapters/tts.ts"],"sourcesContent":["import { BaseTTSAdapter } from '@tanstack/ai/adapters'\nimport {\n createGeminiClient,\n generateId,\n getGeminiApiKeyFromEnv,\n} from '../utils'\nimport { GEMINI_TTS_VOICES } from '../model-meta'\nimport type { GEMINI_TTS_MODELS, GeminiTTSVoice } from '../model-meta'\nimport type { TTSOptions, TTSResult } from '@tanstack/ai'\nimport type { GoogleGenAI, SpeechConfig } from '@google/genai'\nimport type { GeminiClientConfig } from '../utils'\n\n/**\n * Configuration for a single speaker in a multi-speaker dialogue.\n * Supported by Gemini 3.1 Flash TTS Preview and the 2.5 TTS models.\n */\nexport interface GeminiSpeakerVoiceConfig {\n /** A name used in the prompt to refer to this speaker */\n speaker: string\n /** Voice configuration for this speaker */\n voiceConfig: {\n prebuiltVoiceConfig: {\n voiceName: GeminiTTSVoice\n }\n }\n}\n\n/**\n * Provider-specific options for Gemini TTS\n *\n * @experimental Gemini TTS is an experimental feature.\n * @see https://ai.google.dev/gemini-api/docs/speech-generation\n * @see https://ai.google.dev/gemini-api/docs/models/gemini-3.1-flash-tts-preview\n */\nexport interface GeminiTTSProviderOptions {\n /**\n * Voice configuration for single-speaker TTS.\n * Choose from 30 available voices with different characteristics.\n *\n * Use `multiSpeakerVoiceConfig` instead for dialogues.\n */\n voiceConfig?: {\n prebuiltVoiceConfig?: {\n /**\n * The voice name to use for speech synthesis.\n * @see https://ai.google.dev/gemini-api/docs/speech-generation#voices\n */\n voiceName?: GeminiTTSVoice\n }\n }\n\n /**\n * Multi-speaker voice configuration (up to 2 speakers).\n * Supported by Gemini 3.1 Flash TTS Preview and the 2.5 TTS models.\n *\n * Each speaker's lines in the prompt are prefixed with the name defined\n * here, e.g.:\n *\n * ```text\n * Joe: Hey, how's it going?\n * Jane: Not bad, you?\n * ```\n */\n multiSpeakerVoiceConfig?: {\n speakerVoiceConfigs: Array<GeminiSpeakerVoiceConfig>\n }\n\n /**\n * System instruction for controlling speech style.\n * Use natural language to describe the desired speaking style,\n * pace, tone, accent, or other characteristics.\n *\n * With Gemini 3.1 Flash TTS, you can also use inline audio tags like\n * `[whispering]`, `[laughs]`, `[excited]` directly in the input text\n * to control delivery.\n *\n * @example \"Speak slowly and calmly, as if telling a bedtime story\"\n * @example \"Use an upbeat, enthusiastic tone with moderate pace\"\n * @example \"Speak with a British accent\"\n */\n systemInstruction?: string\n\n /**\n * Language code hint for the speech synthesis.\n * Gemini 3.1 Flash TTS supports 70+ languages with auto-detection;\n * the 2.5 TTS models support 24 languages.\n *\n * @example \"en-US\" for American English\n * @example \"es-ES\" for Spanish (Spain)\n * @example \"ja-JP\" for Japanese\n */\n languageCode?: string\n}\n\n/**\n * Configuration for Gemini TTS adapter\n *\n * @experimental Gemini TTS is an experimental feature.\n */\nexport interface GeminiTTSConfig extends GeminiClientConfig {}\n\n/** Model type for Gemini TTS */\nexport type GeminiTTSModel = (typeof GEMINI_TTS_MODELS)[number]\n\n/**\n * Gemini Text-to-Speech Adapter\n *\n * Tree-shakeable adapter for Gemini TTS functionality.\n *\n * **IMPORTANT**: Gemini TTS uses the Live API (WebSocket-based) which requires\n * different handling than traditional REST APIs. This adapter provides a\n * simplified interface but may have limitations.\n *\n * @experimental Gemini TTS is an experimental feature and may change.\n *\n * Models:\n * - gemini-2.5-flash-preview-tts\n */\nexport class GeminiTTSAdapter<\n TModel extends GeminiTTSModel,\n> extends BaseTTSAdapter<TModel, GeminiTTSProviderOptions> {\n readonly name = 'gemini' as const\n\n private client: GoogleGenAI\n\n constructor(config: GeminiTTSConfig, model: TModel) {\n super(model, config)\n this.client = createGeminiClient(config)\n }\n\n /**\n * Generate speech from text using Gemini's TTS model.\n *\n * @experimental This implementation is experimental and may change.\n * @see https://ai.google.dev/gemini-api/docs/speech-generation\n */\n async generateSpeech(\n options: TTSOptions<GeminiTTSProviderOptions>,\n ): Promise<TTSResult> {\n const { model, text, modelOptions, voice, logger } = options\n\n logger.request(`activity=generateSpeech provider=gemini model=${model}`, {\n provider: 'gemini',\n model,\n })\n\n const speechConfig: SpeechConfig = {}\n\n if (modelOptions?.multiSpeakerVoiceConfig) {\n // Validate multi-speaker config: 1 or 2 speakers allowed.\n const speakerConfigs =\n modelOptions.multiSpeakerVoiceConfig.speakerVoiceConfigs\n if (\n !Array.isArray(speakerConfigs) ||\n speakerConfigs.length < 1 ||\n speakerConfigs.length > 2\n ) {\n throw new Error(\n `Gemini TTS multiSpeakerVoiceConfig.speakerVoiceConfigs must contain 1 or 2 speakers; received ${Array.isArray(speakerConfigs) ? speakerConfigs.length : 'non-array'}.`,\n )\n }\n speechConfig.multiSpeakerVoiceConfig =\n modelOptions.multiSpeakerVoiceConfig\n } else {\n // Honor the standard TTSOptions.voice (used by every other TTS adapter)\n // as a fallback for the prebuilt voice name. If an explicit\n // modelOptions.voiceConfig is supplied its values win — but we still\n // fall back to `voice` / 'Kore' if the supplied voiceConfig is missing\n // prebuiltVoiceConfig.voiceName.\n if (\n voice !== undefined &&\n !(GEMINI_TTS_VOICES as ReadonlyArray<string>).includes(voice)\n ) {\n throw new Error(\n `Invalid Gemini TTS voice \"${voice}\". Valid voices are: ${GEMINI_TTS_VOICES.join(', ')}.`,\n )\n }\n const defaultVoiceName = (voice as GeminiTTSVoice | undefined) ?? 'Kore'\n const supplied = modelOptions?.voiceConfig\n const resolvedVoiceName =\n supplied?.prebuiltVoiceConfig?.voiceName ?? defaultVoiceName\n speechConfig.voiceConfig = {\n prebuiltVoiceConfig: { voiceName: resolvedVoiceName },\n }\n }\n\n if (modelOptions?.languageCode) {\n speechConfig.languageCode = modelOptions.languageCode\n }\n\n try {\n const response = await this.client.models.generateContent({\n model,\n contents: [\n {\n role: 'user',\n parts: [{ text }],\n },\n ],\n config: {\n responseModalities: ['AUDIO'],\n speechConfig,\n // systemInstruction belongs inside `config` per the @google/genai\n // contract — matches sibling Gemini adapters (summarize, text).\n ...(modelOptions?.systemInstruction && {\n systemInstruction: modelOptions.systemInstruction,\n }),\n },\n })\n\n // Extract audio data from response\n const candidate = response.candidates?.[0]\n const parts = candidate?.content?.parts\n\n if (!parts || parts.length === 0) {\n throw new Error('No audio output received from Gemini TTS')\n }\n\n // Look for inline data (audio)\n const audioPart = parts.find((part: any) =>\n part.inlineData?.mimeType?.startsWith('audio/'),\n )\n\n if (!audioPart || !audioPart.inlineData || !audioPart.inlineData.data) {\n throw new Error('No audio data in Gemini TTS response')\n }\n\n const audioBase64 = audioPart.inlineData.data\n // mime is guaranteed by the `startsWith('audio/')` find predicate above.\n const mimeType = audioPart.inlineData.mimeType as string\n\n // Gemini TTS models return raw 16-bit LE PCM with a mime type like\n // `audio/L16;codec=pcm;rate=24000`. That isn't playable in an <audio>\n // element and the bare string isn't a usable file extension, so we\n // prepend a RIFF/WAV header here and normalize the result to audio/wav.\n const pcm = parsePcmMimeType(mimeType)\n if (pcm) {\n const wavBase64 = wrapPcmBase64AsWav(\n audioBase64,\n pcm.sampleRate,\n pcm.channels,\n pcm.bitsPerSample,\n )\n return {\n id: generateId(this.name),\n model,\n audio: wavBase64,\n format: 'wav',\n contentType: 'audio/wav',\n }\n }\n\n // Strip any mime parameters (e.g. `audio/ogg;codec=opus`) before pulling\n // the subtype out as the file format.\n const format = mimeType.split(';')[0]!.split('/')[1] || 'wav'\n\n return {\n id: generateId(this.name),\n model,\n audio: audioBase64,\n format,\n contentType: mimeType,\n }\n } catch (error) {\n logger.errors('gemini.generateSpeech fatal', {\n error,\n source: 'gemini.generateSpeech',\n })\n throw error\n }\n }\n}\n\nfunction parsePcmMimeType(\n mimeType: string,\n): { sampleRate: number; channels: number; bitsPerSample: number } | undefined {\n const normalized = mimeType.toLowerCase()\n const subtype = normalized.split(';')[0]!.split('/')[1] ?? ''\n // Exclude containerized wav (e.g. `audio/wav;codec=pcm`) — those already\n // carry a RIFF header and must not be re-wrapped.\n if (subtype.includes('wav')) return undefined\n\n // Accept the variants Gemini and other providers actually emit:\n // - audio/L16;codec=pcm;rate=24000 (IANA PCM with bit depth in the type)\n // - audio/L24 and friends\n // - audio/pcm and audio/x-pcm\n // - anything else that explicitly tags codec=pcm and isn't wav-containered\n const bitDepthMatch = /^audio\\/l(\\d+)/.exec(normalized)\n const isPcm =\n bitDepthMatch !== null ||\n normalized.startsWith('audio/pcm') ||\n normalized.startsWith('audio/x-pcm') ||\n normalized.includes('codec=pcm')\n if (!isPcm) return undefined\n\n const rateMatch = /rate=(\\d+)/.exec(normalized)\n const channelsMatch = /channels=(\\d+)/.exec(normalized)\n // Default to 16-bit when the mime type doesn't specify — matches Gemini's\n // audio/L16;codec=pcm;rate=24000 response.\n const bitsPerSample = bitDepthMatch ? Number(bitDepthMatch[1]) : 16\n return {\n sampleRate: rateMatch ? Number(rateMatch[1]) : 24000,\n channels: channelsMatch ? Number(channelsMatch[1]) : 1,\n bitsPerSample,\n }\n}\n\nfunction wrapPcmBase64AsWav(\n pcmBase64: string,\n sampleRate: number,\n channels = 1,\n bitsPerSample = 16,\n): string {\n // The WAV writer below emits a 16-bit PCM fmt chunk. If the source claims a\n // different bit depth we'd be lying about the payload, so bail out loudly\n // rather than producing a corrupt file.\n if (bitsPerSample !== 16) {\n throw new Error(\n `Unsupported PCM bit depth ${bitsPerSample}: only 16-bit PCM can be wrapped as WAV.`,\n )\n }\n\n const pcmBytes =\n typeof Buffer !== 'undefined'\n ? new Uint8Array(Buffer.from(pcmBase64, 'base64'))\n : decodeBase64(pcmBase64)\n\n const byteRate = (sampleRate * channels * bitsPerSample) / 8\n const blockAlign = (channels * bitsPerSample) / 8\n const dataSize = pcmBytes.byteLength\n const buffer = new ArrayBuffer(44 + dataSize)\n const view = new DataView(buffer)\n\n writeAscii(view, 0, 'RIFF')\n view.setUint32(4, 36 + dataSize, true)\n writeAscii(view, 8, 'WAVE')\n writeAscii(view, 12, 'fmt ')\n view.setUint32(16, 16, true)\n view.setUint16(20, 1, true)\n view.setUint16(22, channels, true)\n view.setUint32(24, sampleRate, true)\n view.setUint32(28, byteRate, true)\n view.setUint16(32, blockAlign, true)\n view.setUint16(34, bitsPerSample, true)\n writeAscii(view, 36, 'data')\n view.setUint32(40, dataSize, true)\n new Uint8Array(buffer, 44).set(pcmBytes)\n\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(buffer).toString('base64')\n }\n let binary = ''\n const bytes = new Uint8Array(buffer)\n for (let i = 0; i < bytes.byteLength; i += 1) {\n binary += String.fromCharCode(bytes[i]!)\n }\n return btoa(binary)\n}\n\nfunction decodeBase64(b64: string): Uint8Array {\n const binary = atob(b64)\n const out = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i += 1) out[i] = binary.charCodeAt(i)\n return out\n}\n\nfunction writeAscii(view: DataView, offset: number, text: string): void {\n for (let i = 0; i < text.length; i += 1) {\n view.setUint8(offset + i, text.charCodeAt(i))\n }\n}\n\n/**\n * Creates a Gemini TTS adapter with explicit API key.\n * Type resolution happens here at the call site.\n *\n * @experimental Gemini TTS is an experimental feature and may change.\n *\n * @param model - The model name (e.g., 'gemini-2.5-flash-preview-tts')\n * @param apiKey - Your Google API key\n * @param config - Optional additional configuration\n * @returns Configured Gemini TTS adapter instance with resolved types\n *\n * @example\n * ```typescript\n * const adapter = createGeminiSpeech('gemini-2.5-flash-preview-tts', \"your-api-key\");\n *\n * const result = await generateSpeech({\n * adapter,\n * text: 'Hello, world!'\n * });\n * ```\n */\nexport function createGeminiSpeech<TModel extends GeminiTTSModel>(\n model: TModel,\n apiKey: string,\n config?: Omit<GeminiTTSConfig, 'apiKey'>,\n): GeminiTTSAdapter<TModel> {\n // Put apiKey LAST so caller-supplied config can't silently override the\n // explicit argument.\n return new GeminiTTSAdapter({ ...config, apiKey }, model)\n}\n\n/**\n * Creates a Gemini speech adapter with automatic API key detection from environment variables.\n * Type resolution happens here at the call site.\n *\n * @experimental Gemini TTS is an experimental feature and may change.\n *\n * Looks for `GOOGLE_API_KEY` or `GEMINI_API_KEY` in:\n * - `process.env` (Node.js)\n * - `window.env` (Browser with injected env)\n *\n * @param model - The model name (e.g., 'gemini-2.5-flash-preview-tts')\n * @param config - Optional configuration (excluding apiKey which is auto-detected)\n * @returns Configured Gemini speech adapter instance with resolved types\n * @throws Error if GOOGLE_API_KEY or GEMINI_API_KEY is not found in environment\n *\n * @example\n * ```typescript\n * // Automatically uses GOOGLE_API_KEY from environment\n * const adapter = geminiSpeech('gemini-2.5-flash-preview-tts');\n *\n * const result = await generateSpeech({\n * adapter,\n * text: 'Welcome to TanStack AI!'\n * });\n * ```\n */\nexport function geminiSpeech<TModel extends GeminiTTSModel>(\n model: TModel,\n config?: Omit<GeminiTTSConfig, 'apiKey'>,\n): GeminiTTSAdapter<TModel> {\n const apiKey = getGeminiApiKeyFromEnv()\n return createGeminiSpeech(model, apiKey, config)\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tts.js","sources":["../../../src/adapters/tts.ts"],"sourcesContent":["import { BaseTTSAdapter } from '@tanstack/ai/adapters'\nimport {\n createGeminiClient,\n generateId,\n getGeminiApiKeyFromEnv,\n} from '../utils'\nimport { GEMINI_TTS_VOICES } from '../model-meta'\nimport type { GEMINI_TTS_MODELS, GeminiTTSVoice } from '../model-meta'\nimport type { TTSOptions, TTSResult } from '@tanstack/ai'\nimport type { GoogleGenAI, SpeechConfig } from '@google/genai'\nimport type { GeminiClientConfig } from '../utils'\n\n/**\n * Configuration for a single speaker in a multi-speaker dialogue.\n * Supported by Gemini 3.1 Flash TTS Preview and the 2.5 TTS models.\n */\nexport interface GeminiSpeakerVoiceConfig {\n /** A name used in the prompt to refer to this speaker */\n speaker: string\n /** Voice configuration for this speaker */\n voiceConfig: {\n prebuiltVoiceConfig: {\n voiceName: GeminiTTSVoice\n }\n }\n}\n\n/**\n * Provider-specific options for Gemini TTS\n *\n * @experimental Gemini TTS is an experimental feature.\n * @see https://ai.google.dev/gemini-api/docs/speech-generation\n * @see https://ai.google.dev/gemini-api/docs/models/gemini-3.1-flash-tts-preview\n */\nexport interface GeminiTTSProviderOptions {\n /**\n * Voice configuration for single-speaker TTS.\n * Choose from 30 available voices with different characteristics.\n *\n * Use `multiSpeakerVoiceConfig` instead for dialogues.\n */\n voiceConfig?: {\n prebuiltVoiceConfig?: {\n /**\n * The voice name to use for speech synthesis.\n * @see https://ai.google.dev/gemini-api/docs/speech-generation#voices\n */\n voiceName?: GeminiTTSVoice\n }\n }\n\n /**\n * Multi-speaker voice configuration (up to 2 speakers).\n * Supported by Gemini 3.1 Flash TTS Preview and the 2.5 TTS models.\n *\n * Each speaker's lines in the prompt are prefixed with the name defined\n * here, e.g.:\n *\n * ```text\n * Joe: Hey, how's it going?\n * Jane: Not bad, you?\n * ```\n */\n multiSpeakerVoiceConfig?: {\n speakerVoiceConfigs: Array<GeminiSpeakerVoiceConfig>\n }\n\n /**\n * System instruction for controlling speech style.\n * Use natural language to describe the desired speaking style,\n * pace, tone, accent, or other characteristics.\n *\n * With Gemini 3.1 Flash TTS, you can also use inline audio tags like\n * `[whispering]`, `[laughs]`, `[excited]` directly in the input text\n * to control delivery.\n *\n * @example \"Speak slowly and calmly, as if telling a bedtime story\"\n * @example \"Use an upbeat, enthusiastic tone with moderate pace\"\n * @example \"Speak with a British accent\"\n */\n systemInstruction?: string\n\n /**\n * Language code hint for the speech synthesis.\n * Gemini 3.1 Flash TTS supports 70+ languages with auto-detection;\n * the 2.5 TTS models support 24 languages.\n *\n * @example \"en-US\" for American English\n * @example \"es-ES\" for Spanish (Spain)\n * @example \"ja-JP\" for Japanese\n */\n languageCode?: string\n}\n\n/**\n * Configuration for Gemini TTS adapter\n *\n * @experimental Gemini TTS is an experimental feature.\n */\nexport interface GeminiTTSConfig extends GeminiClientConfig {}\n\n/** Model type for Gemini TTS */\nexport type GeminiTTSModel = (typeof GEMINI_TTS_MODELS)[number]\n\n/**\n * Gemini Text-to-Speech Adapter\n *\n * Tree-shakeable adapter for Gemini TTS functionality.\n *\n * **IMPORTANT**: Gemini TTS uses the Live API (WebSocket-based) which requires\n * different handling than traditional REST APIs. This adapter provides a\n * simplified interface but may have limitations.\n *\n * @experimental Gemini TTS is an experimental feature and may change.\n *\n * Models:\n * - gemini-2.5-flash-preview-tts\n */\nexport class GeminiTTSAdapter<\n TModel extends GeminiTTSModel,\n> extends BaseTTSAdapter<TModel, GeminiTTSProviderOptions> {\n readonly name = 'gemini' as const\n\n private readonly client: GoogleGenAI\n\n constructor(config: GeminiTTSConfig, model: TModel) {\n super(model, config)\n this.client = createGeminiClient(config)\n }\n\n /**\n * Generate speech from text using Gemini's TTS model.\n *\n * @experimental This implementation is experimental and may change.\n * @see https://ai.google.dev/gemini-api/docs/speech-generation\n */\n async generateSpeech(\n options: TTSOptions<GeminiTTSProviderOptions>,\n ): Promise<TTSResult> {\n const { model, text, modelOptions, voice, logger } = options\n\n logger.request(`activity=generateSpeech provider=gemini model=${model}`, {\n provider: 'gemini',\n model,\n })\n\n const speechConfig: SpeechConfig = {}\n\n if (modelOptions?.multiSpeakerVoiceConfig) {\n // Validate multi-speaker config: 1 or 2 speakers allowed.\n const speakerConfigs =\n modelOptions.multiSpeakerVoiceConfig.speakerVoiceConfigs\n if (\n !Array.isArray(speakerConfigs) ||\n speakerConfigs.length < 1 ||\n speakerConfigs.length > 2\n ) {\n throw new Error(\n `Gemini TTS multiSpeakerVoiceConfig.speakerVoiceConfigs must contain 1 or 2 speakers; received ${Array.isArray(speakerConfigs) ? speakerConfigs.length : 'non-array'}.`,\n )\n }\n speechConfig.multiSpeakerVoiceConfig =\n modelOptions.multiSpeakerVoiceConfig\n } else {\n // Honor the standard TTSOptions.voice (used by every other TTS adapter)\n // as a fallback for the prebuilt voice name. If an explicit\n // modelOptions.voiceConfig is supplied its values win — but we still\n // fall back to `voice` / 'Kore' if the supplied voiceConfig is missing\n // prebuiltVoiceConfig.voiceName.\n if (\n voice !== undefined &&\n !(GEMINI_TTS_VOICES as ReadonlyArray<string>).includes(voice)\n ) {\n throw new Error(\n `Invalid Gemini TTS voice \"${voice}\". Valid voices are: ${GEMINI_TTS_VOICES.join(', ')}.`,\n )\n }\n const defaultVoiceName = (voice as GeminiTTSVoice | undefined) ?? 'Kore'\n const supplied = modelOptions?.voiceConfig\n const resolvedVoiceName =\n supplied?.prebuiltVoiceConfig?.voiceName ?? defaultVoiceName\n speechConfig.voiceConfig = {\n prebuiltVoiceConfig: { voiceName: resolvedVoiceName },\n }\n }\n\n if (modelOptions?.languageCode) {\n speechConfig.languageCode = modelOptions.languageCode\n }\n\n try {\n const response = await this.client.models.generateContent({\n model,\n contents: [\n {\n role: 'user',\n parts: [{ text }],\n },\n ],\n config: {\n responseModalities: ['AUDIO'],\n speechConfig,\n // systemInstruction belongs inside `config` per the @google/genai\n // contract — matches sibling Gemini adapters (summarize, text).\n ...(modelOptions?.systemInstruction && {\n systemInstruction: modelOptions.systemInstruction,\n }),\n },\n })\n\n // Extract audio data from response\n const candidate = response.candidates?.[0]\n const parts = candidate?.content?.parts\n\n if (!parts || parts.length === 0) {\n throw new Error('No audio output received from Gemini TTS')\n }\n\n // Look for inline data (audio)\n const audioPart = parts.find((part: any) =>\n part.inlineData?.mimeType?.startsWith('audio/'),\n )\n\n if (!audioPart || !audioPart.inlineData || !audioPart.inlineData.data) {\n throw new Error('No audio data in Gemini TTS response')\n }\n\n const audioBase64 = audioPart.inlineData.data\n // mime is guaranteed by the `startsWith('audio/')` find predicate above.\n const mimeType = audioPart.inlineData.mimeType as string\n\n // Gemini TTS models return raw 16-bit LE PCM with a mime type like\n // `audio/L16;codec=pcm;rate=24000`. That isn't playable in an <audio>\n // element and the bare string isn't a usable file extension, so we\n // prepend a RIFF/WAV header here and normalize the result to audio/wav.\n const pcm = parsePcmMimeType(mimeType)\n if (pcm) {\n const wavBase64 = wrapPcmBase64AsWav(\n audioBase64,\n pcm.sampleRate,\n pcm.channels,\n pcm.bitsPerSample,\n )\n return {\n id: generateId(this.name),\n model,\n audio: wavBase64,\n format: 'wav',\n contentType: 'audio/wav',\n }\n }\n\n // Strip any mime parameters (e.g. `audio/ogg;codec=opus`) before pulling\n // the subtype out as the file format. `String.split` always returns at\n // least one element, so [0] is defined.\n const format = (mimeType.split(';')[0] ?? '').split('/')[1] || 'wav'\n\n return {\n id: generateId(this.name),\n model,\n audio: audioBase64,\n format,\n contentType: mimeType,\n }\n } catch (error) {\n logger.errors('gemini.generateSpeech fatal', {\n error,\n source: 'gemini.generateSpeech',\n })\n throw error\n }\n }\n}\n\nfunction parsePcmMimeType(\n mimeType: string,\n): { sampleRate: number; channels: number; bitsPerSample: number } | undefined {\n const normalized = mimeType.toLowerCase()\n const subtype = (normalized.split(';')[0] ?? '').split('/')[1] ?? ''\n // Exclude containerized wav (e.g. `audio/wav;codec=pcm`) — those already\n // carry a RIFF header and must not be re-wrapped.\n if (subtype.includes('wav')) return undefined\n\n // Accept the variants Gemini and other providers actually emit:\n // - audio/L16;codec=pcm;rate=24000 (IANA PCM with bit depth in the type)\n // - audio/L24 and friends\n // - audio/pcm and audio/x-pcm\n // - anything else that explicitly tags codec=pcm and isn't wav-containered\n const bitDepthMatch = /^audio\\/l(\\d+)/.exec(normalized)\n const isPcm =\n bitDepthMatch !== null ||\n normalized.startsWith('audio/pcm') ||\n normalized.startsWith('audio/x-pcm') ||\n normalized.includes('codec=pcm')\n if (!isPcm) return undefined\n\n const rateMatch = /rate=(\\d+)/.exec(normalized)\n const channelsMatch = /channels=(\\d+)/.exec(normalized)\n // Default to 16-bit when the mime type doesn't specify — matches Gemini's\n // audio/L16;codec=pcm;rate=24000 response.\n const bitsPerSample = bitDepthMatch ? Number(bitDepthMatch[1]) : 16\n return {\n sampleRate: rateMatch ? Number(rateMatch[1]) : 24000,\n channels: channelsMatch ? Number(channelsMatch[1]) : 1,\n bitsPerSample,\n }\n}\n\nfunction wrapPcmBase64AsWav(\n pcmBase64: string,\n sampleRate: number,\n channels = 1,\n bitsPerSample = 16,\n): string {\n // The WAV writer below emits a 16-bit PCM fmt chunk. If the source claims a\n // different bit depth we'd be lying about the payload, so bail out loudly\n // rather than producing a corrupt file.\n if (bitsPerSample !== 16) {\n throw new Error(\n `Unsupported PCM bit depth ${bitsPerSample}: only 16-bit PCM can be wrapped as WAV.`,\n )\n }\n\n const pcmBytes =\n typeof Buffer !== 'undefined'\n ? new Uint8Array(Buffer.from(pcmBase64, 'base64'))\n : decodeBase64(pcmBase64)\n\n const byteRate = (sampleRate * channels * bitsPerSample) / 8\n const blockAlign = (channels * bitsPerSample) / 8\n const dataSize = pcmBytes.byteLength\n const buffer = new ArrayBuffer(44 + dataSize)\n const view = new DataView(buffer)\n\n writeAscii(view, 0, 'RIFF')\n view.setUint32(4, 36 + dataSize, true)\n writeAscii(view, 8, 'WAVE')\n writeAscii(view, 12, 'fmt ')\n view.setUint32(16, 16, true)\n view.setUint16(20, 1, true)\n view.setUint16(22, channels, true)\n view.setUint32(24, sampleRate, true)\n view.setUint32(28, byteRate, true)\n view.setUint16(32, blockAlign, true)\n view.setUint16(34, bitsPerSample, true)\n writeAscii(view, 36, 'data')\n view.setUint32(40, dataSize, true)\n new Uint8Array(buffer, 44).set(pcmBytes)\n\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(buffer).toString('base64')\n }\n let binary = ''\n const bytes = new Uint8Array(buffer)\n for (const byte of bytes) {\n binary += String.fromCharCode(byte)\n }\n return btoa(binary)\n}\n\nfunction decodeBase64(b64: string): Uint8Array {\n const binary = atob(b64)\n const out = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i += 1) out[i] = binary.charCodeAt(i)\n return out\n}\n\nfunction writeAscii(view: DataView, offset: number, text: string): void {\n for (let i = 0; i < text.length; i += 1) {\n view.setUint8(offset + i, text.charCodeAt(i))\n }\n}\n\n/**\n * Creates a Gemini TTS adapter with explicit API key.\n * Type resolution happens here at the call site.\n *\n * @experimental Gemini TTS is an experimental feature and may change.\n *\n * @param model - The model name (e.g., 'gemini-2.5-flash-preview-tts')\n * @param apiKey - Your Google API key\n * @param config - Optional additional configuration\n * @returns Configured Gemini TTS adapter instance with resolved types\n *\n * @example\n * ```typescript\n * const adapter = createGeminiSpeech('gemini-2.5-flash-preview-tts', \"your-api-key\");\n *\n * const result = await generateSpeech({\n * adapter,\n * text: 'Hello, world!'\n * });\n * ```\n */\nexport function createGeminiSpeech<TModel extends GeminiTTSModel>(\n model: TModel,\n apiKey: string,\n config?: Omit<GeminiTTSConfig, 'apiKey'>,\n): GeminiTTSAdapter<TModel> {\n // Put apiKey LAST so caller-supplied config can't silently override the\n // explicit argument.\n return new GeminiTTSAdapter({ ...config, apiKey }, model)\n}\n\n/**\n * Creates a Gemini speech adapter with automatic API key detection from environment variables.\n * Type resolution happens here at the call site.\n *\n * @experimental Gemini TTS is an experimental feature and may change.\n *\n * Looks for `GOOGLE_API_KEY` or `GEMINI_API_KEY` in:\n * - `process.env` (Node.js)\n * - `window.env` (Browser with injected env)\n *\n * @param model - The model name (e.g., 'gemini-2.5-flash-preview-tts')\n * @param config - Optional configuration (excluding apiKey which is auto-detected)\n * @returns Configured Gemini speech adapter instance with resolved types\n * @throws Error if GOOGLE_API_KEY or GEMINI_API_KEY is not found in environment\n *\n * @example\n * ```typescript\n * // Automatically uses GOOGLE_API_KEY from environment\n * const adapter = geminiSpeech('gemini-2.5-flash-preview-tts');\n *\n * const result = await generateSpeech({\n * adapter,\n * text: 'Welcome to TanStack AI!'\n * });\n * ```\n */\nexport function geminiSpeech<TModel extends GeminiTTSModel>(\n model: TModel,\n config?: Omit<GeminiTTSConfig, 'apiKey'>,\n): GeminiTTSAdapter<TModel> {\n const apiKey = getGeminiApiKeyFromEnv()\n return createGeminiSpeech(model, apiKey, config)\n}\n"],"names":[],"mappings":"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"}
@@ -52,8 +52,9 @@ function validatePrompt(options) {
52
52
  }
53
53
  function parseNativeImageSize(size) {
54
54
  const match = size.match(/^(\d+:\d+)_(.+)$/);
55
- if (!match) return void 0;
56
- return { aspectRatio: match[1], resolution: match[2] };
55
+ const [, aspectRatio, resolution] = match ?? [];
56
+ if (aspectRatio === void 0 || resolution === void 0) return void 0;
57
+ return { aspectRatio, resolution };
57
58
  }
58
59
  export {
59
60
  GEMINI_SIZE_TO_ASPECT_RATIO,
@@ -1 +1 @@
1
- {"version":3,"file":"image-provider-options.js","sources":["../../../src/image/image-provider-options.ts"],"sourcesContent":["import type { GeminiImageModels } from '../model-meta'\nimport type {\n ImagePromptLanguage,\n PersonGeneration,\n SafetyFilterLevel,\n} from '@google/genai'\n\n// Re-export SDK types so users can use them directly\nexport type { ImagePromptLanguage, PersonGeneration, SafetyFilterLevel }\n\n/**\n * Gemini Imagen aspect ratio options\n * Controls the aspect ratio of generated images\n */\nexport type GeminiAspectRatio =\n | '1:1'\n | '3:4'\n | '4:3'\n | '9:16'\n | '16:9'\n | '9:21'\n | '21:9'\n\n/**\n * Provider options for Gemini image generation\n * These options match the @google/genai GenerateImagesConfig interface\n * and can be spread directly into the API request.\n */\nexport interface GeminiImageProviderOptions {\n /**\n * The aspect ratio of generated images\n * @default '1:1'\n */\n aspectRatio?: GeminiAspectRatio\n\n /**\n * Controls whether people can appear in generated images\n * Use PersonGeneration enum values: DONT_ALLOW, ALLOW_ADULT, ALLOW_ALL\n * @default 'ALLOW_ADULT'\n */\n personGeneration?: PersonGeneration\n\n /**\n * Safety filter level for content filtering\n * Use SafetyFilterLevel enum values\n */\n safetyFilterLevel?: SafetyFilterLevel\n\n /**\n * Optional seed for reproducible image generation\n * When the same seed is used with the same prompt and settings,\n * you should get similar (though not identical) results\n */\n seed?: number\n\n /**\n * Whether to add a SynthID watermark to generated images\n * SynthID helps identify AI-generated content\n * @default true\n */\n addWatermark?: boolean\n\n /**\n * Language of the prompt\n * Use ImagePromptLanguage enum values\n */\n language?: ImagePromptLanguage\n\n /**\n * Negative prompt - what to avoid in the generated image\n * Not all models support negative prompts\n */\n negativePrompt?: string\n\n /**\n * Output MIME type for the generated image\n * @default 'image/png'\n */\n outputMimeType?: 'image/png' | 'image/jpeg' | 'image/webp'\n\n /**\n * Compression quality for JPEG outputs (0-100)\n * Higher values mean better quality but larger file sizes\n * @default 75\n */\n outputCompressionQuality?: number\n\n /**\n * Controls how much the model adheres to the text prompt\n * Large values increase output and prompt alignment,\n * but may compromise image quality\n */\n guidanceScale?: number\n\n /**\n * Whether to use the prompt rewriting logic\n */\n enhancePrompt?: boolean\n\n /**\n * Whether to report the safety scores of each generated image\n * and the positive prompt in the response\n */\n includeSafetyAttributes?: boolean\n\n /**\n * Whether to include the Responsible AI filter reason\n * if the image is filtered out of the response\n */\n includeRaiReason?: boolean\n\n /**\n * Cloud Storage URI used to store the generated images\n */\n outputGcsUri?: string\n\n /**\n * User specified labels to track billing usage\n */\n labels?: Record<string, string>\n}\n\n/**\n * Model-specific provider options mapping\n * Currently all Imagen models use the same options structure\n */\nexport type GeminiImageModelProviderOptionsByName = {\n [K in GeminiImageModels]: GeminiImageProviderOptions\n}\n\n/**\n * Supported size strings for Gemini Imagen models\n * These map to aspect ratios internally\n */\nexport type GeminiImageSize =\n | '1024x1024'\n | '512x512'\n | '1024x768'\n | '1536x1024'\n | '1792x1024'\n | '1920x1080'\n | '768x1024'\n | '1024x1536'\n | '1024x1792'\n | '1080x1920'\n\n/**\n * Aspect ratios supported by Gemini native image models (via generateContent API).\n * Matches the SDK's ImageConfig.aspectRatio values.\n */\nexport type GeminiNativeImageAspectRatio =\n | '1:1'\n | '2:3'\n | '3:2'\n | '3:4'\n | '4:3'\n | '9:16'\n | '16:9'\n | '21:9'\n\n/**\n * Resolution tiers for Gemini native image models.\n * Matches the SDK's ImageConfig.imageSize values.\n */\nexport type GeminiNativeImageResolution = '1K' | '2K' | '4K'\n\n/**\n * Template literal size type for Gemini native image models: \"16:9_4K\", \"1:1_2K\", etc.\n */\nexport type GeminiNativeImageSize =\n `${GeminiNativeImageAspectRatio}_${GeminiNativeImageResolution}`\n\n/**\n * Gemini native image models that use the generateContent API path.\n * These models support template literal sizes (aspectRatio_resolution).\n */\nexport type GeminiNativeImageModels =\n | 'gemini-3.1-flash-image-preview'\n | 'gemini-3-pro-image-preview'\n | 'gemini-2.5-flash-image'\n | 'gemini-2.0-flash-preview-image-generation'\n\n/**\n * Model-specific size options mapping.\n * Gemini native image models use template literal sizes, Imagen models use pixel sizes.\n */\nexport type GeminiImageModelSizeByName = {\n [K in GeminiNativeImageModels]: GeminiNativeImageSize\n} & {\n [K in Exclude<GeminiImageModels, GeminiNativeImageModels>]: GeminiImageSize\n}\n\n/**\n * Valid sizes for Gemini Imagen models\n * Gemini uses aspect ratios, but we map common WIDTHxHEIGHT formats to aspect ratios\n * These are approximate mappings based on common image dimensions\n */\nexport const GEMINI_SIZE_TO_ASPECT_RATIO: Record<string, GeminiAspectRatio> = {\n // Square\n '1024x1024': '1:1',\n '512x512': '1:1',\n // Landscape\n '1024x768': '4:3',\n '1536x1024': '4:3',\n '1792x1024': '16:9',\n '1920x1080': '16:9',\n // Portrait\n '768x1024': '3:4',\n '1024x1536': '3:4', // Inverted\n '1024x1792': '9:16',\n '1080x1920': '9:16',\n}\n\n/**\n * Maps a WIDTHxHEIGHT size string to a Gemini aspect ratio\n * Returns undefined if the size cannot be mapped\n */\nexport function sizeToAspectRatio(\n size: string | undefined,\n): GeminiAspectRatio | undefined {\n if (!size) return undefined\n return GEMINI_SIZE_TO_ASPECT_RATIO[size]\n}\n\n/**\n * Validates that the provided size can be mapped to an aspect ratio\n * Throws an error if the size is invalid\n */\nexport function validateImageSize(\n model: string,\n size: string | undefined,\n): void {\n if (!size) return\n\n const aspectRatio = sizeToAspectRatio(size)\n if (!aspectRatio) {\n const validSizes = Object.keys(GEMINI_SIZE_TO_ASPECT_RATIO)\n throw new Error(\n `Invalid size \"${size}\" for model \"${model}\". ` +\n `Gemini Imagen uses aspect ratios. Valid sizes that map to aspect ratios: ${validSizes.join(', ')}. ` +\n `Alternatively, use providerOptions.aspectRatio directly with values: 1:1, 3:4, 4:3, 9:16, 16:9, 9:21, 21:9`,\n )\n }\n}\n\n/**\n * Per-model caps on images per request.\n * Imagen 3 and the Imagen 4 family all support up to 4 images per request\n * via the Gemini API (the rumored 8-image tier is Vertex-only and isn't\n * reachable through @google/genai today). Unknown models fall through to\n * the shared cap defined below.\n *\n * @see https://ai.google.dev/gemini-api/docs/imagen\n */\nconst IMAGEN_MAX_IMAGES_BY_MODEL: Record<string, number> = {\n 'imagen-3.0-generate-002': 4,\n 'imagen-4.0-generate-001': 4,\n 'imagen-4.0-ultra-generate-001': 4,\n 'imagen-4.0-fast-generate-001': 4,\n}\n\nconst DEFAULT_IMAGEN_MAX_IMAGES = 4\n\n/**\n * Validates the number of images requested against the model's known cap.\n * Uses a per-model table where available and falls back to the shared\n * default otherwise — no more \"some support up to 8\" comments that don't\n * match the error message.\n */\nexport function validateNumberOfImages(\n model: string,\n numberOfImages: number | undefined,\n): void {\n if (numberOfImages === undefined) return\n\n const maxImages =\n IMAGEN_MAX_IMAGES_BY_MODEL[model] ?? DEFAULT_IMAGEN_MAX_IMAGES\n if (numberOfImages < 1 || numberOfImages > maxImages) {\n throw new Error(\n `Invalid numberOfImages \"${numberOfImages}\" for model \"${model}\". ` +\n `Must be between 1 and ${maxImages}.`,\n )\n }\n}\n\n/**\n * Validates the prompt is not empty\n */\nexport function validatePrompt(options: {\n prompt: string\n model: string\n}): void {\n const { prompt, model } = options\n if (!prompt || prompt.trim().length === 0) {\n throw new Error(`Prompt cannot be empty for model \"${model}\".`)\n }\n}\n\n/**\n * Parses a Gemini native image size string into its components.\n * Format: \"aspectRatio_resolution\" e.g. \"16:9_4K\" → { aspectRatio: \"16:9\", resolution: \"4K\" }\n */\nexport function parseNativeImageSize(\n size: string,\n): { aspectRatio: string; resolution: string } | undefined {\n const match = size.match(/^(\\d+:\\d+)_(.+)$/)\n if (!match) return undefined\n return { aspectRatio: match[1]!, resolution: match[2]! }\n}\n"],"names":[],"mappings":"AAqMO,MAAM,8BAAiE;AAAA;AAAA,EAE5E,aAAa;AAAA,EACb,WAAW;AAAA;AAAA,EAEX,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA;AAAA,EAEb,YAAY;AAAA,EACZ,aAAa;AAAA;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AACf;AAMO,SAAS,kBACd,MAC+B;AAC/B,MAAI,CAAC,KAAM,QAAO;AAClB,SAAO,4BAA4B,IAAI;AACzC;AAMO,SAAS,kBACd,OACA,MACM;AACN,MAAI,CAAC,KAAM;AAEX,QAAM,cAAc,kBAAkB,IAAI;AAC1C,MAAI,CAAC,aAAa;AAChB,UAAM,aAAa,OAAO,KAAK,2BAA2B;AAC1D,UAAM,IAAI;AAAA,MACR,iBAAiB,IAAI,gBAAgB,KAAK,+EACoC,WAAW,KAAK,IAAI,CAAC;AAAA,IAAA;AAAA,EAGvG;AACF;AAWA,MAAM,6BAAqD;AAAA,EACzD,2BAA2B;AAAA,EAC3B,2BAA2B;AAAA,EAC3B,iCAAiC;AAAA,EACjC,gCAAgC;AAClC;AAEA,MAAM,4BAA4B;AAQ3B,SAAS,uBACd,OACA,gBACM;AACN,MAAI,mBAAmB,OAAW;AAElC,QAAM,YACJ,2BAA2B,KAAK,KAAK;AACvC,MAAI,iBAAiB,KAAK,iBAAiB,WAAW;AACpD,UAAM,IAAI;AAAA,MACR,2BAA2B,cAAc,gBAAgB,KAAK,4BACnC,SAAS;AAAA,IAAA;AAAA,EAExC;AACF;AAKO,SAAS,eAAe,SAGtB;AACP,QAAM,EAAE,QAAQ,MAAA,IAAU;AAC1B,MAAI,CAAC,UAAU,OAAO,KAAA,EAAO,WAAW,GAAG;AACzC,UAAM,IAAI,MAAM,qCAAqC,KAAK,IAAI;AAAA,EAChE;AACF;AAMO,SAAS,qBACd,MACyD;AACzD,QAAM,QAAQ,KAAK,MAAM,kBAAkB;AAC3C,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO,EAAE,aAAa,MAAM,CAAC,GAAI,YAAY,MAAM,CAAC,EAAA;AACtD;"}
1
+ {"version":3,"file":"image-provider-options.js","sources":["../../../src/image/image-provider-options.ts"],"sourcesContent":["import type { GeminiImageModels } from '../model-meta'\nimport type {\n ImagePromptLanguage,\n PersonGeneration,\n SafetyFilterLevel,\n} from '@google/genai'\n\n// Re-export SDK types so users can use them directly\nexport type { ImagePromptLanguage, PersonGeneration, SafetyFilterLevel }\n\n/**\n * Gemini Imagen aspect ratio options\n * Controls the aspect ratio of generated images\n */\nexport type GeminiAspectRatio =\n | '1:1'\n | '3:4'\n | '4:3'\n | '9:16'\n | '16:9'\n | '9:21'\n | '21:9'\n\n/**\n * Provider options for Gemini image generation\n * These options match the @google/genai GenerateImagesConfig interface\n * and can be spread directly into the API request.\n */\nexport interface GeminiImageProviderOptions {\n /**\n * The aspect ratio of generated images\n * @default '1:1'\n */\n aspectRatio?: GeminiAspectRatio\n\n /**\n * Controls whether people can appear in generated images\n * Use PersonGeneration enum values: DONT_ALLOW, ALLOW_ADULT, ALLOW_ALL\n * @default 'ALLOW_ADULT'\n */\n personGeneration?: PersonGeneration\n\n /**\n * Safety filter level for content filtering\n * Use SafetyFilterLevel enum values\n */\n safetyFilterLevel?: SafetyFilterLevel\n\n /**\n * Optional seed for reproducible image generation\n * When the same seed is used with the same prompt and settings,\n * you should get similar (though not identical) results\n */\n seed?: number\n\n /**\n * Whether to add a SynthID watermark to generated images\n * SynthID helps identify AI-generated content\n * @default true\n */\n addWatermark?: boolean\n\n /**\n * Language of the prompt\n * Use ImagePromptLanguage enum values\n */\n language?: ImagePromptLanguage\n\n /**\n * Negative prompt - what to avoid in the generated image\n * Not all models support negative prompts\n */\n negativePrompt?: string\n\n /**\n * Output MIME type for the generated image\n * @default 'image/png'\n */\n outputMimeType?: 'image/png' | 'image/jpeg' | 'image/webp'\n\n /**\n * Compression quality for JPEG outputs (0-100)\n * Higher values mean better quality but larger file sizes\n * @default 75\n */\n outputCompressionQuality?: number\n\n /**\n * Controls how much the model adheres to the text prompt\n * Large values increase output and prompt alignment,\n * but may compromise image quality\n */\n guidanceScale?: number\n\n /**\n * Whether to use the prompt rewriting logic\n */\n enhancePrompt?: boolean\n\n /**\n * Whether to report the safety scores of each generated image\n * and the positive prompt in the response\n */\n includeSafetyAttributes?: boolean\n\n /**\n * Whether to include the Responsible AI filter reason\n * if the image is filtered out of the response\n */\n includeRaiReason?: boolean\n\n /**\n * Cloud Storage URI used to store the generated images\n */\n outputGcsUri?: string\n\n /**\n * User specified labels to track billing usage\n */\n labels?: Record<string, string>\n}\n\n/**\n * Model-specific provider options mapping\n * Currently all Imagen models use the same options structure\n */\nexport type GeminiImageModelProviderOptionsByName = {\n [K in GeminiImageModels]: GeminiImageProviderOptions\n}\n\n/**\n * Supported size strings for Gemini Imagen models\n * These map to aspect ratios internally\n */\nexport type GeminiImageSize =\n | '1024x1024'\n | '512x512'\n | '1024x768'\n | '1536x1024'\n | '1792x1024'\n | '1920x1080'\n | '768x1024'\n | '1024x1536'\n | '1024x1792'\n | '1080x1920'\n\n/**\n * Aspect ratios supported by Gemini native image models (via generateContent API).\n * Matches the SDK's ImageConfig.aspectRatio values.\n */\nexport type GeminiNativeImageAspectRatio =\n | '1:1'\n | '2:3'\n | '3:2'\n | '3:4'\n | '4:3'\n | '9:16'\n | '16:9'\n | '21:9'\n\n/**\n * Resolution tiers for Gemini native image models.\n * Matches the SDK's ImageConfig.imageSize values.\n */\nexport type GeminiNativeImageResolution = '1K' | '2K' | '4K'\n\n/**\n * Template literal size type for Gemini native image models: \"16:9_4K\", \"1:1_2K\", etc.\n */\nexport type GeminiNativeImageSize =\n `${GeminiNativeImageAspectRatio}_${GeminiNativeImageResolution}`\n\n/**\n * Gemini native image models that use the generateContent API path.\n * These models support template literal sizes (aspectRatio_resolution).\n */\nexport type GeminiNativeImageModels =\n | 'gemini-3.1-flash-image-preview'\n | 'gemini-3-pro-image-preview'\n | 'gemini-2.5-flash-image'\n | 'gemini-2.0-flash-preview-image-generation'\n\n/**\n * Model-specific size options mapping.\n * Gemini native image models use template literal sizes, Imagen models use pixel sizes.\n */\nexport type GeminiImageModelSizeByName = {\n [K in GeminiNativeImageModels]: GeminiNativeImageSize\n} & {\n [K in Exclude<GeminiImageModels, GeminiNativeImageModels>]: GeminiImageSize\n}\n\n/**\n * Valid sizes for Gemini Imagen models\n * Gemini uses aspect ratios, but we map common WIDTHxHEIGHT formats to aspect ratios\n * These are approximate mappings based on common image dimensions\n */\nexport const GEMINI_SIZE_TO_ASPECT_RATIO: Record<string, GeminiAspectRatio> = {\n // Square\n '1024x1024': '1:1',\n '512x512': '1:1',\n // Landscape\n '1024x768': '4:3',\n '1536x1024': '4:3',\n '1792x1024': '16:9',\n '1920x1080': '16:9',\n // Portrait\n '768x1024': '3:4',\n '1024x1536': '3:4', // Inverted\n '1024x1792': '9:16',\n '1080x1920': '9:16',\n}\n\n/**\n * Maps a WIDTHxHEIGHT size string to a Gemini aspect ratio\n * Returns undefined if the size cannot be mapped\n */\nexport function sizeToAspectRatio(\n size: string | undefined,\n): GeminiAspectRatio | undefined {\n if (!size) return undefined\n return GEMINI_SIZE_TO_ASPECT_RATIO[size]\n}\n\n/**\n * Validates that the provided size can be mapped to an aspect ratio\n * Throws an error if the size is invalid\n */\nexport function validateImageSize(\n model: string,\n size: string | undefined,\n): void {\n if (!size) return\n\n const aspectRatio = sizeToAspectRatio(size)\n if (!aspectRatio) {\n const validSizes = Object.keys(GEMINI_SIZE_TO_ASPECT_RATIO)\n throw new Error(\n `Invalid size \"${size}\" for model \"${model}\". ` +\n `Gemini Imagen uses aspect ratios. Valid sizes that map to aspect ratios: ${validSizes.join(', ')}. ` +\n `Alternatively, use providerOptions.aspectRatio directly with values: 1:1, 3:4, 4:3, 9:16, 16:9, 9:21, 21:9`,\n )\n }\n}\n\n/**\n * Per-model caps on images per request.\n * Imagen 3 and the Imagen 4 family all support up to 4 images per request\n * via the Gemini API (the rumored 8-image tier is Vertex-only and isn't\n * reachable through @google/genai today). Unknown models fall through to\n * the shared cap defined below.\n *\n * @see https://ai.google.dev/gemini-api/docs/imagen\n */\nconst IMAGEN_MAX_IMAGES_BY_MODEL: Record<string, number> = {\n 'imagen-3.0-generate-002': 4,\n 'imagen-4.0-generate-001': 4,\n 'imagen-4.0-ultra-generate-001': 4,\n 'imagen-4.0-fast-generate-001': 4,\n}\n\nconst DEFAULT_IMAGEN_MAX_IMAGES = 4\n\n/**\n * Validates the number of images requested against the model's known cap.\n * Uses a per-model table where available and falls back to the shared\n * default otherwise — no more \"some support up to 8\" comments that don't\n * match the error message.\n */\nexport function validateNumberOfImages(\n model: string,\n numberOfImages: number | undefined,\n): void {\n if (numberOfImages === undefined) return\n\n const maxImages =\n IMAGEN_MAX_IMAGES_BY_MODEL[model] ?? DEFAULT_IMAGEN_MAX_IMAGES\n if (numberOfImages < 1 || numberOfImages > maxImages) {\n throw new Error(\n `Invalid numberOfImages \"${numberOfImages}\" for model \"${model}\". ` +\n `Must be between 1 and ${maxImages}.`,\n )\n }\n}\n\n/**\n * Validates the prompt is not empty\n */\nexport function validatePrompt(options: {\n prompt: string\n model: string\n}): void {\n const { prompt, model } = options\n if (!prompt || prompt.trim().length === 0) {\n throw new Error(`Prompt cannot be empty for model \"${model}\".`)\n }\n}\n\n/**\n * Parses a Gemini native image size string into its components.\n * Format: \"aspectRatio_resolution\" e.g. \"16:9_4K\" → { aspectRatio: \"16:9\", resolution: \"4K\" }\n */\nexport function parseNativeImageSize(\n size: string,\n): { aspectRatio: string; resolution: string } | undefined {\n const match = size.match(/^(\\d+:\\d+)_(.+)$/)\n const [, aspectRatio, resolution] = match ?? []\n if (aspectRatio === undefined || resolution === undefined) return undefined\n return { aspectRatio, resolution }\n}\n"],"names":[],"mappings":"AAqMO,MAAM,8BAAiE;AAAA;AAAA,EAE5E,aAAa;AAAA,EACb,WAAW;AAAA;AAAA,EAEX,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA;AAAA,EAEb,YAAY;AAAA,EACZ,aAAa;AAAA;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AACf;AAMO,SAAS,kBACd,MAC+B;AAC/B,MAAI,CAAC,KAAM,QAAO;AAClB,SAAO,4BAA4B,IAAI;AACzC;AAMO,SAAS,kBACd,OACA,MACM;AACN,MAAI,CAAC,KAAM;AAEX,QAAM,cAAc,kBAAkB,IAAI;AAC1C,MAAI,CAAC,aAAa;AAChB,UAAM,aAAa,OAAO,KAAK,2BAA2B;AAC1D,UAAM,IAAI;AAAA,MACR,iBAAiB,IAAI,gBAAgB,KAAK,+EACoC,WAAW,KAAK,IAAI,CAAC;AAAA,IAAA;AAAA,EAGvG;AACF;AAWA,MAAM,6BAAqD;AAAA,EACzD,2BAA2B;AAAA,EAC3B,2BAA2B;AAAA,EAC3B,iCAAiC;AAAA,EACjC,gCAAgC;AAClC;AAEA,MAAM,4BAA4B;AAQ3B,SAAS,uBACd,OACA,gBACM;AACN,MAAI,mBAAmB,OAAW;AAElC,QAAM,YACJ,2BAA2B,KAAK,KAAK;AACvC,MAAI,iBAAiB,KAAK,iBAAiB,WAAW;AACpD,UAAM,IAAI;AAAA,MACR,2BAA2B,cAAc,gBAAgB,KAAK,4BACnC,SAAS;AAAA,IAAA;AAAA,EAExC;AACF;AAKO,SAAS,eAAe,SAGtB;AACP,QAAM,EAAE,QAAQ,MAAA,IAAU;AAC1B,MAAI,CAAC,UAAU,OAAO,KAAA,EAAO,WAAW,GAAG;AACzC,UAAM,IAAI,MAAM,qCAAqC,KAAK,IAAI;AAAA,EAChE;AACF;AAMO,SAAS,qBACd,MACyD;AACzD,QAAM,QAAQ,KAAK,MAAM,kBAAkB;AAC3C,QAAM,GAAG,aAAa,UAAU,IAAI,SAAS,CAAA;AAC7C,MAAI,gBAAgB,UAAa,eAAe,OAAW,QAAO;AAClE,SAAO,EAAE,aAAa,WAAA;AACxB;"}
@@ -333,7 +333,27 @@ const VEO_2 = {
333
333
  GeminiGenerationConfigOptions &
334
334
  GeminiCachedContentOptions
335
335
  > */
336
- export declare const GEMINI_MODELS: readonly ["gemini-3.1-pro-preview", "gemini-3-pro-preview", "gemini-3-flash-preview", "gemini-3.1-flash-lite-preview", "gemini-2.5-pro", "gemini-2.5-flash", "gemini-2.5-flash-preview-09-2025", "gemini-2.5-flash-lite", "gemini-2.5-flash-lite-preview-09-2025", "gemini-2.0-flash", "gemini-2.0-flash-lite"];
336
+ declare const GEMINI_3_5_FLASH: {
337
+ readonly name: "gemini-3.5-flash";
338
+ readonly max_input_tokens: 1048576;
339
+ readonly max_output_tokens: 65536;
340
+ readonly supports: {
341
+ readonly input: ["text", "image", "video", "document", "audio"];
342
+ readonly output: ["text"];
343
+ readonly capabilities: ["batch_api", "caching", "function_calling", "structured_output", "thinking"];
344
+ readonly tools: ["code_execution", "file_search", "google_search", "url_context"];
345
+ };
346
+ readonly pricing: {
347
+ readonly input: {
348
+ readonly normal: 1.5;
349
+ readonly cached: 0.15;
350
+ };
351
+ readonly output: {
352
+ readonly normal: 9;
353
+ };
354
+ };
355
+ };
356
+ export declare const GEMINI_MODELS: readonly ["gemini-3.1-pro-preview", "gemini-3-pro-preview", "gemini-3-flash-preview", "gemini-3.1-flash-lite-preview", "gemini-2.5-pro", "gemini-2.5-flash", "gemini-2.5-flash-preview-09-2025", "gemini-2.5-flash-lite", "gemini-2.5-flash-lite-preview-09-2025", "gemini-2.0-flash", "gemini-2.0-flash-lite", "gemini-3.5-flash"];
337
357
  export type GeminiModels = (typeof GEMINI_MODELS)[number];
338
358
  export type GeminiImageModels = (typeof GEMINI_IMAGE_MODELS)[number];
339
359
  export declare const GEMINI_IMAGE_MODELS: readonly ["gemini-3.1-flash-image-preview", "gemini-3-pro-image-preview", "gemini-2.5-flash-image", "gemini-2.0-flash-preview-image-generation", "imagen-3.0-generate-002", "imagen-4.0-generate-001", "imagen-4.0-fast-generate-001", "imagen-4.0-ultra-generate-001"];
@@ -365,6 +385,7 @@ export type GeminiChatModelProviderOptionsByName = {
365
385
  [GEMINI_2_5_FLASH_LITE_PREVIEW.name]: GeminiToolConfigOptions & GeminiSafetyOptions & GeminiCommonConfigOptions & GeminiCachedContentOptions & GeminiStructuredOutputOptions & GeminiThinkingOptions;
366
386
  [GEMINI_2_FLASH.name]: GeminiToolConfigOptions & GeminiSafetyOptions & GeminiCommonConfigOptions & GeminiCachedContentOptions & GeminiStructuredOutputOptions;
367
387
  [GEMINI_2_FLASH_LITE.name]: GeminiToolConfigOptions & GeminiSafetyOptions & GeminiCommonConfigOptions & GeminiCachedContentOptions & GeminiStructuredOutputOptions;
388
+ [GEMINI_3_5_FLASH.name]: GeminiToolConfigOptions & GeminiSafetyOptions & GeminiCommonConfigOptions & GeminiCachedContentOptions & GeminiStructuredOutputOptions & GeminiThinkingOptions;
368
389
  };
369
390
  /**
370
391
  * Type-only map from chat model name to its supported tool capabilities.
@@ -408,5 +429,6 @@ export type GeminiModelInputModalitiesByName = {
408
429
  [GEMINI_2_5_FLASH_PREVIEW.name]: typeof GEMINI_2_5_FLASH_PREVIEW.supports.input;
409
430
  [GEMINI_2_FLASH.name]: typeof GEMINI_2_FLASH.supports.input;
410
431
  [GEMINI_2_FLASH_LITE.name]: typeof GEMINI_2_FLASH_LITE.supports.input;
432
+ [GEMINI_3_5_FLASH.name]: typeof GEMINI_3_5_FLASH.supports.input;
411
433
  };
412
434
  export {};
@@ -70,6 +70,9 @@ const IMAGEN_4_GENERATE_FAST = {
70
70
  const IMAGEN_3 = {
71
71
  name: "imagen-3.0-generate-002"
72
72
  };
73
+ const GEMINI_3_5_FLASH = {
74
+ name: "gemini-3.5-flash"
75
+ };
73
76
  const GEMINI_MODELS = [
74
77
  GEMINI_3_1_PRO.name,
75
78
  GEMINI_3_PRO.name,
@@ -81,7 +84,8 @@ const GEMINI_MODELS = [
81
84
  GEMINI_2_5_FLASH_LITE.name,
82
85
  GEMINI_2_5_FLASH_LITE_PREVIEW.name,
83
86
  GEMINI_2_FLASH.name,
84
- GEMINI_2_FLASH_LITE.name
87
+ GEMINI_2_FLASH_LITE.name,
88
+ GEMINI_3_5_FLASH.name
85
89
  ];
86
90
  const GEMINI_IMAGE_MODELS = [
87
91
  GEMINI_3_1_FLASH_IMAGE.name,
@@ -1 +1 @@
1
- {"version":3,"file":"model-meta.js","sources":["../../src/model-meta.ts"],"sourcesContent":["import type {\n GeminiCachedContentOptions,\n GeminiCommonConfigOptions,\n GeminiSafetyOptions,\n GeminiStructuredOutputOptions,\n GeminiThinkingOptions,\n GeminiToolConfigOptions,\n} from './text/text-provider-options'\n\ninterface ModelMeta<TProviderOptions = unknown> {\n name: string\n supports: {\n input: Array<'text' | 'image' | 'audio' | 'video' | 'document'>\n output: Array<'text' | 'image' | 'audio' | 'video'>\n capabilities?: Array<\n | 'audio_generation'\n | 'batch_api'\n | 'caching'\n | 'function_calling'\n | 'live_api'\n | 'structured_output'\n | 'thinking'\n >\n tools?: Array<\n | 'code_execution'\n | 'file_search'\n | 'google_search'\n | 'google_search_retrieval'\n | 'google_maps'\n | 'url_context'\n | 'computer_use'\n >\n }\n max_input_tokens?: number\n max_output_tokens?: number\n knowledge_cutoff?: string\n pricing?: {\n input: {\n normal: number\n cached?: number\n }\n output: {\n normal: number\n }\n }\n /**\n * Type-level description of which provider options this model supports.\n */\n providerOptions?: TProviderOptions\n}\n\nconst GEMINI_3_1_PRO = {\n name: 'gemini-3.1-pro-preview',\n max_input_tokens: 1_048_576,\n max_output_tokens: 65_536,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'image', 'audio', 'video', 'document'],\n output: ['text'],\n capabilities: [\n 'batch_api',\n 'caching',\n 'function_calling',\n 'structured_output',\n 'thinking',\n ],\n tools: ['code_execution', 'file_search', 'google_search', 'url_context'],\n },\n pricing: {\n input: {\n normal: 2.5,\n },\n output: {\n normal: 15,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n>\n\nconst GEMINI_3_PRO = {\n name: 'gemini-3-pro-preview',\n max_input_tokens: 1_048_576,\n max_output_tokens: 65_536,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'image', 'audio', 'video', 'document'],\n output: ['text'],\n capabilities: [\n 'batch_api',\n 'caching',\n 'function_calling',\n 'structured_output',\n 'thinking',\n ],\n tools: ['code_execution', 'file_search', 'google_search', 'url_context'],\n },\n pricing: {\n input: {\n normal: 2.5,\n },\n output: {\n normal: 15,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n>\n\nconst GEMINI_3_FLASH = {\n name: 'gemini-3-flash-preview',\n max_input_tokens: 1_048_576,\n max_output_tokens: 65_536,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'image', 'audio', 'video', 'document'],\n output: ['text'],\n capabilities: [\n 'batch_api',\n 'caching',\n 'function_calling',\n 'structured_output',\n 'thinking',\n ],\n tools: ['code_execution', 'file_search', 'google_search', 'url_context'],\n },\n pricing: {\n input: {\n normal: 0.5,\n },\n output: {\n normal: 3,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n>\n\nconst GEMINI_3_PRO_IMAGE = {\n name: 'gemini-3-pro-image-preview',\n max_input_tokens: 65_536,\n max_output_tokens: 32_768,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'image'],\n output: ['text', 'image'],\n capabilities: ['batch_api', 'structured_output', 'thinking'],\n tools: ['google_search'],\n },\n pricing: {\n input: {\n normal: 2,\n },\n output: {\n normal: 0.134,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n>\n\nconst GEMINI_3_1_FLASH_IMAGE = {\n name: 'gemini-3.1-flash-image-preview',\n max_input_tokens: 65_536,\n max_output_tokens: 65_536,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'image'],\n output: ['text', 'image'],\n capabilities: ['batch_api', 'structured_output', 'thinking'],\n tools: ['google_search'],\n },\n pricing: {\n input: {\n normal: 0.25,\n },\n output: {\n normal: 1.5,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n>\n\nconst GEMINI_3_1_FLASH_LITE = {\n name: 'gemini-3.1-flash-lite-preview',\n max_input_tokens: 1_048_576,\n max_output_tokens: 65_536,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'image', 'audio', 'video', 'document'],\n output: ['text'],\n capabilities: [\n 'batch_api',\n 'caching',\n 'function_calling',\n 'structured_output',\n 'thinking',\n ],\n tools: ['code_execution', 'file_search', 'google_search', 'url_context'],\n },\n pricing: {\n input: {\n normal: 0.25,\n },\n output: {\n normal: 1.5,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n>\n\nconst GEMINI_2_5_PRO = {\n name: 'gemini-2.5-pro',\n max_input_tokens: 1_048_576,\n max_output_tokens: 65_536,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'image', 'audio', 'video', 'document'],\n output: ['text'],\n capabilities: [\n 'batch_api',\n 'caching',\n 'function_calling',\n 'structured_output',\n 'thinking',\n ],\n tools: [\n 'code_execution',\n 'file_search',\n 'google_maps',\n 'google_search',\n 'url_context',\n ],\n },\n pricing: {\n input: {\n normal: 2.5,\n },\n output: {\n normal: 15,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n>\n\nconst GEMINI_2_5_PRO_TTS = {\n name: 'gemini-2.5-pro-preview-tts',\n max_input_tokens: 8_192,\n max_output_tokens: 16_384,\n knowledge_cutoff: '2025-05-01',\n supports: {\n input: ['text'],\n output: ['audio'],\n capabilities: ['audio_generation'],\n },\n pricing: {\n input: {\n normal: 2.5,\n },\n output: {\n normal: 15,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions\n>\n\nconst GEMINI_2_5_FLASH = {\n name: 'gemini-2.5-flash',\n max_input_tokens: 1_048_576,\n max_output_tokens: 65_536,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'image', 'audio', 'video'],\n output: ['text'],\n capabilities: [\n 'batch_api',\n 'caching',\n 'function_calling',\n 'structured_output',\n 'thinking',\n ],\n tools: [\n 'code_execution',\n 'file_search',\n 'google_maps',\n 'google_search',\n 'url_context',\n ],\n },\n pricing: {\n input: {\n normal: 1,\n },\n output: {\n normal: 2.5,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n>\n\nconst GEMINI_2_5_FLASH_PREVIEW = {\n name: 'gemini-2.5-flash-preview-09-2025',\n max_input_tokens: 1_048_576,\n max_output_tokens: 65_536,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'image', 'audio', 'video'],\n output: ['text'],\n capabilities: [\n 'batch_api',\n 'caching',\n 'function_calling',\n 'structured_output',\n 'thinking',\n ],\n tools: ['code_execution', 'file_search', 'google_search', 'url_context'],\n },\n pricing: {\n input: {\n normal: 1,\n },\n output: {\n normal: 2.5,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n>\n\nconst GEMINI_2_5_FLASH_IMAGE = {\n name: 'gemini-2.5-flash-image',\n max_input_tokens: 1_048_576,\n max_output_tokens: 65_536,\n knowledge_cutoff: '2025-06-01',\n supports: {\n input: ['text', 'image'],\n output: ['text', 'image'],\n capabilities: ['batch_api', 'caching', 'structured_output'],\n tools: ['file_search'],\n },\n pricing: {\n input: {\n normal: 0.3,\n },\n output: {\n normal: 0.4,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions\n>\n/**\nconst GEMINI_2_5_FLASH_LIVE = {\n name: 'gemini-2.5-flash-native-audio-preview-09-2025',\n max_input_tokens: 141_072,\n max_output_tokens: 8_192,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'audio', 'video'],\n output: ['text', 'audio'],\n capabilities: [\n 'audio_generation',\n 'file_search',\n 'function_calling',\n 'live_api',\n 'search_grounding',\n 'thinking',\n ],\n },\n pricing: {\n // todo find this info\n input: {\n normal: 0,\n },\n output: {\n normal: 0,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiGenerationConfigOptions &\n GeminiCachedContentOptions &\n GeminiThinkingOptions\n>\n*/\nconst GEMINI_2_5_FLASH_TTS = {\n name: 'gemini-2.5-flash-preview-tts',\n max_input_tokens: 8_192,\n max_output_tokens: 16_384,\n knowledge_cutoff: '2025-05-01',\n supports: {\n input: ['text'],\n output: ['audio'],\n capabilities: ['audio_generation', 'batch_api'],\n },\n pricing: {\n input: {\n normal: 1,\n },\n output: {\n normal: 2.5,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions\n>\n\n/**\n * Gemini 3.1 Flash TTS Preview - latest expressive TTS model with\n * 200+ audio tags, 70+ languages, and multi-speaker dialogue support.\n * @see https://ai.google.dev/gemini-api/docs/models/gemini-3.1-flash-tts-preview\n */\nconst GEMINI_3_1_FLASH_TTS = {\n name: 'gemini-3.1-flash-tts-preview',\n max_input_tokens: 32_768,\n max_output_tokens: 16_384,\n knowledge_cutoff: '2025-05-01',\n supports: {\n input: ['text'],\n output: ['audio'],\n capabilities: ['audio_generation', 'batch_api'],\n },\n pricing: {\n input: {\n normal: 0.5,\n },\n output: {\n normal: 10,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions\n>\n\n/**\n * Lyria 3 Pro Preview — Google's flagship music generation model.\n * Generates full-length songs with multiple verses, choruses, and bridges.\n * Outputs MP3 or WAV at 48 kHz stereo.\n * @see https://ai.google.dev/gemini-api/docs/models/lyria-3-pro-preview\n */\nconst LYRIA_3_PRO = {\n name: 'lyria-3-pro-preview',\n max_input_tokens: 131_072,\n supports: {\n input: ['text', 'image'],\n output: ['audio'],\n capabilities: ['audio_generation'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0,\n },\n },\n} as const satisfies ModelMeta\n\n/**\n * Lyria 3 Clip Preview — 30-second music clips in MP3 format.\n * @see https://ai.google.dev/gemini-api/docs/music-generation\n */\nconst LYRIA_3_CLIP = {\n name: 'lyria-3-clip-preview',\n max_input_tokens: 131_072,\n supports: {\n input: ['text', 'image'],\n output: ['audio'],\n capabilities: ['audio_generation'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0,\n },\n },\n} as const satisfies ModelMeta\n\nconst GEMINI_2_5_FLASH_LITE = {\n name: 'gemini-2.5-flash-lite',\n max_input_tokens: 1_048_576,\n max_output_tokens: 65_536,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'image', 'audio', 'video', 'document'],\n output: ['text'],\n capabilities: [\n 'batch_api',\n 'caching',\n 'function_calling',\n 'structured_output',\n 'thinking',\n ],\n tools: ['code_execution', 'google_maps', 'google_search', 'url_context'],\n },\n pricing: {\n input: {\n normal: 0.1,\n },\n output: {\n normal: 0.4,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n>\n\nconst GEMINI_2_5_FLASH_LITE_PREVIEW = {\n name: 'gemini-2.5-flash-lite-preview-09-2025',\n max_input_tokens: 1_048_576,\n max_output_tokens: 65_536,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'image', 'audio', 'video', 'document'],\n output: ['text'],\n capabilities: [\n 'batch_api',\n 'caching',\n 'function_calling',\n 'structured_output',\n 'thinking',\n ],\n tools: ['code_execution', 'google_search', 'url_context'],\n },\n pricing: {\n input: {\n normal: 0.1,\n },\n output: {\n normal: 0.4,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n>\n\nconst GEMINI_2_FLASH = {\n name: 'gemini-2.0-flash',\n max_input_tokens: 1_048_576,\n max_output_tokens: 8_192,\n knowledge_cutoff: '2024-08-01',\n supports: {\n input: ['text', 'image', 'audio', 'video'],\n output: ['text'],\n capabilities: [\n 'batch_api',\n 'caching',\n 'function_calling',\n 'live_api',\n 'structured_output',\n ],\n tools: ['code_execution', 'google_maps', 'google_search'],\n },\n pricing: {\n input: {\n normal: 0.1,\n },\n output: {\n normal: 0.4,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions\n>\n\nconst GEMINI_2_FLASH_IMAGE = {\n name: 'gemini-2.0-flash-preview-image-generation',\n max_input_tokens: 32_768,\n max_output_tokens: 8_192,\n knowledge_cutoff: '2024-08-01',\n supports: {\n input: ['text', 'image', 'audio', 'video'],\n output: ['text', 'image'],\n capabilities: ['batch_api', 'caching', 'structured_output'],\n tools: [],\n },\n pricing: {\n input: {\n normal: 0.1,\n },\n output: {\n normal: 0.039,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions\n>\n/* \nconst GEMINI_2_FLASH_LIVE = {\n name: 'gemini-2.0-flash-live-001',\n max_input_tokens: 1_048_576,\n max_output_tokens: 8_192,\n knowledge_cutoff: '2024-08-01',\n supports: {\n input: ['text', 'audio', 'video'],\n output: ['text', 'audio'],\n capabilities: [\n 'audio_generation',\n 'code_execution',\n 'function_calling',\n 'live_api',\n 'search_grounding',\n 'structured_output',\n 'url_context',\n ],\n },\n pricing: {\n // todo find this info\n input: {\n normal: 0,\n },\n output: {\n normal: 0,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiGenerationConfigOptions &\n GeminiCachedContentOptions\n> */\n\nconst GEMINI_2_FLASH_LITE = {\n name: 'gemini-2.0-flash-lite',\n max_input_tokens: 1_048_576,\n max_output_tokens: 8_192,\n knowledge_cutoff: '2024-08-01',\n supports: {\n input: ['text', 'audio', 'video', 'image'],\n output: ['text'],\n capabilities: [\n 'batch_api',\n 'caching',\n 'function_calling',\n 'structured_output',\n ],\n tools: [],\n },\n pricing: {\n input: {\n normal: 0.075,\n },\n output: {\n normal: 0.3,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions\n>\n\nconst IMAGEN_4_GENERATE = {\n name: 'imagen-4.0-generate-001',\n max_input_tokens: 480,\n max_output_tokens: 4,\n supports: {\n input: ['text'],\n output: ['image'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0.4,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions\n>\n\nconst IMAGEN_4_GENERATE_ULTRA = {\n name: 'imagen-4.0-ultra-generate-001',\n max_input_tokens: 480,\n max_output_tokens: 4,\n supports: {\n input: ['text'],\n output: ['image'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0.6,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions\n>\n\nconst IMAGEN_4_GENERATE_FAST = {\n name: 'imagen-4.0-fast-generate-001',\n max_input_tokens: 480,\n max_output_tokens: 4,\n supports: {\n input: ['text'],\n output: ['image'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0.2,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions\n>\n\nconst IMAGEN_3 = {\n name: 'imagen-3.0-generate-002',\n max_output_tokens: 4,\n supports: {\n input: ['text'],\n output: ['image'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0.03,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions\n>\n/** \nconst VEO_3_1_PREVIEW = {\n name: 'veo-3.1-generate-preview',\n max_input_tokens: 1024,\n max_output_tokens: 1,\n supports: {\n input: ['text', 'image'],\n output: ['video', 'audio'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0.4,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiGenerationConfigOptions &\n GeminiCachedContentOptions\n>\n\nconst VEO_3_1_FAST_PREVIEW = {\n name: 'veo-3.1-fast-generate-preview',\n max_input_tokens: 1024,\n max_output_tokens: 1,\n supports: {\n input: ['text', 'image'],\n output: ['video', 'audio'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0.15,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiGenerationConfigOptions &\n GeminiCachedContentOptions\n>\n\nconst VEO_3 = {\n name: 'veo-3.0-generate-001',\n max_input_tokens: 1024,\n max_output_tokens: 1,\n supports: {\n input: ['text', 'image'],\n output: ['video', 'audio'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0.4,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiGenerationConfigOptions &\n GeminiCachedContentOptions\n>\n\nconst VEO_3_FAST = {\n name: 'veo-3.0-fast-generate-001',\n max_input_tokens: 1024,\n max_output_tokens: 1,\n supports: {\n input: ['text', 'image'],\n output: ['video', 'audio'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0.15,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiGenerationConfigOptions &\n GeminiCachedContentOptions\n>\n\nconst VEO_2 = {\n name: 'veo-2.0-generate-001',\n max_output_tokens: 2,\n supports: {\n input: ['text', 'image'],\n output: ['video'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0.35,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiGenerationConfigOptions &\n GeminiCachedContentOptions\n> */\n\n/* const GEMINI_MODEL_META = {\n [GEMINI_3_PRO.name]: GEMINI_3_PRO,\n [GEMINI_2_5_PRO.name]: GEMINI_2_5_PRO,\n [GEMINI_2_5_PRO_TTS.name]: GEMINI_2_5_PRO_TTS,\n [GEMINI_2_5_FLASH.name]: GEMINI_2_5_FLASH,\n [GEMINI_2_5_FLASH_PREVIEW.name]: GEMINI_2_5_FLASH_PREVIEW,\n [GEMINI_2_5_FLASH_IMAGE.name]: GEMINI_2_5_FLASH_IMAGE,\n [GEMINI_2_5_FLASH_LIVE.name]: GEMINI_2_5_FLASH_LIVE,\n [GEMINI_2_5_FLASH_TTS.name]: GEMINI_2_5_FLASH_TTS,\n [GEMINI_2_5_FLASH_LITE.name]: GEMINI_2_5_FLASH_LITE,\n [GEMINI_2_5_FLASH_LITE_PREVIEW.name]: GEMINI_2_5_FLASH_LITE_PREVIEW,\n [GEMINI_2_FLASH.name]: GEMINI_2_FLASH,\n [GEMINI_2_FLASH_IMAGE.name]: GEMINI_2_FLASH_IMAGE,\n [GEMINI_2_FLASH_LIVE.name]: GEMINI_2_FLASH_LIVE,\n [GEMINI_2_FLASH_LITE.name]: GEMINI_2_FLASH_LITE,\n [IMAGEN_4_GENERATE.name]: IMAGEN_4_GENERATE,\n [IMAGEN_4_GENERATE_ULTRA.name]: IMAGEN_4_GENERATE_ULTRA,\n [IMAGEN_4_GENERATE_FAST.name]: IMAGEN_4_GENERATE_FAST,\n [IMAGEN_3.name]: IMAGEN_3,\n [VEO_3_1_PREVIEW.name]: VEO_3_1_PREVIEW,\n [VEO_3_1_FAST_PREVIEW.name]: VEO_3_1_FAST_PREVIEW,\n [VEO_3.name]: VEO_3,\n [VEO_3_FAST.name]: VEO_3_FAST,\n [VEO_2.name]: VEO_2,\n} as const */\n\nexport const GEMINI_MODELS = [\n GEMINI_3_1_PRO.name,\n GEMINI_3_PRO.name,\n GEMINI_3_FLASH.name,\n GEMINI_3_1_FLASH_LITE.name,\n GEMINI_2_5_PRO.name,\n GEMINI_2_5_FLASH.name,\n GEMINI_2_5_FLASH_PREVIEW.name,\n GEMINI_2_5_FLASH_LITE.name,\n GEMINI_2_5_FLASH_LITE_PREVIEW.name,\n GEMINI_2_FLASH.name,\n GEMINI_2_FLASH_LITE.name,\n] as const\n\nexport type GeminiModels = (typeof GEMINI_MODELS)[number]\n\nexport type GeminiImageModels = (typeof GEMINI_IMAGE_MODELS)[number]\n\nexport const GEMINI_IMAGE_MODELS = [\n GEMINI_3_1_FLASH_IMAGE.name,\n GEMINI_3_PRO_IMAGE.name,\n GEMINI_2_5_FLASH_IMAGE.name,\n GEMINI_2_FLASH_IMAGE.name,\n IMAGEN_3.name,\n IMAGEN_4_GENERATE.name,\n IMAGEN_4_GENERATE_FAST.name,\n IMAGEN_4_GENERATE_ULTRA.name,\n] as const\n\n/**\n * Text-to-speech models\n * @experimental Gemini TTS is an experimental feature and may change.\n */\nexport const GEMINI_TTS_MODELS = [\n GEMINI_3_1_FLASH_TTS.name,\n GEMINI_2_5_FLASH_TTS.name,\n GEMINI_2_5_PRO_TTS.name,\n] as const\n\n/**\n * Audio generation models (Lyria music generation).\n * @experimental Lyria music generation is an experimental feature and may change.\n */\nexport const GEMINI_AUDIO_MODELS = [\n LYRIA_3_PRO.name,\n LYRIA_3_CLIP.name,\n] as const\n\n/**\n * Available voice names for Gemini TTS\n * @see https://ai.google.dev/gemini-api/docs/speech-generation\n */\nexport const GEMINI_TTS_VOICES = [\n 'Zephyr',\n 'Puck',\n 'Charon',\n 'Kore',\n 'Fenrir',\n 'Leda',\n 'Orus',\n 'Aoede',\n 'Callirrhoe',\n 'Autonoe',\n 'Enceladus',\n 'Iapetus',\n 'Umbriel',\n 'Algieba',\n 'Despina',\n 'Erinome',\n 'Algenib',\n 'Rasalgethi',\n 'Laomedeia',\n 'Achernar',\n 'Alnilam',\n 'Schedar',\n 'Gacrux',\n 'Pulcherrima',\n 'Achird',\n 'Zubenelgenubi',\n 'Vindemiatrix',\n 'Sadachbia',\n 'Sadaltager',\n 'Sulafat',\n] as const\n\nexport type GeminiTTSVoice = (typeof GEMINI_TTS_VOICES)[number]\n\n/* const GEMINI_AUDIO_MODELS = [\n GEMINI_2_5_PRO_TTS.name,\n GEMINI_2_5_FLASH_TTS.name,\n GEMINI_2_5_FLASH_LIVE.name,\n GEMINI_2_FLASH_LIVE.name,\n] as const\n\n const GEMINI_VIDEO_MODELS = [\n VEO_3_1_PREVIEW.name,\n VEO_3_1_FAST_PREVIEW.name,\n VEO_3.name,\n VEO_3_FAST.name,\n VEO_2.name,\n] as const */\n\n// Manual type map for per-model provider options\nexport type GeminiChatModelProviderOptionsByName = {\n // Models with thinking and structured output support\n [GEMINI_3_1_PRO.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n [GEMINI_3_PRO.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n [GEMINI_3_FLASH.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n [GEMINI_3_1_FLASH_LITE.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n [GEMINI_2_5_PRO.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n [GEMINI_2_5_FLASH.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n [GEMINI_2_5_FLASH_PREVIEW.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n [GEMINI_2_5_FLASH_LITE.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n [GEMINI_2_5_FLASH_LITE_PREVIEW.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n // Models with structured output but no thinking support\n [GEMINI_2_FLASH.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions\n [GEMINI_2_FLASH_LITE.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions\n}\n\n/**\n * Type-only map from chat model name to its supported tool capabilities.\n * Based on the 'supports.tools' arrays defined for each model.\n */\nexport type GeminiChatModelToolCapabilitiesByName = {\n [GEMINI_3_1_PRO.name]: typeof GEMINI_3_1_PRO.supports.tools\n [GEMINI_3_PRO.name]: typeof GEMINI_3_PRO.supports.tools\n [GEMINI_3_FLASH.name]: typeof GEMINI_3_FLASH.supports.tools\n [GEMINI_3_1_FLASH_LITE.name]: typeof GEMINI_3_1_FLASH_LITE.supports.tools\n [GEMINI_2_5_PRO.name]: typeof GEMINI_2_5_PRO.supports.tools\n [GEMINI_2_5_FLASH.name]: typeof GEMINI_2_5_FLASH.supports.tools\n [GEMINI_2_5_FLASH_PREVIEW.name]: typeof GEMINI_2_5_FLASH_PREVIEW.supports.tools\n [GEMINI_2_5_FLASH_LITE.name]: typeof GEMINI_2_5_FLASH_LITE.supports.tools\n [GEMINI_2_5_FLASH_LITE_PREVIEW.name]: typeof GEMINI_2_5_FLASH_LITE_PREVIEW.supports.tools\n [GEMINI_2_FLASH.name]: typeof GEMINI_2_FLASH.supports.tools\n [GEMINI_2_FLASH_LITE.name]: typeof GEMINI_2_FLASH_LITE.supports.tools\n}\n\n/**\n * Type-only map from chat model name to its supported input modalities.\n * Based on the 'supports.input' arrays defined for each model.\n * Note: 'document' in the model meta is mapped to 'document' modality.\n * Used by the core AI types to constrain ContentPart types based on the selected model.\n * Note: These must be inlined as readonly arrays (not typeof) because the model\n * constants are not exported and typeof references don't work in .d.ts files\n * when consumed by external packages.\n *\n * @see https://ai.google.dev/gemini-api/docs/vision\n * @see https://ai.google.dev/gemini-api/docs/audio\n * @see https://ai.google.dev/gemini-api/docs/document-processing\n */\nexport type GeminiModelInputModalitiesByName = {\n // Models with full multimodal support (text, image, audio, video, document)\n [GEMINI_3_1_PRO.name]: typeof GEMINI_3_1_PRO.supports.input\n [GEMINI_3_PRO.name]: typeof GEMINI_3_PRO.supports.input\n [GEMINI_3_FLASH.name]: typeof GEMINI_3_FLASH.supports.input\n [GEMINI_3_1_FLASH_LITE.name]: typeof GEMINI_3_1_FLASH_LITE.supports.input\n [GEMINI_2_5_PRO.name]: typeof GEMINI_2_5_PRO.supports.input\n [GEMINI_2_5_FLASH_LITE.name]: typeof GEMINI_2_5_FLASH_LITE.supports.input\n [GEMINI_2_5_FLASH_LITE_PREVIEW.name]: typeof GEMINI_2_5_FLASH_LITE_PREVIEW.supports.input\n\n // Models with text, image, audio, video (no document)\n [GEMINI_2_5_FLASH.name]: typeof GEMINI_2_5_FLASH.supports.input\n [GEMINI_2_5_FLASH_PREVIEW.name]: typeof GEMINI_2_5_FLASH_PREVIEW.supports.input\n [GEMINI_2_FLASH.name]: typeof GEMINI_2_FLASH.supports.input\n [GEMINI_2_FLASH_LITE.name]: typeof GEMINI_2_FLASH_LITE.supports.input\n}\n"],"names":[],"mappings":"AAmDA,MAAM,iBAAiB;AAAA,EACrB,MAAM;AAwBR;AASA,MAAM,eAAe;AAAA,EACnB,MAAM;AAwBR;AASA,MAAM,iBAAiB;AAAA,EACrB,MAAM;AAwBR;AASA,MAAM,qBAAqB;AAAA,EACzB,MAAM;AAkBR;AASA,MAAM,yBAAyB;AAAA,EAC7B,MAAM;AAkBR;AASA,MAAM,wBAAwB;AAAA,EAC5B,MAAM;AAwBR;AASA,MAAM,iBAAiB;AAAA,EACrB,MAAM;AA8BR;AASA,MAAM,qBAAqB;AAAA,EACzB,MAAM;AAiBR;AAOA,MAAM,mBAAmB;AAAA,EACvB,MAAM;AA8BR;AASA,MAAM,2BAA2B;AAAA,EAC/B,MAAM;AAwBR;AASA,MAAM,yBAAyB;AAAA,EAC7B,MAAM;AAkBR;AAyCA,MAAM,uBAAuB;AAAA,EAC3B,MAAM;AAiBR;AAYA,MAAM,uBAAuB;AAAA,EAC3B,MAAM;AAiBR;AAaA,MAAM,cAAc;AAAA,EAClB,MAAM;AAeR;AAMA,MAAM,eAAe;AAAA,EACnB,MAAM;AAeR;AAEA,MAAM,wBAAwB;AAAA,EAC5B,MAAM;AAwBR;AASA,MAAM,gCAAgC;AAAA,EACpC,MAAM;AAwBR;AASA,MAAM,iBAAiB;AAAA,EACrB,MAAM;AAwBR;AAQA,MAAM,uBAAuB;AAAA,EAC3B,MAAM;AAkBR;AAyCA,MAAM,sBAAsB;AAAA,EAC1B,MAAM;AAuBR;AAQA,MAAM,oBAAoB;AAAA,EACxB,MAAM;AAeR;AAOA,MAAM,0BAA0B;AAAA,EAC9B,MAAM;AAeR;AAOA,MAAM,yBAAyB;AAAA,EAC7B,MAAM;AAeR;AAOA,MAAM,WAAW;AAAA,EACf,MAAM;AAcR;AAmJO,MAAM,gBAAgB;AAAA,EAC3B,eAAe;AAAA,EACf,aAAa;AAAA,EACb,eAAe;AAAA,EACf,sBAAsB;AAAA,EACtB,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,yBAAyB;AAAA,EACzB,sBAAsB;AAAA,EACtB,8BAA8B;AAAA,EAC9B,eAAe;AAAA,EACf,oBAAoB;AACtB;AAMO,MAAM,sBAAsB;AAAA,EACjC,uBAAuB;AAAA,EACvB,mBAAmB;AAAA,EACnB,uBAAuB;AAAA,EACvB,qBAAqB;AAAA,EACrB,SAAS;AAAA,EACT,kBAAkB;AAAA,EAClB,uBAAuB;AAAA,EACvB,wBAAwB;AAC1B;AAMO,MAAM,oBAAoB;AAAA,EAC/B,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,mBAAmB;AACrB;AAMO,MAAM,sBAAsB;AAAA,EACjC,YAAY;AAAA,EACZ,aAAa;AACf;AAMO,MAAM,oBAAoB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;"}
1
+ {"version":3,"file":"model-meta.js","sources":["../../src/model-meta.ts"],"sourcesContent":["import type {\n GeminiCachedContentOptions,\n GeminiCommonConfigOptions,\n GeminiSafetyOptions,\n GeminiStructuredOutputOptions,\n GeminiThinkingOptions,\n GeminiToolConfigOptions,\n} from './text/text-provider-options'\n\ninterface ModelMeta<TProviderOptions = unknown> {\n name: string\n supports: {\n input: Array<'text' | 'image' | 'audio' | 'video' | 'document'>\n output: Array<'text' | 'image' | 'audio' | 'video'>\n capabilities?: Array<\n | 'audio_generation'\n | 'batch_api'\n | 'caching'\n | 'function_calling'\n | 'live_api'\n | 'structured_output'\n | 'thinking'\n >\n tools?: Array<\n | 'code_execution'\n | 'file_search'\n | 'google_search'\n | 'google_search_retrieval'\n | 'google_maps'\n | 'url_context'\n | 'computer_use'\n >\n }\n max_input_tokens?: number\n max_output_tokens?: number\n knowledge_cutoff?: string\n pricing?: {\n input: {\n normal: number\n cached?: number\n }\n output: {\n normal: number\n }\n }\n /**\n * Type-level description of which provider options this model supports.\n */\n providerOptions?: TProviderOptions\n}\n\nconst GEMINI_3_1_PRO = {\n name: 'gemini-3.1-pro-preview',\n max_input_tokens: 1_048_576,\n max_output_tokens: 65_536,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'image', 'audio', 'video', 'document'],\n output: ['text'],\n capabilities: [\n 'batch_api',\n 'caching',\n 'function_calling',\n 'structured_output',\n 'thinking',\n ],\n tools: ['code_execution', 'file_search', 'google_search', 'url_context'],\n },\n pricing: {\n input: {\n normal: 2.5,\n },\n output: {\n normal: 15,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n>\n\nconst GEMINI_3_PRO = {\n name: 'gemini-3-pro-preview',\n max_input_tokens: 1_048_576,\n max_output_tokens: 65_536,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'image', 'audio', 'video', 'document'],\n output: ['text'],\n capabilities: [\n 'batch_api',\n 'caching',\n 'function_calling',\n 'structured_output',\n 'thinking',\n ],\n tools: ['code_execution', 'file_search', 'google_search', 'url_context'],\n },\n pricing: {\n input: {\n normal: 2.5,\n },\n output: {\n normal: 15,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n>\n\nconst GEMINI_3_FLASH = {\n name: 'gemini-3-flash-preview',\n max_input_tokens: 1_048_576,\n max_output_tokens: 65_536,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'image', 'audio', 'video', 'document'],\n output: ['text'],\n capabilities: [\n 'batch_api',\n 'caching',\n 'function_calling',\n 'structured_output',\n 'thinking',\n ],\n tools: ['code_execution', 'file_search', 'google_search', 'url_context'],\n },\n pricing: {\n input: {\n normal: 0.5,\n },\n output: {\n normal: 3,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n>\n\nconst GEMINI_3_PRO_IMAGE = {\n name: 'gemini-3-pro-image-preview',\n max_input_tokens: 65_536,\n max_output_tokens: 32_768,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'image'],\n output: ['text', 'image'],\n capabilities: ['batch_api', 'structured_output', 'thinking'],\n tools: ['google_search'],\n },\n pricing: {\n input: {\n normal: 2,\n },\n output: {\n normal: 0.134,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n>\n\nconst GEMINI_3_1_FLASH_IMAGE = {\n name: 'gemini-3.1-flash-image-preview',\n max_input_tokens: 65_536,\n max_output_tokens: 65_536,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'image'],\n output: ['text', 'image'],\n capabilities: ['batch_api', 'structured_output', 'thinking'],\n tools: ['google_search'],\n },\n pricing: {\n input: {\n normal: 0.25,\n },\n output: {\n normal: 1.5,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n>\n\nconst GEMINI_3_1_FLASH_LITE = {\n name: 'gemini-3.1-flash-lite-preview',\n max_input_tokens: 1_048_576,\n max_output_tokens: 65_536,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'image', 'audio', 'video', 'document'],\n output: ['text'],\n capabilities: [\n 'batch_api',\n 'caching',\n 'function_calling',\n 'structured_output',\n 'thinking',\n ],\n tools: ['code_execution', 'file_search', 'google_search', 'url_context'],\n },\n pricing: {\n input: {\n normal: 0.25,\n },\n output: {\n normal: 1.5,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n>\n\nconst GEMINI_2_5_PRO = {\n name: 'gemini-2.5-pro',\n max_input_tokens: 1_048_576,\n max_output_tokens: 65_536,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'image', 'audio', 'video', 'document'],\n output: ['text'],\n capabilities: [\n 'batch_api',\n 'caching',\n 'function_calling',\n 'structured_output',\n 'thinking',\n ],\n tools: [\n 'code_execution',\n 'file_search',\n 'google_maps',\n 'google_search',\n 'url_context',\n ],\n },\n pricing: {\n input: {\n normal: 2.5,\n },\n output: {\n normal: 15,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n>\n\nconst GEMINI_2_5_PRO_TTS = {\n name: 'gemini-2.5-pro-preview-tts',\n max_input_tokens: 8_192,\n max_output_tokens: 16_384,\n knowledge_cutoff: '2025-05-01',\n supports: {\n input: ['text'],\n output: ['audio'],\n capabilities: ['audio_generation'],\n },\n pricing: {\n input: {\n normal: 2.5,\n },\n output: {\n normal: 15,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions\n>\n\nconst GEMINI_2_5_FLASH = {\n name: 'gemini-2.5-flash',\n max_input_tokens: 1_048_576,\n max_output_tokens: 65_536,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'image', 'audio', 'video'],\n output: ['text'],\n capabilities: [\n 'batch_api',\n 'caching',\n 'function_calling',\n 'structured_output',\n 'thinking',\n ],\n tools: [\n 'code_execution',\n 'file_search',\n 'google_maps',\n 'google_search',\n 'url_context',\n ],\n },\n pricing: {\n input: {\n normal: 1,\n },\n output: {\n normal: 2.5,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n>\n\nconst GEMINI_2_5_FLASH_PREVIEW = {\n name: 'gemini-2.5-flash-preview-09-2025',\n max_input_tokens: 1_048_576,\n max_output_tokens: 65_536,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'image', 'audio', 'video'],\n output: ['text'],\n capabilities: [\n 'batch_api',\n 'caching',\n 'function_calling',\n 'structured_output',\n 'thinking',\n ],\n tools: ['code_execution', 'file_search', 'google_search', 'url_context'],\n },\n pricing: {\n input: {\n normal: 1,\n },\n output: {\n normal: 2.5,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n>\n\nconst GEMINI_2_5_FLASH_IMAGE = {\n name: 'gemini-2.5-flash-image',\n max_input_tokens: 1_048_576,\n max_output_tokens: 65_536,\n knowledge_cutoff: '2025-06-01',\n supports: {\n input: ['text', 'image'],\n output: ['text', 'image'],\n capabilities: ['batch_api', 'caching', 'structured_output'],\n tools: ['file_search'],\n },\n pricing: {\n input: {\n normal: 0.3,\n },\n output: {\n normal: 0.4,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions\n>\n/**\nconst GEMINI_2_5_FLASH_LIVE = {\n name: 'gemini-2.5-flash-native-audio-preview-09-2025',\n max_input_tokens: 141_072,\n max_output_tokens: 8_192,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'audio', 'video'],\n output: ['text', 'audio'],\n capabilities: [\n 'audio_generation',\n 'file_search',\n 'function_calling',\n 'live_api',\n 'search_grounding',\n 'thinking',\n ],\n },\n pricing: {\n // todo find this info\n input: {\n normal: 0,\n },\n output: {\n normal: 0,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiGenerationConfigOptions &\n GeminiCachedContentOptions &\n GeminiThinkingOptions\n>\n*/\nconst GEMINI_2_5_FLASH_TTS = {\n name: 'gemini-2.5-flash-preview-tts',\n max_input_tokens: 8_192,\n max_output_tokens: 16_384,\n knowledge_cutoff: '2025-05-01',\n supports: {\n input: ['text'],\n output: ['audio'],\n capabilities: ['audio_generation', 'batch_api'],\n },\n pricing: {\n input: {\n normal: 1,\n },\n output: {\n normal: 2.5,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions\n>\n\n/**\n * Gemini 3.1 Flash TTS Preview - latest expressive TTS model with\n * 200+ audio tags, 70+ languages, and multi-speaker dialogue support.\n * @see https://ai.google.dev/gemini-api/docs/models/gemini-3.1-flash-tts-preview\n */\nconst GEMINI_3_1_FLASH_TTS = {\n name: 'gemini-3.1-flash-tts-preview',\n max_input_tokens: 32_768,\n max_output_tokens: 16_384,\n knowledge_cutoff: '2025-05-01',\n supports: {\n input: ['text'],\n output: ['audio'],\n capabilities: ['audio_generation', 'batch_api'],\n },\n pricing: {\n input: {\n normal: 0.5,\n },\n output: {\n normal: 10,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions\n>\n\n/**\n * Lyria 3 Pro Preview — Google's flagship music generation model.\n * Generates full-length songs with multiple verses, choruses, and bridges.\n * Outputs MP3 or WAV at 48 kHz stereo.\n * @see https://ai.google.dev/gemini-api/docs/models/lyria-3-pro-preview\n */\nconst LYRIA_3_PRO = {\n name: 'lyria-3-pro-preview',\n max_input_tokens: 131_072,\n supports: {\n input: ['text', 'image'],\n output: ['audio'],\n capabilities: ['audio_generation'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0,\n },\n },\n} as const satisfies ModelMeta\n\n/**\n * Lyria 3 Clip Preview — 30-second music clips in MP3 format.\n * @see https://ai.google.dev/gemini-api/docs/music-generation\n */\nconst LYRIA_3_CLIP = {\n name: 'lyria-3-clip-preview',\n max_input_tokens: 131_072,\n supports: {\n input: ['text', 'image'],\n output: ['audio'],\n capabilities: ['audio_generation'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0,\n },\n },\n} as const satisfies ModelMeta\n\nconst GEMINI_2_5_FLASH_LITE = {\n name: 'gemini-2.5-flash-lite',\n max_input_tokens: 1_048_576,\n max_output_tokens: 65_536,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'image', 'audio', 'video', 'document'],\n output: ['text'],\n capabilities: [\n 'batch_api',\n 'caching',\n 'function_calling',\n 'structured_output',\n 'thinking',\n ],\n tools: ['code_execution', 'google_maps', 'google_search', 'url_context'],\n },\n pricing: {\n input: {\n normal: 0.1,\n },\n output: {\n normal: 0.4,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n>\n\nconst GEMINI_2_5_FLASH_LITE_PREVIEW = {\n name: 'gemini-2.5-flash-lite-preview-09-2025',\n max_input_tokens: 1_048_576,\n max_output_tokens: 65_536,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'image', 'audio', 'video', 'document'],\n output: ['text'],\n capabilities: [\n 'batch_api',\n 'caching',\n 'function_calling',\n 'structured_output',\n 'thinking',\n ],\n tools: ['code_execution', 'google_search', 'url_context'],\n },\n pricing: {\n input: {\n normal: 0.1,\n },\n output: {\n normal: 0.4,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n>\n\nconst GEMINI_2_FLASH = {\n name: 'gemini-2.0-flash',\n max_input_tokens: 1_048_576,\n max_output_tokens: 8_192,\n knowledge_cutoff: '2024-08-01',\n supports: {\n input: ['text', 'image', 'audio', 'video'],\n output: ['text'],\n capabilities: [\n 'batch_api',\n 'caching',\n 'function_calling',\n 'live_api',\n 'structured_output',\n ],\n tools: ['code_execution', 'google_maps', 'google_search'],\n },\n pricing: {\n input: {\n normal: 0.1,\n },\n output: {\n normal: 0.4,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions\n>\n\nconst GEMINI_2_FLASH_IMAGE = {\n name: 'gemini-2.0-flash-preview-image-generation',\n max_input_tokens: 32_768,\n max_output_tokens: 8_192,\n knowledge_cutoff: '2024-08-01',\n supports: {\n input: ['text', 'image', 'audio', 'video'],\n output: ['text', 'image'],\n capabilities: ['batch_api', 'caching', 'structured_output'],\n tools: [],\n },\n pricing: {\n input: {\n normal: 0.1,\n },\n output: {\n normal: 0.039,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions\n>\n/* \nconst GEMINI_2_FLASH_LIVE = {\n name: 'gemini-2.0-flash-live-001',\n max_input_tokens: 1_048_576,\n max_output_tokens: 8_192,\n knowledge_cutoff: '2024-08-01',\n supports: {\n input: ['text', 'audio', 'video'],\n output: ['text', 'audio'],\n capabilities: [\n 'audio_generation',\n 'code_execution',\n 'function_calling',\n 'live_api',\n 'search_grounding',\n 'structured_output',\n 'url_context',\n ],\n },\n pricing: {\n // todo find this info\n input: {\n normal: 0,\n },\n output: {\n normal: 0,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiGenerationConfigOptions &\n GeminiCachedContentOptions\n> */\n\nconst GEMINI_2_FLASH_LITE = {\n name: 'gemini-2.0-flash-lite',\n max_input_tokens: 1_048_576,\n max_output_tokens: 8_192,\n knowledge_cutoff: '2024-08-01',\n supports: {\n input: ['text', 'audio', 'video', 'image'],\n output: ['text'],\n capabilities: [\n 'batch_api',\n 'caching',\n 'function_calling',\n 'structured_output',\n ],\n tools: [],\n },\n pricing: {\n input: {\n normal: 0.075,\n },\n output: {\n normal: 0.3,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions\n>\n\nconst IMAGEN_4_GENERATE = {\n name: 'imagen-4.0-generate-001',\n max_input_tokens: 480,\n max_output_tokens: 4,\n supports: {\n input: ['text'],\n output: ['image'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0.4,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions\n>\n\nconst IMAGEN_4_GENERATE_ULTRA = {\n name: 'imagen-4.0-ultra-generate-001',\n max_input_tokens: 480,\n max_output_tokens: 4,\n supports: {\n input: ['text'],\n output: ['image'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0.6,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions\n>\n\nconst IMAGEN_4_GENERATE_FAST = {\n name: 'imagen-4.0-fast-generate-001',\n max_input_tokens: 480,\n max_output_tokens: 4,\n supports: {\n input: ['text'],\n output: ['image'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0.2,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions\n>\n\nconst IMAGEN_3 = {\n name: 'imagen-3.0-generate-002',\n max_output_tokens: 4,\n supports: {\n input: ['text'],\n output: ['image'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0.03,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions\n>\n/** \nconst VEO_3_1_PREVIEW = {\n name: 'veo-3.1-generate-preview',\n max_input_tokens: 1024,\n max_output_tokens: 1,\n supports: {\n input: ['text', 'image'],\n output: ['video', 'audio'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0.4,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiGenerationConfigOptions &\n GeminiCachedContentOptions\n>\n\nconst VEO_3_1_FAST_PREVIEW = {\n name: 'veo-3.1-fast-generate-preview',\n max_input_tokens: 1024,\n max_output_tokens: 1,\n supports: {\n input: ['text', 'image'],\n output: ['video', 'audio'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0.15,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiGenerationConfigOptions &\n GeminiCachedContentOptions\n>\n\nconst VEO_3 = {\n name: 'veo-3.0-generate-001',\n max_input_tokens: 1024,\n max_output_tokens: 1,\n supports: {\n input: ['text', 'image'],\n output: ['video', 'audio'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0.4,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiGenerationConfigOptions &\n GeminiCachedContentOptions\n>\n\nconst VEO_3_FAST = {\n name: 'veo-3.0-fast-generate-001',\n max_input_tokens: 1024,\n max_output_tokens: 1,\n supports: {\n input: ['text', 'image'],\n output: ['video', 'audio'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0.15,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiGenerationConfigOptions &\n GeminiCachedContentOptions\n>\n\nconst VEO_2 = {\n name: 'veo-2.0-generate-001',\n max_output_tokens: 2,\n supports: {\n input: ['text', 'image'],\n output: ['video'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0.35,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiGenerationConfigOptions &\n GeminiCachedContentOptions\n> */\n\n/* const GEMINI_MODEL_META = {\n [GEMINI_3_PRO.name]: GEMINI_3_PRO,\n [GEMINI_2_5_PRO.name]: GEMINI_2_5_PRO,\n [GEMINI_2_5_PRO_TTS.name]: GEMINI_2_5_PRO_TTS,\n [GEMINI_2_5_FLASH.name]: GEMINI_2_5_FLASH,\n [GEMINI_2_5_FLASH_PREVIEW.name]: GEMINI_2_5_FLASH_PREVIEW,\n [GEMINI_2_5_FLASH_IMAGE.name]: GEMINI_2_5_FLASH_IMAGE,\n [GEMINI_2_5_FLASH_LIVE.name]: GEMINI_2_5_FLASH_LIVE,\n [GEMINI_2_5_FLASH_TTS.name]: GEMINI_2_5_FLASH_TTS,\n [GEMINI_2_5_FLASH_LITE.name]: GEMINI_2_5_FLASH_LITE,\n [GEMINI_2_5_FLASH_LITE_PREVIEW.name]: GEMINI_2_5_FLASH_LITE_PREVIEW,\n [GEMINI_2_FLASH.name]: GEMINI_2_FLASH,\n [GEMINI_2_FLASH_IMAGE.name]: GEMINI_2_FLASH_IMAGE,\n [GEMINI_2_FLASH_LIVE.name]: GEMINI_2_FLASH_LIVE,\n [GEMINI_2_FLASH_LITE.name]: GEMINI_2_FLASH_LITE,\n [IMAGEN_4_GENERATE.name]: IMAGEN_4_GENERATE,\n [IMAGEN_4_GENERATE_ULTRA.name]: IMAGEN_4_GENERATE_ULTRA,\n [IMAGEN_4_GENERATE_FAST.name]: IMAGEN_4_GENERATE_FAST,\n [IMAGEN_3.name]: IMAGEN_3,\n [VEO_3_1_PREVIEW.name]: VEO_3_1_PREVIEW,\n [VEO_3_1_FAST_PREVIEW.name]: VEO_3_1_FAST_PREVIEW,\n [VEO_3.name]: VEO_3,\n [VEO_3_FAST.name]: VEO_3_FAST,\n [VEO_2.name]: VEO_2,\n} as const */\n\nconst GEMINI_3_5_FLASH = {\n name: 'gemini-3.5-flash',\n max_input_tokens: 1_048_576,\n max_output_tokens: 65_536,\n supports: {\n input: ['text', 'image', 'video', 'document', 'audio'],\n output: ['text'],\n capabilities: [\n 'batch_api',\n 'caching',\n 'function_calling',\n 'structured_output',\n 'thinking',\n ],\n tools: ['code_execution', 'file_search', 'google_search', 'url_context'],\n },\n pricing: {\n input: {\n normal: 1.5,\n cached: 0.15,\n },\n output: {\n normal: 9,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n>\n\nexport const GEMINI_MODELS = [\n GEMINI_3_1_PRO.name,\n GEMINI_3_PRO.name,\n GEMINI_3_FLASH.name,\n GEMINI_3_1_FLASH_LITE.name,\n GEMINI_2_5_PRO.name,\n GEMINI_2_5_FLASH.name,\n GEMINI_2_5_FLASH_PREVIEW.name,\n GEMINI_2_5_FLASH_LITE.name,\n GEMINI_2_5_FLASH_LITE_PREVIEW.name,\n GEMINI_2_FLASH.name,\n GEMINI_2_FLASH_LITE.name,\n\n GEMINI_3_5_FLASH.name,\n] as const\n\nexport type GeminiModels = (typeof GEMINI_MODELS)[number]\n\nexport type GeminiImageModels = (typeof GEMINI_IMAGE_MODELS)[number]\n\nexport const GEMINI_IMAGE_MODELS = [\n GEMINI_3_1_FLASH_IMAGE.name,\n GEMINI_3_PRO_IMAGE.name,\n GEMINI_2_5_FLASH_IMAGE.name,\n GEMINI_2_FLASH_IMAGE.name,\n IMAGEN_3.name,\n IMAGEN_4_GENERATE.name,\n IMAGEN_4_GENERATE_FAST.name,\n IMAGEN_4_GENERATE_ULTRA.name,\n] as const\n\n/**\n * Text-to-speech models\n * @experimental Gemini TTS is an experimental feature and may change.\n */\nexport const GEMINI_TTS_MODELS = [\n GEMINI_3_1_FLASH_TTS.name,\n GEMINI_2_5_FLASH_TTS.name,\n GEMINI_2_5_PRO_TTS.name,\n] as const\n\n/**\n * Audio generation models (Lyria music generation).\n * @experimental Lyria music generation is an experimental feature and may change.\n */\nexport const GEMINI_AUDIO_MODELS = [\n LYRIA_3_PRO.name,\n LYRIA_3_CLIP.name,\n] as const\n\n/**\n * Available voice names for Gemini TTS\n * @see https://ai.google.dev/gemini-api/docs/speech-generation\n */\nexport const GEMINI_TTS_VOICES = [\n 'Zephyr',\n 'Puck',\n 'Charon',\n 'Kore',\n 'Fenrir',\n 'Leda',\n 'Orus',\n 'Aoede',\n 'Callirrhoe',\n 'Autonoe',\n 'Enceladus',\n 'Iapetus',\n 'Umbriel',\n 'Algieba',\n 'Despina',\n 'Erinome',\n 'Algenib',\n 'Rasalgethi',\n 'Laomedeia',\n 'Achernar',\n 'Alnilam',\n 'Schedar',\n 'Gacrux',\n 'Pulcherrima',\n 'Achird',\n 'Zubenelgenubi',\n 'Vindemiatrix',\n 'Sadachbia',\n 'Sadaltager',\n 'Sulafat',\n] as const\n\nexport type GeminiTTSVoice = (typeof GEMINI_TTS_VOICES)[number]\n\n/* const GEMINI_AUDIO_MODELS = [\n GEMINI_2_5_PRO_TTS.name,\n GEMINI_2_5_FLASH_TTS.name,\n GEMINI_2_5_FLASH_LIVE.name,\n GEMINI_2_FLASH_LIVE.name,\n] as const\n\n const GEMINI_VIDEO_MODELS = [\n VEO_3_1_PREVIEW.name,\n VEO_3_1_FAST_PREVIEW.name,\n VEO_3.name,\n VEO_3_FAST.name,\n VEO_2.name,\n] as const */\n\n// Manual type map for per-model provider options\nexport type GeminiChatModelProviderOptionsByName = {\n // Models with thinking and structured output support\n [GEMINI_3_1_PRO.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n [GEMINI_3_PRO.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n [GEMINI_3_FLASH.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n [GEMINI_3_1_FLASH_LITE.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n [GEMINI_2_5_PRO.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n [GEMINI_2_5_FLASH.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n [GEMINI_2_5_FLASH_PREVIEW.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n [GEMINI_2_5_FLASH_LITE.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n [GEMINI_2_5_FLASH_LITE_PREVIEW.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n // Models with structured output but no thinking support\n [GEMINI_2_FLASH.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions\n [GEMINI_2_FLASH_LITE.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions\n [GEMINI_3_5_FLASH.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n}\n\n/**\n * Type-only map from chat model name to its supported tool capabilities.\n * Based on the 'supports.tools' arrays defined for each model.\n */\nexport type GeminiChatModelToolCapabilitiesByName = {\n [GEMINI_3_1_PRO.name]: typeof GEMINI_3_1_PRO.supports.tools\n [GEMINI_3_PRO.name]: typeof GEMINI_3_PRO.supports.tools\n [GEMINI_3_FLASH.name]: typeof GEMINI_3_FLASH.supports.tools\n [GEMINI_3_1_FLASH_LITE.name]: typeof GEMINI_3_1_FLASH_LITE.supports.tools\n [GEMINI_2_5_PRO.name]: typeof GEMINI_2_5_PRO.supports.tools\n [GEMINI_2_5_FLASH.name]: typeof GEMINI_2_5_FLASH.supports.tools\n [GEMINI_2_5_FLASH_PREVIEW.name]: typeof GEMINI_2_5_FLASH_PREVIEW.supports.tools\n [GEMINI_2_5_FLASH_LITE.name]: typeof GEMINI_2_5_FLASH_LITE.supports.tools\n [GEMINI_2_5_FLASH_LITE_PREVIEW.name]: typeof GEMINI_2_5_FLASH_LITE_PREVIEW.supports.tools\n [GEMINI_2_FLASH.name]: typeof GEMINI_2_FLASH.supports.tools\n [GEMINI_2_FLASH_LITE.name]: typeof GEMINI_2_FLASH_LITE.supports.tools\n}\n\n/**\n * Type-only map from chat model name to its supported input modalities.\n * Based on the 'supports.input' arrays defined for each model.\n * Note: 'document' in the model meta is mapped to 'document' modality.\n * Used by the core AI types to constrain ContentPart types based on the selected model.\n * Note: These must be inlined as readonly arrays (not typeof) because the model\n * constants are not exported and typeof references don't work in .d.ts files\n * when consumed by external packages.\n *\n * @see https://ai.google.dev/gemini-api/docs/vision\n * @see https://ai.google.dev/gemini-api/docs/audio\n * @see https://ai.google.dev/gemini-api/docs/document-processing\n */\nexport type GeminiModelInputModalitiesByName = {\n // Models with full multimodal support (text, image, audio, video, document)\n [GEMINI_3_1_PRO.name]: typeof GEMINI_3_1_PRO.supports.input\n [GEMINI_3_PRO.name]: typeof GEMINI_3_PRO.supports.input\n [GEMINI_3_FLASH.name]: typeof GEMINI_3_FLASH.supports.input\n [GEMINI_3_1_FLASH_LITE.name]: typeof GEMINI_3_1_FLASH_LITE.supports.input\n [GEMINI_2_5_PRO.name]: typeof GEMINI_2_5_PRO.supports.input\n [GEMINI_2_5_FLASH_LITE.name]: typeof GEMINI_2_5_FLASH_LITE.supports.input\n [GEMINI_2_5_FLASH_LITE_PREVIEW.name]: typeof GEMINI_2_5_FLASH_LITE_PREVIEW.supports.input\n\n // Models with text, image, audio, video (no document)\n [GEMINI_2_5_FLASH.name]: typeof GEMINI_2_5_FLASH.supports.input\n [GEMINI_2_5_FLASH_PREVIEW.name]: typeof GEMINI_2_5_FLASH_PREVIEW.supports.input\n [GEMINI_2_FLASH.name]: typeof GEMINI_2_FLASH.supports.input\n [GEMINI_2_FLASH_LITE.name]: typeof GEMINI_2_FLASH_LITE.supports.input\n [GEMINI_3_5_FLASH.name]: typeof GEMINI_3_5_FLASH.supports.input\n}\n"],"names":[],"mappings":"AAmDA,MAAM,iBAAiB;AAAA,EACrB,MAAM;AAwBR;AASA,MAAM,eAAe;AAAA,EACnB,MAAM;AAwBR;AASA,MAAM,iBAAiB;AAAA,EACrB,MAAM;AAwBR;AASA,MAAM,qBAAqB;AAAA,EACzB,MAAM;AAkBR;AASA,MAAM,yBAAyB;AAAA,EAC7B,MAAM;AAkBR;AASA,MAAM,wBAAwB;AAAA,EAC5B,MAAM;AAwBR;AASA,MAAM,iBAAiB;AAAA,EACrB,MAAM;AA8BR;AASA,MAAM,qBAAqB;AAAA,EACzB,MAAM;AAiBR;AAOA,MAAM,mBAAmB;AAAA,EACvB,MAAM;AA8BR;AASA,MAAM,2BAA2B;AAAA,EAC/B,MAAM;AAwBR;AASA,MAAM,yBAAyB;AAAA,EAC7B,MAAM;AAkBR;AAyCA,MAAM,uBAAuB;AAAA,EAC3B,MAAM;AAiBR;AAYA,MAAM,uBAAuB;AAAA,EAC3B,MAAM;AAiBR;AAaA,MAAM,cAAc;AAAA,EAClB,MAAM;AAeR;AAMA,MAAM,eAAe;AAAA,EACnB,MAAM;AAeR;AAEA,MAAM,wBAAwB;AAAA,EAC5B,MAAM;AAwBR;AASA,MAAM,gCAAgC;AAAA,EACpC,MAAM;AAwBR;AASA,MAAM,iBAAiB;AAAA,EACrB,MAAM;AAwBR;AAQA,MAAM,uBAAuB;AAAA,EAC3B,MAAM;AAkBR;AAyCA,MAAM,sBAAsB;AAAA,EAC1B,MAAM;AAuBR;AAQA,MAAM,oBAAoB;AAAA,EACxB,MAAM;AAeR;AAOA,MAAM,0BAA0B;AAAA,EAC9B,MAAM;AAeR;AAOA,MAAM,yBAAyB;AAAA,EAC7B,MAAM;AAeR;AAOA,MAAM,WAAW;AAAA,EACf,MAAM;AAcR;AAmJA,MAAM,mBAAmB;AAAA,EACvB,MAAM;AAwBR;AASO,MAAM,gBAAgB;AAAA,EAC3B,eAAe;AAAA,EACf,aAAa;AAAA,EACb,eAAe;AAAA,EACf,sBAAsB;AAAA,EACtB,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,yBAAyB;AAAA,EACzB,sBAAsB;AAAA,EACtB,8BAA8B;AAAA,EAC9B,eAAe;AAAA,EACf,oBAAoB;AAAA,EAEpB,iBAAiB;AACnB;AAMO,MAAM,sBAAsB;AAAA,EACjC,uBAAuB;AAAA,EACvB,mBAAmB;AAAA,EACnB,uBAAuB;AAAA,EACvB,qBAAqB;AAAA,EACrB,SAAS;AAAA,EACT,kBAAkB;AAAA,EAClB,uBAAuB;AAAA,EACvB,wBAAwB;AAC1B;AAMO,MAAM,oBAAoB;AAAA,EAC/B,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,mBAAmB;AACrB;AAMO,MAAM,sBAAsB;AAAA,EACjC,YAAY;AAAA,EACZ,aAAa;AACf;AAMO,MAAM,oBAAoB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;"}
@@ -1,14 +1,15 @@
1
+ import { brandProviderTool } from "@tanstack/ai";
1
2
  function convertCodeExecutionToolToAdapterFormat(_tool) {
2
3
  return {
3
4
  codeExecution: {}
4
5
  };
5
6
  }
6
7
  function codeExecutionTool() {
7
- return {
8
+ return brandProviderTool({
8
9
  name: "code_execution",
9
10
  description: "",
10
11
  metadata: {}
11
- };
12
+ });
12
13
  }
13
14
  export {
14
15
  codeExecutionTool,
@@ -1 +1 @@
1
- {"version":3,"file":"code-execution-tool.js","sources":["../../../src/tools/code-execution-tool.ts"],"sourcesContent":["import type { ProviderTool, Tool } from '@tanstack/ai'\n\nexport interface CodeExecutionToolConfig {}\n\n/** @deprecated Renamed to `CodeExecutionToolConfig`. Will be removed in a future release. */\nexport type CodeExecutionTool = CodeExecutionToolConfig\n\nexport type GeminiCodeExecutionTool = ProviderTool<'gemini', 'code_execution'>\n\nexport function convertCodeExecutionToolToAdapterFormat(_tool: Tool) {\n return {\n codeExecution: {},\n }\n}\n\nexport function codeExecutionTool(): GeminiCodeExecutionTool {\n // Phantom-brand cast: '~provider'/'~toolKind' are type-only and never assigned at runtime.\n return {\n name: 'code_execution',\n description: '',\n metadata: {},\n } as unknown as GeminiCodeExecutionTool\n}\n"],"names":[],"mappings":"AASO,SAAS,wCAAwC,OAAa;AACnE,SAAO;AAAA,IACL,eAAe,CAAA;AAAA,EAAC;AAEpB;AAEO,SAAS,oBAA6C;AAE3D,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aAAa;AAAA,IACb,UAAU,CAAA;AAAA,EAAC;AAEf;"}
1
+ {"version":3,"file":"code-execution-tool.js","sources":["../../../src/tools/code-execution-tool.ts"],"sourcesContent":["import { brandProviderTool } from '@tanstack/ai'\nimport type { ProviderTool, Tool } from '@tanstack/ai'\n\nexport interface CodeExecutionToolConfig {}\n\n/** @deprecated Renamed to `CodeExecutionToolConfig`. Will be removed in a future release. */\nexport type CodeExecutionTool = CodeExecutionToolConfig\n\nexport type GeminiCodeExecutionTool = ProviderTool<'gemini', 'code_execution'>\n\nexport function convertCodeExecutionToolToAdapterFormat(_tool: Tool) {\n return {\n codeExecution: {},\n }\n}\n\nexport function codeExecutionTool(): GeminiCodeExecutionTool {\n return brandProviderTool<GeminiCodeExecutionTool>({\n name: 'code_execution',\n description: '',\n metadata: {},\n })\n}\n"],"names":[],"mappings":";AAUO,SAAS,wCAAwC,OAAa;AACnE,SAAO;AAAA,IACL,eAAe,CAAA;AAAA,EAAC;AAEpB;AAEO,SAAS,oBAA6C;AAC3D,SAAO,kBAA2C;AAAA,IAChD,MAAM;AAAA,IACN,aAAa;AAAA,IACb,UAAU,CAAA;AAAA,EAAC,CACZ;AACH;"}
@@ -6,8 +6,8 @@ export type ComputerUseTool = ComputerUseToolConfig;
6
6
  export type GeminiComputerUseTool = ProviderTool<'gemini', 'computer_use'>;
7
7
  export declare function convertComputerUseToolToAdapterFormat(tool: Tool): {
8
8
  computerUse: {
9
- environment: import('@google/genai').Environment | undefined;
10
- excludedPredefinedFunctions: string[] | undefined;
9
+ excludedPredefinedFunctions?: string[] | undefined;
10
+ environment?: import('@google/genai').Environment | undefined;
11
11
  };
12
12
  };
13
13
  export declare function computerUseTool(config: ComputerUseToolConfig): GeminiComputerUseTool;
@@ -1,21 +1,30 @@
1
+ import { brandProviderTool } from "@tanstack/ai";
1
2
  function convertComputerUseToolToAdapterFormat(tool) {
2
3
  const metadata = tool.metadata;
3
4
  return {
4
5
  computerUse: {
5
- environment: metadata.environment,
6
- excludedPredefinedFunctions: metadata.excludedPredefinedFunctions
6
+ ...metadata.environment !== void 0 && {
7
+ environment: metadata.environment
8
+ },
9
+ ...metadata.excludedPredefinedFunctions !== void 0 && {
10
+ excludedPredefinedFunctions: metadata.excludedPredefinedFunctions
11
+ }
7
12
  }
8
13
  };
9
14
  }
10
15
  function computerUseTool(config) {
11
- return {
16
+ return brandProviderTool({
12
17
  name: "computer_use",
13
18
  description: "",
14
19
  metadata: {
15
- environment: config.environment,
16
- excludedPredefinedFunctions: config.excludedPredefinedFunctions
20
+ ...config.environment !== void 0 && {
21
+ environment: config.environment
22
+ },
23
+ ...config.excludedPredefinedFunctions !== void 0 && {
24
+ excludedPredefinedFunctions: config.excludedPredefinedFunctions
25
+ }
17
26
  }
18
- };
27
+ });
19
28
  }
20
29
  export {
21
30
  computerUseTool,
@@ -1 +1 @@
1
- {"version":3,"file":"computer-use-tool.js","sources":["../../../src/tools/computer-use-tool.ts"],"sourcesContent":["import type { ComputerUse } from '@google/genai'\nimport type { ProviderTool, Tool } from '@tanstack/ai'\n\nexport type ComputerUseToolConfig = ComputerUse\n\n/** @deprecated Renamed to `ComputerUseToolConfig`. Will be removed in a future release. */\nexport type ComputerUseTool = ComputerUseToolConfig\n\nexport type GeminiComputerUseTool = ProviderTool<'gemini', 'computer_use'>\n\nexport function convertComputerUseToolToAdapterFormat(tool: Tool) {\n const metadata = tool.metadata as ComputerUseToolConfig\n return {\n computerUse: {\n environment: metadata.environment,\n excludedPredefinedFunctions: metadata.excludedPredefinedFunctions,\n },\n }\n}\n\nexport function computerUseTool(\n config: ComputerUseToolConfig,\n): GeminiComputerUseTool {\n // Phantom-brand cast: '~provider'/'~toolKind' are type-only and never assigned at runtime.\n return {\n name: 'computer_use',\n description: '',\n metadata: {\n environment: config.environment,\n excludedPredefinedFunctions: config.excludedPredefinedFunctions,\n },\n } as unknown as GeminiComputerUseTool\n}\n"],"names":[],"mappings":"AAUO,SAAS,sCAAsC,MAAY;AAChE,QAAM,WAAW,KAAK;AACtB,SAAO;AAAA,IACL,aAAa;AAAA,MACX,aAAa,SAAS;AAAA,MACtB,6BAA6B,SAAS;AAAA,IAAA;AAAA,EACxC;AAEJ;AAEO,SAAS,gBACd,QACuB;AAEvB,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aAAa;AAAA,IACb,UAAU;AAAA,MACR,aAAa,OAAO;AAAA,MACpB,6BAA6B,OAAO;AAAA,IAAA;AAAA,EACtC;AAEJ;"}
1
+ {"version":3,"file":"computer-use-tool.js","sources":["../../../src/tools/computer-use-tool.ts"],"sourcesContent":["import { brandProviderTool } from '@tanstack/ai'\nimport type { ComputerUse } from '@google/genai'\nimport type { ProviderTool, Tool } from '@tanstack/ai'\n\nexport type ComputerUseToolConfig = ComputerUse\n\n/** @deprecated Renamed to `ComputerUseToolConfig`. Will be removed in a future release. */\nexport type ComputerUseTool = ComputerUseToolConfig\n\nexport type GeminiComputerUseTool = ProviderTool<'gemini', 'computer_use'>\n\nexport function convertComputerUseToolToAdapterFormat(tool: Tool) {\n const metadata = tool.metadata as ComputerUseToolConfig\n // Vendor `ComputerUse` fields are `field?: T` (no `| undefined`) under EOPT,\n // so spread each field conditionally rather than emitting explicit\n // `undefined`s on the wire payload.\n return {\n computerUse: {\n ...(metadata.environment !== undefined && {\n environment: metadata.environment,\n }),\n ...(metadata.excludedPredefinedFunctions !== undefined && {\n excludedPredefinedFunctions: metadata.excludedPredefinedFunctions,\n }),\n },\n }\n}\n\nexport function computerUseTool(\n config: ComputerUseToolConfig,\n): GeminiComputerUseTool {\n return brandProviderTool<GeminiComputerUseTool>({\n name: 'computer_use',\n description: '',\n metadata: {\n ...(config.environment !== undefined && {\n environment: config.environment,\n }),\n ...(config.excludedPredefinedFunctions !== undefined && {\n excludedPredefinedFunctions: config.excludedPredefinedFunctions,\n }),\n },\n })\n}\n"],"names":[],"mappings":";AAWO,SAAS,sCAAsC,MAAY;AAChE,QAAM,WAAW,KAAK;AAItB,SAAO;AAAA,IACL,aAAa;AAAA,MACX,GAAI,SAAS,gBAAgB,UAAa;AAAA,QACxC,aAAa,SAAS;AAAA,MAAA;AAAA,MAExB,GAAI,SAAS,gCAAgC,UAAa;AAAA,QACxD,6BAA6B,SAAS;AAAA,MAAA;AAAA,IACxC;AAAA,EACF;AAEJ;AAEO,SAAS,gBACd,QACuB;AACvB,SAAO,kBAAyC;AAAA,IAC9C,MAAM;AAAA,IACN,aAAa;AAAA,IACb,UAAU;AAAA,MACR,GAAI,OAAO,gBAAgB,UAAa;AAAA,QACtC,aAAa,OAAO;AAAA,MAAA;AAAA,MAEtB,GAAI,OAAO,gCAAgC,UAAa;AAAA,QACtD,6BAA6B,OAAO;AAAA,MAAA;AAAA,IACtC;AAAA,EACF,CACD;AACH;"}
@@ -1,3 +1,4 @@
1
+ import { brandProviderTool } from "@tanstack/ai";
1
2
  function convertFileSearchToolToAdapterFormat(tool) {
2
3
  const metadata = tool.metadata;
3
4
  return {
@@ -5,11 +6,11 @@ function convertFileSearchToolToAdapterFormat(tool) {
5
6
  };
6
7
  }
7
8
  function fileSearchTool(config) {
8
- return {
9
+ return brandProviderTool({
9
10
  name: "file_search",
10
11
  description: "",
11
12
  metadata: config
12
- };
13
+ });
13
14
  }
14
15
  export {
15
16
  convertFileSearchToolToAdapterFormat,
@@ -1 +1 @@
1
- {"version":3,"file":"file-search-tool.js","sources":["../../../src/tools/file-search-tool.ts"],"sourcesContent":["import type { FileSearch } from '@google/genai'\nimport type { ProviderTool, Tool } from '@tanstack/ai'\n\nexport type FileSearchToolConfig = FileSearch\n\n/** @deprecated Renamed to `FileSearchToolConfig`. Will be removed in a future release. */\nexport type FileSearchTool = FileSearchToolConfig\n\nexport type GeminiFileSearchTool = ProviderTool<'gemini', 'file_search'>\n\nexport function convertFileSearchToolToAdapterFormat(tool: Tool) {\n const metadata = tool.metadata as FileSearchToolConfig\n return {\n fileSearch: metadata,\n }\n}\n\nexport function fileSearchTool(\n config: FileSearchToolConfig,\n): GeminiFileSearchTool {\n // Phantom-brand cast: '~provider'/'~toolKind' are type-only and never assigned at runtime.\n return {\n name: 'file_search',\n description: '',\n metadata: config,\n } as unknown as GeminiFileSearchTool\n}\n"],"names":[],"mappings":"AAUO,SAAS,qCAAqC,MAAY;AAC/D,QAAM,WAAW,KAAK;AACtB,SAAO;AAAA,IACL,YAAY;AAAA,EAAA;AAEhB;AAEO,SAAS,eACd,QACsB;AAEtB,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aAAa;AAAA,IACb,UAAU;AAAA,EAAA;AAEd;"}
1
+ {"version":3,"file":"file-search-tool.js","sources":["../../../src/tools/file-search-tool.ts"],"sourcesContent":["import { brandProviderTool } from '@tanstack/ai'\nimport type { FileSearch } from '@google/genai'\nimport type { ProviderTool, Tool } from '@tanstack/ai'\n\nexport type FileSearchToolConfig = FileSearch\n\n/** @deprecated Renamed to `FileSearchToolConfig`. Will be removed in a future release. */\nexport type FileSearchTool = FileSearchToolConfig\n\nexport type GeminiFileSearchTool = ProviderTool<'gemini', 'file_search'>\n\nexport function convertFileSearchToolToAdapterFormat(tool: Tool) {\n const metadata = tool.metadata as FileSearchToolConfig\n return {\n fileSearch: metadata,\n }\n}\n\nexport function fileSearchTool(\n config: FileSearchToolConfig,\n): GeminiFileSearchTool {\n return brandProviderTool<GeminiFileSearchTool>({\n name: 'file_search',\n description: '',\n metadata: config,\n })\n}\n"],"names":[],"mappings":";AAWO,SAAS,qCAAqC,MAAY;AAC/D,QAAM,WAAW,KAAK;AACtB,SAAO;AAAA,IACL,YAAY;AAAA,EAAA;AAEhB;AAEO,SAAS,eACd,QACsB;AACtB,SAAO,kBAAwC;AAAA,IAC7C,MAAM;AAAA,IACN,aAAa;AAAA,IACb,UAAU;AAAA,EAAA,CACX;AACH;"}
@@ -1,7 +1,6 @@
1
1
  const validateFunctionDeclarationTool = (tool) => {
2
2
  const nameRegex = /^[a-zA-Z0-9_:.-]{1,64}$/;
3
- const valid = nameRegex.test(tool.name);
4
- if (!valid) {
3
+ if (tool.name === void 0 || !nameRegex.test(tool.name)) {
5
4
  throw new Error(
6
5
  `Invalid function name: ${tool.name}. Must be 1-64 characters long and contain only a-z, A-Z, 0-9, underscores, colons, dots, and dashes.`
7
6
  );
@@ -1 +1 @@
1
- {"version":3,"file":"function-declaration-tool.js","sources":["../../../src/tools/function-declaration-tool.ts"],"sourcesContent":["import type { FunctionDeclaration } from '@google/genai'\n\nexport type FunctionDeclarationTool = FunctionDeclaration\n\nconst validateFunctionDeclarationTool = (tool: FunctionDeclarationTool) => {\n const nameRegex = /^[a-zA-Z0-9_:.-]{1,64}$/\n const valid = nameRegex.test(tool.name!)\n if (!valid) {\n throw new Error(\n `Invalid function name: ${tool.name}. Must be 1-64 characters long and contain only a-z, A-Z, 0-9, underscores, colons, dots, and dashes.`,\n )\n }\n\n if (tool.parameters && tool.parametersJsonSchema) {\n throw new Error(\n `FunctionDeclarationTool cannot have both 'parameters' and 'parametersJsonSchema' defined. Please use only one.`,\n )\n }\n\n if (tool.response && tool.responseJsonSchema) {\n throw new Error(\n `FunctionDeclarationTool cannot have both 'response' and 'responseJsonSchema' defined. Please use only one.`,\n )\n }\n}\n\nexport function functionDeclarationTools(\n tools: Array<FunctionDeclarationTool>,\n) {\n tools.forEach(validateFunctionDeclarationTool)\n return {\n functionDeclarations: tools,\n }\n}\n"],"names":[],"mappings":"AAIA,MAAM,kCAAkC,CAAC,SAAkC;AACzE,QAAM,YAAY;AAClB,QAAM,QAAQ,UAAU,KAAK,KAAK,IAAK;AACvC,MAAI,CAAC,OAAO;AACV,UAAM,IAAI;AAAA,MACR,0BAA0B,KAAK,IAAI;AAAA,IAAA;AAAA,EAEvC;AAEA,MAAI,KAAK,cAAc,KAAK,sBAAsB;AAChD,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AAEA,MAAI,KAAK,YAAY,KAAK,oBAAoB;AAC5C,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AACF;AAEO,SAAS,yBACd,OACA;AACA,QAAM,QAAQ,+BAA+B;AAC7C,SAAO;AAAA,IACL,sBAAsB;AAAA,EAAA;AAE1B;"}
1
+ {"version":3,"file":"function-declaration-tool.js","sources":["../../../src/tools/function-declaration-tool.ts"],"sourcesContent":["import type { FunctionDeclaration } from '@google/genai'\n\nexport type FunctionDeclarationTool = FunctionDeclaration\n\nconst validateFunctionDeclarationTool = (tool: FunctionDeclarationTool) => {\n const nameRegex = /^[a-zA-Z0-9_:.-]{1,64}$/\n if (tool.name === undefined || !nameRegex.test(tool.name)) {\n throw new Error(\n `Invalid function name: ${tool.name}. Must be 1-64 characters long and contain only a-z, A-Z, 0-9, underscores, colons, dots, and dashes.`,\n )\n }\n\n if (tool.parameters && tool.parametersJsonSchema) {\n throw new Error(\n `FunctionDeclarationTool cannot have both 'parameters' and 'parametersJsonSchema' defined. Please use only one.`,\n )\n }\n\n if (tool.response && tool.responseJsonSchema) {\n throw new Error(\n `FunctionDeclarationTool cannot have both 'response' and 'responseJsonSchema' defined. Please use only one.`,\n )\n }\n}\n\nexport function functionDeclarationTools(\n tools: Array<FunctionDeclarationTool>,\n) {\n tools.forEach(validateFunctionDeclarationTool)\n return {\n functionDeclarations: tools,\n }\n}\n"],"names":[],"mappings":"AAIA,MAAM,kCAAkC,CAAC,SAAkC;AACzE,QAAM,YAAY;AAClB,MAAI,KAAK,SAAS,UAAa,CAAC,UAAU,KAAK,KAAK,IAAI,GAAG;AACzD,UAAM,IAAI;AAAA,MACR,0BAA0B,KAAK,IAAI;AAAA,IAAA;AAAA,EAEvC;AAEA,MAAI,KAAK,cAAc,KAAK,sBAAsB;AAChD,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AAEA,MAAI,KAAK,YAAY,KAAK,oBAAoB;AAC5C,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AACF;AAEO,SAAS,yBACd,OACA;AACA,QAAM,QAAQ,+BAA+B;AAC7C,SAAO;AAAA,IACL,sBAAsB;AAAA,EAAA;AAE1B;"}
@@ -1,3 +1,4 @@
1
+ import { brandProviderTool } from "@tanstack/ai";
1
2
  function convertGoogleMapsToolToAdapterFormat(tool) {
2
3
  const metadata = tool.metadata;
3
4
  return {
@@ -5,11 +6,11 @@ function convertGoogleMapsToolToAdapterFormat(tool) {
5
6
  };
6
7
  }
7
8
  function googleMapsTool(config) {
8
- return {
9
+ return brandProviderTool({
9
10
  name: "google_maps",
10
11
  description: "",
11
12
  metadata: config
12
- };
13
+ });
13
14
  }
14
15
  export {
15
16
  convertGoogleMapsToolToAdapterFormat,
@@ -1 +1 @@
1
- {"version":3,"file":"google-maps-tool.js","sources":["../../../src/tools/google-maps-tool.ts"],"sourcesContent":["import type { GoogleMaps } from '@google/genai'\nimport type { ProviderTool, Tool } from '@tanstack/ai'\n\nexport type GoogleMapsToolConfig = GoogleMaps\n\n/** @deprecated Renamed to `GoogleMapsToolConfig`. Will be removed in a future release. */\nexport type GoogleMapsTool = GoogleMapsToolConfig\n\nexport type GeminiGoogleMapsTool = ProviderTool<'gemini', 'google_maps'>\n\nexport function convertGoogleMapsToolToAdapterFormat(tool: Tool) {\n const metadata = tool.metadata as GoogleMapsToolConfig\n return {\n googleMaps: metadata,\n }\n}\n\nexport function googleMapsTool(\n config?: GoogleMapsToolConfig,\n): GeminiGoogleMapsTool {\n // Phantom-brand cast: '~provider'/'~toolKind' are type-only and never assigned at runtime.\n return {\n name: 'google_maps',\n description: '',\n metadata: config,\n } as unknown as GeminiGoogleMapsTool\n}\n"],"names":[],"mappings":"AAUO,SAAS,qCAAqC,MAAY;AAC/D,QAAM,WAAW,KAAK;AACtB,SAAO;AAAA,IACL,YAAY;AAAA,EAAA;AAEhB;AAEO,SAAS,eACd,QACsB;AAEtB,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aAAa;AAAA,IACb,UAAU;AAAA,EAAA;AAEd;"}
1
+ {"version":3,"file":"google-maps-tool.js","sources":["../../../src/tools/google-maps-tool.ts"],"sourcesContent":["import { brandProviderTool } from '@tanstack/ai'\nimport type { GoogleMaps } from '@google/genai'\nimport type { ProviderTool, Tool } from '@tanstack/ai'\n\nexport type GoogleMapsToolConfig = GoogleMaps\n\n/** @deprecated Renamed to `GoogleMapsToolConfig`. Will be removed in a future release. */\nexport type GoogleMapsTool = GoogleMapsToolConfig\n\nexport type GeminiGoogleMapsTool = ProviderTool<'gemini', 'google_maps'>\n\nexport function convertGoogleMapsToolToAdapterFormat(tool: Tool) {\n const metadata = tool.metadata as GoogleMapsToolConfig\n return {\n googleMaps: metadata,\n }\n}\n\nexport function googleMapsTool(\n config?: GoogleMapsToolConfig,\n): GeminiGoogleMapsTool {\n return brandProviderTool<GeminiGoogleMapsTool>({\n name: 'google_maps',\n description: '',\n metadata: config,\n })\n}\n"],"names":[],"mappings":";AAWO,SAAS,qCAAqC,MAAY;AAC/D,QAAM,WAAW,KAAK;AACtB,SAAO;AAAA,IACL,YAAY;AAAA,EAAA;AAEhB;AAEO,SAAS,eACd,QACsB;AACtB,SAAO,kBAAwC;AAAA,IAC7C,MAAM;AAAA,IACN,aAAa;AAAA,IACb,UAAU;AAAA,EAAA,CACX;AACH;"}
@@ -1,3 +1,4 @@
1
+ import { brandProviderTool } from "@tanstack/ai";
1
2
  function convertGoogleSearchRetrievalToolToAdapterFormat(tool) {
2
3
  const metadata = tool.metadata;
3
4
  return {
@@ -5,11 +6,11 @@ function convertGoogleSearchRetrievalToolToAdapterFormat(tool) {
5
6
  };
6
7
  }
7
8
  function googleSearchRetrievalTool(config) {
8
- return {
9
+ return brandProviderTool({
9
10
  name: "google_search_retrieval",
10
11
  description: "",
11
12
  metadata: config
12
- };
13
+ });
13
14
  }
14
15
  export {
15
16
  convertGoogleSearchRetrievalToolToAdapterFormat,