@tanstack/ai-gemini 0.3.1 → 0.3.2

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.
@@ -87,16 +87,27 @@ class GeminiTextAdapter extends BaseTextAdapter {
87
87
  const parts = chunk.candidates[0].content.parts;
88
88
  for (const part of parts) {
89
89
  if (part.text) {
90
- accumulatedContent += part.text;
91
- yield {
92
- type: "content",
93
- id: generateId(this.name),
94
- model,
95
- timestamp,
96
- delta: part.text,
97
- content: accumulatedContent,
98
- role: "assistant"
99
- };
90
+ if (part.thought) {
91
+ yield {
92
+ type: "thinking",
93
+ content: part.text,
94
+ delta: part.text,
95
+ id: generateId(this.name),
96
+ model,
97
+ timestamp
98
+ };
99
+ } else {
100
+ accumulatedContent += part.text;
101
+ yield {
102
+ type: "content",
103
+ id: generateId(this.name),
104
+ model,
105
+ timestamp,
106
+ delta: part.text,
107
+ content: accumulatedContent,
108
+ role: "assistant"
109
+ };
110
+ }
100
111
  }
101
112
  const functionCall = part.functionCall;
102
113
  if (functionCall) {
@@ -297,17 +308,24 @@ class GeminiTextAdapter extends BaseTextAdapter {
297
308
  });
298
309
  }
299
310
  mapCommonOptionsToGemini(options) {
300
- const providerOpts = options.modelOptions;
311
+ const modelOpts = options.modelOptions;
312
+ const thinkingConfig = modelOpts?.thinkingConfig;
301
313
  const requestOptions = {
302
314
  model: options.model,
303
315
  contents: this.formatMessages(options.messages),
304
316
  config: {
305
- ...providerOpts,
317
+ ...modelOpts,
306
318
  temperature: options.temperature,
307
319
  topP: options.topP,
308
320
  maxOutputTokens: options.maxTokens,
321
+ thinkingConfig: thinkingConfig ? {
322
+ ...thinkingConfig,
323
+ thinkingLevel: thinkingConfig.thinkingLevel ? (
324
+ // Enum is provided by the SDK, we use it for the type but cast it to string constants, here we just cast them back
325
+ thinkingConfig.thinkingLevel
326
+ ) : void 0
327
+ } : void 0,
309
328
  systemInstruction: options.systemPrompts?.join("\n"),
310
- ...providerOpts?.generationConfig,
311
329
  tools: convertToolsToProviderFormat(options.tools)
312
330
  }
313
331
  };
@@ -1 +1 @@
1
- {"version":3,"file":"text.js","sources":["../../../src/adapters/text.ts"],"sourcesContent":["import { FinishReason } from '@google/genai'\nimport { BaseTextAdapter } from '@tanstack/ai/adapters'\nimport { convertToolsToProviderFormat } from '../tools/tool-converter'\nimport {\n createGeminiClient,\n generateId,\n getGeminiApiKeyFromEnv,\n} from '../utils'\nimport type {\n GEMINI_MODELS,\n GeminiChatModelProviderOptionsByName,\n GeminiModelInputModalitiesByName,\n} from '../model-meta'\nimport type {\n StructuredOutputOptions,\n StructuredOutputResult,\n} from '@tanstack/ai/adapters'\nimport type {\n GenerateContentParameters,\n GenerateContentResponse,\n GoogleGenAI,\n Part,\n} from '@google/genai'\nimport type {\n ContentPart,\n Modality,\n ModelMessage,\n StreamChunk,\n TextOptions,\n} from '@tanstack/ai'\nimport type { ExternalTextProviderOptions } from '../text/text-provider-options'\nimport type {\n GeminiAudioMetadata,\n GeminiDocumentMetadata,\n GeminiImageMetadata,\n GeminiMessageMetadataByModality,\n GeminiVideoMetadata,\n} from '../message-types'\nimport type { GeminiClientConfig } from '../utils'\n\n/**\n * Configuration for Gemini text adapter\n */\nexport interface GeminiTextConfig extends GeminiClientConfig {}\n\n/**\n * Gemini-specific provider options for text/chat\n */\nexport type GeminiTextProviderOptions = ExternalTextProviderOptions\n\n// ===========================\n// Type Resolution Helpers\n// ===========================\n\n/**\n * Resolve provider options for a specific model.\n * If the model has explicit options in the map, use those; otherwise use base options.\n */\ntype ResolveProviderOptions<TModel extends string> =\n TModel extends keyof GeminiChatModelProviderOptionsByName\n ? GeminiChatModelProviderOptionsByName[TModel]\n : GeminiTextProviderOptions\n\n/**\n * Resolve input modalities for a specific model.\n * If the model has explicit modalities in the map, use those; otherwise use all modalities.\n */\ntype ResolveInputModalities<TModel extends string> =\n TModel extends keyof GeminiModelInputModalitiesByName\n ? GeminiModelInputModalitiesByName[TModel]\n : readonly ['text', 'image', 'audio', 'video', 'document']\n\n// ===========================\n// Adapter Implementation\n// ===========================\n\n/**\n * Gemini Text (Chat) Adapter\n *\n * Tree-shakeable adapter for Gemini chat/text completion functionality.\n * Import only what you need for smaller bundle sizes.\n */\nexport class GeminiTextAdapter<\n TModel extends (typeof GEMINI_MODELS)[number],\n TProviderOptions extends object = ResolveProviderOptions<TModel>,\n TInputModalities extends ReadonlyArray<Modality> =\n ResolveInputModalities<TModel>,\n> extends BaseTextAdapter<\n TModel,\n TProviderOptions,\n TInputModalities,\n GeminiMessageMetadataByModality\n> {\n readonly kind = 'text' as const\n readonly name = 'gemini' as const\n\n private client: GoogleGenAI\n\n constructor(config: GeminiTextConfig, model: TModel) {\n super({}, model)\n this.client = createGeminiClient(config)\n }\n\n async *chatStream(\n options: TextOptions<GeminiTextProviderOptions>,\n ): AsyncIterable<StreamChunk> {\n const mappedOptions = this.mapCommonOptionsToGemini(options)\n\n try {\n const result =\n await this.client.models.generateContentStream(mappedOptions)\n\n yield* this.processStreamChunks(result, options.model)\n } catch (error) {\n const timestamp = Date.now()\n yield {\n type: 'error',\n id: generateId(this.name),\n model: options.model,\n timestamp,\n error: {\n message:\n error instanceof Error\n ? error.message\n : 'An unknown error occurred during the chat stream.',\n },\n }\n }\n }\n\n /**\n * Generate structured output using Gemini's native JSON response format.\n * Uses responseMimeType: 'application/json' and responseSchema for structured output.\n * The outputSchema is already JSON Schema (converted in the ai layer).\n */\n async structuredOutput(\n options: StructuredOutputOptions<GeminiTextProviderOptions>,\n ): Promise<StructuredOutputResult<unknown>> {\n const { chatOptions, outputSchema } = options\n\n const mappedOptions = this.mapCommonOptionsToGemini(chatOptions)\n\n try {\n // Add structured output configuration\n const result = await this.client.models.generateContent({\n ...mappedOptions,\n config: {\n ...mappedOptions.config,\n responseMimeType: 'application/json',\n responseSchema: outputSchema,\n },\n })\n\n // Extract text content from the response\n const rawText = this.extractTextFromResponse(result)\n\n // Parse the JSON response\n let parsed: unknown\n try {\n parsed = JSON.parse(rawText)\n } catch {\n throw new Error(\n `Failed to parse structured output as JSON. Content: ${rawText.slice(0, 200)}${rawText.length > 200 ? '...' : ''}`,\n )\n }\n\n return {\n data: parsed,\n rawText,\n }\n } catch (error) {\n throw new Error(\n error instanceof Error\n ? error.message\n : 'An unknown error occurred during structured output generation.',\n )\n }\n }\n\n /**\n * Extract text content from a non-streaming response\n */\n private extractTextFromResponse(response: GenerateContentResponse): string {\n let textContent = ''\n\n if (response.candidates?.[0]?.content?.parts) {\n for (const part of response.candidates[0].content.parts) {\n if (part.text) {\n textContent += part.text\n }\n }\n }\n\n return textContent\n }\n\n private async *processStreamChunks(\n result: AsyncGenerator<GenerateContentResponse, unknown, unknown>,\n model: string,\n ): AsyncIterable<StreamChunk> {\n const timestamp = Date.now()\n let accumulatedContent = ''\n const toolCallMap = new Map<\n string,\n { name: string; args: string; index: number }\n >()\n let nextToolIndex = 0\n\n for await (const chunk of result) {\n if (chunk.candidates?.[0]?.content?.parts) {\n const parts = chunk.candidates[0].content.parts\n\n for (const part of parts) {\n if (part.text) {\n accumulatedContent += part.text\n yield {\n type: 'content',\n id: generateId(this.name),\n model,\n timestamp,\n delta: part.text,\n content: accumulatedContent,\n role: 'assistant',\n }\n }\n\n const functionCall = part.functionCall\n if (functionCall) {\n const toolCallId =\n functionCall.id ||\n `${functionCall.name}_${Date.now()}_${nextToolIndex}`\n const functionArgs = functionCall.args || {}\n\n let toolCallData = toolCallMap.get(toolCallId)\n if (!toolCallData) {\n toolCallData = {\n name: functionCall.name || '',\n args:\n typeof functionArgs === 'string'\n ? functionArgs\n : JSON.stringify(functionArgs),\n index: nextToolIndex++,\n }\n toolCallMap.set(toolCallId, toolCallData)\n } else {\n try {\n const existingArgs = JSON.parse(toolCallData.args)\n const newArgs =\n typeof functionArgs === 'string'\n ? JSON.parse(functionArgs)\n : functionArgs\n const mergedArgs = { ...existingArgs, ...newArgs }\n toolCallData.args = JSON.stringify(mergedArgs)\n } catch {\n toolCallData.args =\n typeof functionArgs === 'string'\n ? functionArgs\n : JSON.stringify(functionArgs)\n }\n }\n\n yield {\n type: 'tool_call',\n id: generateId(this.name),\n model,\n timestamp,\n toolCall: {\n id: toolCallId,\n type: 'function',\n function: {\n name: toolCallData.name,\n arguments: toolCallData.args,\n },\n },\n index: toolCallData.index,\n }\n }\n }\n } else if (chunk.data) {\n accumulatedContent += chunk.data\n yield {\n type: 'content',\n id: generateId(this.name),\n model,\n timestamp,\n delta: chunk.data,\n content: accumulatedContent,\n role: 'assistant',\n }\n }\n\n if (chunk.candidates?.[0]?.finishReason) {\n const finishReason = chunk.candidates[0].finishReason\n\n if (finishReason === FinishReason.UNEXPECTED_TOOL_CALL) {\n if (chunk.candidates[0].content?.parts) {\n for (const part of chunk.candidates[0].content.parts) {\n const functionCall = part.functionCall\n if (functionCall) {\n const toolCallId =\n functionCall.id ||\n `${functionCall.name}_${Date.now()}_${nextToolIndex}`\n const functionArgs = functionCall.args || {}\n\n toolCallMap.set(toolCallId, {\n name: functionCall.name || '',\n args:\n typeof functionArgs === 'string'\n ? functionArgs\n : JSON.stringify(functionArgs),\n index: nextToolIndex++,\n })\n\n yield {\n type: 'tool_call',\n id: generateId(this.name),\n model,\n timestamp,\n toolCall: {\n id: toolCallId,\n type: 'function',\n function: {\n name: functionCall.name || '',\n arguments:\n typeof functionArgs === 'string'\n ? functionArgs\n : JSON.stringify(functionArgs),\n },\n },\n index: nextToolIndex - 1,\n }\n }\n }\n }\n }\n if (finishReason === FinishReason.MAX_TOKENS) {\n yield {\n type: 'error',\n id: generateId(this.name),\n model,\n timestamp,\n error: {\n message:\n 'The response was cut off because the maximum token limit was reached.',\n },\n }\n }\n\n yield {\n type: 'done',\n id: generateId(this.name),\n model,\n timestamp,\n finishReason: toolCallMap.size > 0 ? 'tool_calls' : 'stop',\n usage: chunk.usageMetadata\n ? {\n promptTokens: chunk.usageMetadata.promptTokenCount ?? 0,\n completionTokens: chunk.usageMetadata.candidatesTokenCount ?? 0,\n totalTokens: chunk.usageMetadata.totalTokenCount ?? 0,\n }\n : undefined,\n }\n }\n }\n }\n\n private convertContentPartToGemini(part: ContentPart): Part {\n const getDefaultFileType = (\n part: 'image' | 'audio' | 'video' | 'document',\n ) => {\n switch (part) {\n case 'image':\n return 'image/jpeg'\n case 'audio':\n return 'audio/mp3'\n case 'video':\n return 'video/mp4'\n case 'document':\n return 'application/pdf'\n }\n }\n switch (part.type) {\n case 'text':\n return { text: part.content }\n case 'image':\n case 'audio':\n case 'video':\n case 'document': {\n const metadata = part.metadata as\n | GeminiDocumentMetadata\n | GeminiImageMetadata\n | GeminiVideoMetadata\n | GeminiAudioMetadata\n | undefined\n if (part.source.type === 'data') {\n return {\n inlineData: {\n data: part.source.value,\n mimeType: metadata?.mimeType ?? getDefaultFileType(part.type),\n },\n }\n } else {\n return {\n fileData: {\n fileUri: part.source.value,\n mimeType: metadata?.mimeType ?? getDefaultFileType(part.type),\n },\n }\n }\n }\n default: {\n const _exhaustiveCheck: never = part\n throw new Error(\n `Unsupported content part type: ${(_exhaustiveCheck as ContentPart).type}`,\n )\n }\n }\n }\n\n private formatMessages(\n messages: Array<ModelMessage>,\n ): GenerateContentParameters['contents'] {\n return messages.map((msg) => {\n const role: 'user' | 'model' = msg.role === 'assistant' ? 'model' : 'user'\n const parts: Array<Part> = []\n\n if (Array.isArray(msg.content)) {\n for (const contentPart of msg.content) {\n parts.push(this.convertContentPartToGemini(contentPart))\n }\n } else if (msg.content) {\n parts.push({ text: msg.content })\n }\n\n if (msg.role === 'assistant' && msg.toolCalls?.length) {\n for (const toolCall of msg.toolCalls) {\n let parsedArgs: Record<string, unknown> = {}\n try {\n parsedArgs = toolCall.function.arguments\n ? (JSON.parse(toolCall.function.arguments) as Record<\n string,\n unknown\n >)\n : {}\n } catch {\n parsedArgs = toolCall.function.arguments as unknown as Record<\n string,\n unknown\n >\n }\n\n parts.push({\n functionCall: {\n name: toolCall.function.name,\n args: parsedArgs,\n },\n })\n }\n }\n\n if (msg.role === 'tool' && msg.toolCallId) {\n parts.push({\n functionResponse: {\n name: msg.toolCallId,\n response: {\n content: msg.content || '',\n },\n },\n })\n }\n\n return {\n role,\n parts: parts.length > 0 ? parts : [{ text: '' }],\n }\n })\n }\n\n private mapCommonOptionsToGemini(options: TextOptions) {\n const providerOpts = options.modelOptions\n const requestOptions: GenerateContentParameters = {\n model: options.model,\n contents: this.formatMessages(options.messages),\n config: {\n ...providerOpts,\n temperature: options.temperature,\n topP: options.topP,\n maxOutputTokens: options.maxTokens,\n systemInstruction: options.systemPrompts?.join('\\n'),\n ...((providerOpts as Record<string, unknown> | undefined)\n ?.generationConfig as Record<string, unknown> | undefined),\n tools: convertToolsToProviderFormat(options.tools),\n },\n }\n\n return requestOptions\n }\n}\n\n/**\n * Creates a Gemini text adapter with explicit API key.\n * Type resolution happens here at the call site.\n */\nexport function createGeminiChat<TModel extends (typeof GEMINI_MODELS)[number]>(\n model: TModel,\n apiKey: string,\n config?: Omit<GeminiTextConfig, 'apiKey'>,\n): GeminiTextAdapter<\n TModel,\n ResolveProviderOptions<TModel>,\n ResolveInputModalities<TModel>\n> {\n return new GeminiTextAdapter({ apiKey, ...config }, model)\n}\n\n/**\n * Creates a Gemini text adapter with automatic API key detection.\n * Type resolution happens here at the call site.\n */\nexport function geminiText<TModel extends (typeof GEMINI_MODELS)[number]>(\n model: TModel,\n config?: Omit<GeminiTextConfig, 'apiKey'>,\n): GeminiTextAdapter<\n TModel,\n ResolveProviderOptions<TModel>,\n ResolveInputModalities<TModel>\n> {\n const apiKey = getGeminiApiKeyFromEnv()\n return createGeminiChat(model, apiKey, config)\n}\n"],"names":["part"],"mappings":"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"}
1
+ {"version":3,"file":"text.js","sources":["../../../src/adapters/text.ts"],"sourcesContent":["import { FinishReason } from '@google/genai'\nimport { BaseTextAdapter } from '@tanstack/ai/adapters'\nimport { convertToolsToProviderFormat } from '../tools/tool-converter'\nimport {\n createGeminiClient,\n generateId,\n getGeminiApiKeyFromEnv,\n} from '../utils'\nimport type {\n GEMINI_MODELS,\n GeminiChatModelProviderOptionsByName,\n GeminiModelInputModalitiesByName,\n} from '../model-meta'\nimport type {\n StructuredOutputOptions,\n StructuredOutputResult,\n} from '@tanstack/ai/adapters'\nimport type {\n GenerateContentParameters,\n GenerateContentResponse,\n GoogleGenAI,\n Part,\n ThinkingLevel,\n} from '@google/genai'\nimport type {\n ContentPart,\n Modality,\n ModelMessage,\n StreamChunk,\n TextOptions,\n} from '@tanstack/ai'\nimport type { ExternalTextProviderOptions } from '../text/text-provider-options'\nimport type {\n GeminiAudioMetadata,\n GeminiDocumentMetadata,\n GeminiImageMetadata,\n GeminiMessageMetadataByModality,\n GeminiVideoMetadata,\n} from '../message-types'\nimport type { GeminiClientConfig } from '../utils'\n\n/**\n * Configuration for Gemini text adapter\n */\nexport interface GeminiTextConfig extends GeminiClientConfig {}\n\n/**\n * Gemini-specific provider options for text/chat\n */\nexport type GeminiTextProviderOptions = ExternalTextProviderOptions\n\n// ===========================\n// Type Resolution Helpers\n// ===========================\n\n/**\n * Resolve provider options for a specific model.\n * If the model has explicit options in the map, use those; otherwise use base options.\n */\ntype ResolveProviderOptions<TModel extends string> =\n TModel extends keyof GeminiChatModelProviderOptionsByName\n ? GeminiChatModelProviderOptionsByName[TModel]\n : GeminiTextProviderOptions\n\n/**\n * Resolve input modalities for a specific model.\n * If the model has explicit modalities in the map, use those; otherwise use all modalities.\n */\ntype ResolveInputModalities<TModel extends string> =\n TModel extends keyof GeminiModelInputModalitiesByName\n ? GeminiModelInputModalitiesByName[TModel]\n : readonly ['text', 'image', 'audio', 'video', 'document']\n\n// ===========================\n// Adapter Implementation\n// ===========================\n\n/**\n * Gemini Text (Chat) Adapter\n *\n * Tree-shakeable adapter for Gemini chat/text completion functionality.\n * Import only what you need for smaller bundle sizes.\n */\nexport class GeminiTextAdapter<\n TModel extends (typeof GEMINI_MODELS)[number],\n TProviderOptions extends object = ResolveProviderOptions<TModel>,\n TInputModalities extends ReadonlyArray<Modality> =\n ResolveInputModalities<TModel>,\n> extends BaseTextAdapter<\n TModel,\n TProviderOptions,\n TInputModalities,\n GeminiMessageMetadataByModality\n> {\n readonly kind = 'text' as const\n readonly name = 'gemini' as const\n\n private client: GoogleGenAI\n\n constructor(config: GeminiTextConfig, model: TModel) {\n super({}, model)\n this.client = createGeminiClient(config)\n }\n\n async *chatStream(\n options: TextOptions<GeminiTextProviderOptions>,\n ): AsyncIterable<StreamChunk> {\n const mappedOptions = this.mapCommonOptionsToGemini(options)\n\n try {\n const result =\n await this.client.models.generateContentStream(mappedOptions)\n\n yield* this.processStreamChunks(result, options.model)\n } catch (error) {\n const timestamp = Date.now()\n yield {\n type: 'error',\n id: generateId(this.name),\n model: options.model,\n timestamp,\n error: {\n message:\n error instanceof Error\n ? error.message\n : 'An unknown error occurred during the chat stream.',\n },\n }\n }\n }\n\n /**\n * Generate structured output using Gemini's native JSON response format.\n * Uses responseMimeType: 'application/json' and responseSchema for structured output.\n * The outputSchema is already JSON Schema (converted in the ai layer).\n */\n async structuredOutput(\n options: StructuredOutputOptions<GeminiTextProviderOptions>,\n ): Promise<StructuredOutputResult<unknown>> {\n const { chatOptions, outputSchema } = options\n\n const mappedOptions = this.mapCommonOptionsToGemini(chatOptions)\n\n try {\n // Add structured output configuration\n const result = await this.client.models.generateContent({\n ...mappedOptions,\n config: {\n ...mappedOptions.config,\n responseMimeType: 'application/json',\n responseSchema: outputSchema,\n },\n })\n\n // Extract text content from the response\n const rawText = this.extractTextFromResponse(result)\n\n // Parse the JSON response\n let parsed: unknown\n try {\n parsed = JSON.parse(rawText)\n } catch {\n throw new Error(\n `Failed to parse structured output as JSON. Content: ${rawText.slice(0, 200)}${rawText.length > 200 ? '...' : ''}`,\n )\n }\n\n return {\n data: parsed,\n rawText,\n }\n } catch (error) {\n throw new Error(\n error instanceof Error\n ? error.message\n : 'An unknown error occurred during structured output generation.',\n )\n }\n }\n\n /**\n * Extract text content from a non-streaming response\n */\n private extractTextFromResponse(response: GenerateContentResponse): string {\n let textContent = ''\n\n if (response.candidates?.[0]?.content?.parts) {\n for (const part of response.candidates[0].content.parts) {\n if (part.text) {\n textContent += part.text\n }\n }\n }\n\n return textContent\n }\n\n private async *processStreamChunks(\n result: AsyncGenerator<GenerateContentResponse, unknown, unknown>,\n model: string,\n ): AsyncIterable<StreamChunk> {\n const timestamp = Date.now()\n let accumulatedContent = ''\n const toolCallMap = new Map<\n string,\n { name: string; args: string; index: number }\n >()\n let nextToolIndex = 0\n\n for await (const chunk of result) {\n if (chunk.candidates?.[0]?.content?.parts) {\n const parts = chunk.candidates[0].content.parts\n\n for (const part of parts) {\n if (part.text) {\n if (part.thought) {\n yield {\n type: 'thinking',\n content: part.text,\n delta: part.text,\n id: generateId(this.name),\n model,\n timestamp,\n }\n } else {\n accumulatedContent += part.text\n yield {\n type: 'content',\n id: generateId(this.name),\n model,\n timestamp,\n delta: part.text,\n content: accumulatedContent,\n role: 'assistant',\n }\n }\n }\n\n const functionCall = part.functionCall\n if (functionCall) {\n const toolCallId =\n functionCall.id ||\n `${functionCall.name}_${Date.now()}_${nextToolIndex}`\n const functionArgs = functionCall.args || {}\n\n let toolCallData = toolCallMap.get(toolCallId)\n if (!toolCallData) {\n toolCallData = {\n name: functionCall.name || '',\n args:\n typeof functionArgs === 'string'\n ? functionArgs\n : JSON.stringify(functionArgs),\n index: nextToolIndex++,\n }\n toolCallMap.set(toolCallId, toolCallData)\n } else {\n try {\n const existingArgs = JSON.parse(toolCallData.args)\n const newArgs =\n typeof functionArgs === 'string'\n ? JSON.parse(functionArgs)\n : functionArgs\n const mergedArgs = { ...existingArgs, ...newArgs }\n toolCallData.args = JSON.stringify(mergedArgs)\n } catch {\n toolCallData.args =\n typeof functionArgs === 'string'\n ? functionArgs\n : JSON.stringify(functionArgs)\n }\n }\n\n yield {\n type: 'tool_call',\n id: generateId(this.name),\n model,\n timestamp,\n toolCall: {\n id: toolCallId,\n type: 'function',\n function: {\n name: toolCallData.name,\n arguments: toolCallData.args,\n },\n },\n index: toolCallData.index,\n }\n }\n }\n } else if (chunk.data) {\n accumulatedContent += chunk.data\n yield {\n type: 'content',\n id: generateId(this.name),\n model,\n timestamp,\n delta: chunk.data,\n content: accumulatedContent,\n role: 'assistant',\n }\n }\n\n if (chunk.candidates?.[0]?.finishReason) {\n const finishReason = chunk.candidates[0].finishReason\n\n if (finishReason === FinishReason.UNEXPECTED_TOOL_CALL) {\n if (chunk.candidates[0].content?.parts) {\n for (const part of chunk.candidates[0].content.parts) {\n const functionCall = part.functionCall\n if (functionCall) {\n const toolCallId =\n functionCall.id ||\n `${functionCall.name}_${Date.now()}_${nextToolIndex}`\n const functionArgs = functionCall.args || {}\n\n toolCallMap.set(toolCallId, {\n name: functionCall.name || '',\n args:\n typeof functionArgs === 'string'\n ? functionArgs\n : JSON.stringify(functionArgs),\n index: nextToolIndex++,\n })\n\n yield {\n type: 'tool_call',\n id: generateId(this.name),\n model,\n timestamp,\n toolCall: {\n id: toolCallId,\n type: 'function',\n function: {\n name: functionCall.name || '',\n arguments:\n typeof functionArgs === 'string'\n ? functionArgs\n : JSON.stringify(functionArgs),\n },\n },\n index: nextToolIndex - 1,\n }\n }\n }\n }\n }\n if (finishReason === FinishReason.MAX_TOKENS) {\n yield {\n type: 'error',\n id: generateId(this.name),\n model,\n timestamp,\n error: {\n message:\n 'The response was cut off because the maximum token limit was reached.',\n },\n }\n }\n\n yield {\n type: 'done',\n id: generateId(this.name),\n model,\n timestamp,\n finishReason: toolCallMap.size > 0 ? 'tool_calls' : 'stop',\n usage: chunk.usageMetadata\n ? {\n promptTokens: chunk.usageMetadata.promptTokenCount ?? 0,\n completionTokens: chunk.usageMetadata.candidatesTokenCount ?? 0,\n totalTokens: chunk.usageMetadata.totalTokenCount ?? 0,\n }\n : undefined,\n }\n }\n }\n }\n\n private convertContentPartToGemini(part: ContentPart): Part {\n const getDefaultFileType = (\n part: 'image' | 'audio' | 'video' | 'document',\n ) => {\n switch (part) {\n case 'image':\n return 'image/jpeg'\n case 'audio':\n return 'audio/mp3'\n case 'video':\n return 'video/mp4'\n case 'document':\n return 'application/pdf'\n }\n }\n switch (part.type) {\n case 'text':\n return { text: part.content }\n case 'image':\n case 'audio':\n case 'video':\n case 'document': {\n const metadata = part.metadata as\n | GeminiDocumentMetadata\n | GeminiImageMetadata\n | GeminiVideoMetadata\n | GeminiAudioMetadata\n | undefined\n if (part.source.type === 'data') {\n return {\n inlineData: {\n data: part.source.value,\n mimeType: metadata?.mimeType ?? getDefaultFileType(part.type),\n },\n }\n } else {\n return {\n fileData: {\n fileUri: part.source.value,\n mimeType: metadata?.mimeType ?? getDefaultFileType(part.type),\n },\n }\n }\n }\n default: {\n const _exhaustiveCheck: never = part\n throw new Error(\n `Unsupported content part type: ${(_exhaustiveCheck as ContentPart).type}`,\n )\n }\n }\n }\n\n private formatMessages(\n messages: Array<ModelMessage>,\n ): GenerateContentParameters['contents'] {\n return messages.map((msg) => {\n const role: 'user' | 'model' = msg.role === 'assistant' ? 'model' : 'user'\n const parts: Array<Part> = []\n\n if (Array.isArray(msg.content)) {\n for (const contentPart of msg.content) {\n parts.push(this.convertContentPartToGemini(contentPart))\n }\n } else if (msg.content) {\n parts.push({ text: msg.content })\n }\n\n if (msg.role === 'assistant' && msg.toolCalls?.length) {\n for (const toolCall of msg.toolCalls) {\n let parsedArgs: Record<string, unknown> = {}\n try {\n parsedArgs = toolCall.function.arguments\n ? (JSON.parse(toolCall.function.arguments) as Record<\n string,\n unknown\n >)\n : {}\n } catch {\n parsedArgs = toolCall.function.arguments as unknown as Record<\n string,\n unknown\n >\n }\n\n parts.push({\n functionCall: {\n name: toolCall.function.name,\n args: parsedArgs,\n },\n })\n }\n }\n\n if (msg.role === 'tool' && msg.toolCallId) {\n parts.push({\n functionResponse: {\n name: msg.toolCallId,\n response: {\n content: msg.content || '',\n },\n },\n })\n }\n\n return {\n role,\n parts: parts.length > 0 ? parts : [{ text: '' }],\n }\n })\n }\n\n private mapCommonOptionsToGemini(\n options: TextOptions<GeminiTextProviderOptions>,\n ) {\n const modelOpts = options.modelOptions\n const thinkingConfig = modelOpts?.thinkingConfig\n const requestOptions: GenerateContentParameters = {\n model: options.model,\n contents: this.formatMessages(options.messages),\n config: {\n ...modelOpts,\n temperature: options.temperature,\n topP: options.topP,\n maxOutputTokens: options.maxTokens,\n thinkingConfig: thinkingConfig\n ? {\n ...thinkingConfig,\n thinkingLevel: thinkingConfig.thinkingLevel\n ? // Enum is provided by the SDK, we use it for the type but cast it to string constants, here we just cast them back\n (thinkingConfig.thinkingLevel as ThinkingLevel)\n : undefined,\n }\n : undefined,\n systemInstruction: options.systemPrompts?.join('\\n'),\n tools: convertToolsToProviderFormat(options.tools),\n },\n }\n\n return requestOptions\n }\n}\n\n/**\n * Creates a Gemini text adapter with explicit API key.\n * Type resolution happens here at the call site.\n */\nexport function createGeminiChat<TModel extends (typeof GEMINI_MODELS)[number]>(\n model: TModel,\n apiKey: string,\n config?: Omit<GeminiTextConfig, 'apiKey'>,\n): GeminiTextAdapter<\n TModel,\n ResolveProviderOptions<TModel>,\n ResolveInputModalities<TModel>\n> {\n return new GeminiTextAdapter({ apiKey, ...config }, model)\n}\n\n/**\n * Creates a Gemini text adapter with automatic API key detection.\n * Type resolution happens here at the call site.\n */\nexport function geminiText<TModel extends (typeof GEMINI_MODELS)[number]>(\n model: TModel,\n config?: Omit<GeminiTextConfig, 'apiKey'>,\n): GeminiTextAdapter<\n TModel,\n ResolveProviderOptions<TModel>,\n ResolveInputModalities<TModel>\n> {\n const apiKey = getGeminiApiKeyFromEnv()\n return createGeminiChat(model, apiKey, config)\n}\n"],"names":["part"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { GeminiCachedContentOptions, GeminiGenerationConfigOptions, GeminiSafetyOptions, GeminiStructuredOutputOptions, GeminiThinkingOptions, GeminiToolConfigOptions } from './text/text-provider-options.js';
1
+ import { GeminiCachedContentOptions, GeminiCommonConfigOptions, GeminiSafetyOptions, GeminiStructuredOutputOptions, GeminiThinkingAdvancedOptions, GeminiThinkingOptions, GeminiToolConfigOptions } from './text/text-provider-options.js';
2
2
  declare const GEMINI_3_PRO: {
3
3
  readonly name: "gemini-3-pro-preview";
4
4
  readonly max_input_tokens: 1048576;
@@ -300,15 +300,15 @@ export declare const GEMINI_TTS_MODELS: readonly ["gemini-2.5-flash-preview-tts"
300
300
  export declare const GEMINI_TTS_VOICES: readonly ["Zephyr", "Puck", "Charon", "Kore", "Fenrir", "Leda", "Orus", "Aoede", "Callirrhoe", "Autonoe", "Enceladus", "Iapetus", "Umbriel", "Algieba", "Despina", "Erinome", "Algenib", "Rasalgethi", "Laomedeia", "Achernar", "Alnilam", "Schedar", "Gacrux", "Pulcherrima", "Achird", "Zubenelgenubi", "Vindemiatrix", "Sadachbia", "Sadaltager", "Sulafat"];
301
301
  export type GeminiTTSVoice = (typeof GEMINI_TTS_VOICES)[number];
302
302
  export type GeminiChatModelProviderOptionsByName = {
303
- [GEMINI_3_PRO.name]: GeminiToolConfigOptions & GeminiSafetyOptions & GeminiGenerationConfigOptions & GeminiCachedContentOptions & GeminiStructuredOutputOptions & GeminiThinkingOptions;
304
- [GEMINI_3_FLASH.name]: GeminiToolConfigOptions & GeminiSafetyOptions & GeminiGenerationConfigOptions & GeminiCachedContentOptions & GeminiStructuredOutputOptions & GeminiThinkingOptions;
305
- [GEMINI_2_5_PRO.name]: GeminiToolConfigOptions & GeminiSafetyOptions & GeminiGenerationConfigOptions & GeminiCachedContentOptions & GeminiStructuredOutputOptions & GeminiThinkingOptions;
306
- [GEMINI_2_5_FLASH.name]: GeminiToolConfigOptions & GeminiSafetyOptions & GeminiGenerationConfigOptions & GeminiCachedContentOptions & GeminiStructuredOutputOptions & GeminiThinkingOptions;
307
- [GEMINI_2_5_FLASH_PREVIEW.name]: GeminiToolConfigOptions & GeminiSafetyOptions & GeminiGenerationConfigOptions & GeminiCachedContentOptions & GeminiStructuredOutputOptions & GeminiThinkingOptions;
308
- [GEMINI_2_5_FLASH_LITE.name]: GeminiToolConfigOptions & GeminiSafetyOptions & GeminiGenerationConfigOptions & GeminiCachedContentOptions & GeminiStructuredOutputOptions & GeminiThinkingOptions;
309
- [GEMINI_2_5_FLASH_LITE_PREVIEW.name]: GeminiToolConfigOptions & GeminiSafetyOptions & GeminiGenerationConfigOptions & GeminiCachedContentOptions & GeminiStructuredOutputOptions & GeminiThinkingOptions;
310
- [GEMINI_2_FLASH.name]: GeminiToolConfigOptions & GeminiSafetyOptions & GeminiGenerationConfigOptions & GeminiCachedContentOptions & GeminiStructuredOutputOptions;
311
- [GEMINI_2_FLASH_LITE.name]: GeminiToolConfigOptions & GeminiSafetyOptions & GeminiGenerationConfigOptions & GeminiCachedContentOptions & GeminiStructuredOutputOptions;
303
+ [GEMINI_3_PRO.name]: GeminiToolConfigOptions & GeminiSafetyOptions & GeminiCommonConfigOptions & GeminiCachedContentOptions & GeminiStructuredOutputOptions & GeminiThinkingOptions & GeminiThinkingAdvancedOptions;
304
+ [GEMINI_3_FLASH.name]: GeminiToolConfigOptions & GeminiSafetyOptions & GeminiCommonConfigOptions & GeminiCachedContentOptions & GeminiStructuredOutputOptions & GeminiThinkingOptions & GeminiThinkingAdvancedOptions;
305
+ [GEMINI_2_5_PRO.name]: GeminiToolConfigOptions & GeminiSafetyOptions & GeminiCommonConfigOptions & GeminiCachedContentOptions & GeminiStructuredOutputOptions & GeminiThinkingOptions;
306
+ [GEMINI_2_5_FLASH.name]: GeminiToolConfigOptions & GeminiSafetyOptions & GeminiCommonConfigOptions & GeminiCachedContentOptions & GeminiStructuredOutputOptions & GeminiThinkingOptions;
307
+ [GEMINI_2_5_FLASH_PREVIEW.name]: GeminiToolConfigOptions & GeminiSafetyOptions & GeminiCommonConfigOptions & GeminiCachedContentOptions & GeminiStructuredOutputOptions & GeminiThinkingOptions;
308
+ [GEMINI_2_5_FLASH_LITE.name]: GeminiToolConfigOptions & GeminiSafetyOptions & GeminiCommonConfigOptions & GeminiCachedContentOptions & GeminiStructuredOutputOptions & GeminiThinkingOptions;
309
+ [GEMINI_2_5_FLASH_LITE_PREVIEW.name]: GeminiToolConfigOptions & GeminiSafetyOptions & GeminiCommonConfigOptions & GeminiCachedContentOptions & GeminiStructuredOutputOptions & GeminiThinkingOptions;
310
+ [GEMINI_2_FLASH.name]: GeminiToolConfigOptions & GeminiSafetyOptions & GeminiCommonConfigOptions & GeminiCachedContentOptions & GeminiStructuredOutputOptions;
311
+ [GEMINI_2_FLASH_LITE.name]: GeminiToolConfigOptions & GeminiSafetyOptions & GeminiCommonConfigOptions & GeminiCachedContentOptions & GeminiStructuredOutputOptions;
312
312
  };
313
313
  /**
314
314
  * Type-only map from chat model name to its supported input modalities.
@@ -1 +1 @@
1
- {"version":3,"file":"model-meta.js","sources":["../../src/model-meta.ts"],"sourcesContent":["import type {\n GeminiCachedContentOptions,\n GeminiGenerationConfigOptions,\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 | 'code_execution'\n | 'file_search'\n | 'function_calling'\n | 'grounding_with_gmaps'\n | 'image_generation'\n | 'live_api'\n | 'search_grounding'\n | 'structured_output'\n | 'thinking'\n | 'url_context'\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_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 'code_execution',\n 'file_search',\n 'function_calling',\n 'search_grounding',\n 'structured_output',\n 'thinking',\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 GeminiGenerationConfigOptions &\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 'code_execution',\n 'file_search',\n 'function_calling',\n 'search_grounding',\n 'structured_output',\n 'thinking',\n 'url_context',\n ],\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 GeminiGenerationConfigOptions &\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: [\n 'batch_api',\n 'image_generation',\n 'search_grounding',\n 'structured_output',\n 'thinking',\n ],\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 GeminiGenerationConfigOptions &\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 'code_execution',\n 'file_search',\n 'function_calling',\n 'grounding_with_gmaps',\n 'search_grounding',\n 'structured_output',\n 'thinking',\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 GeminiGenerationConfigOptions &\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', 'file_search'],\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 GeminiGenerationConfigOptions &\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 'code_execution',\n 'file_search',\n 'function_calling',\n 'grounding_with_gmaps',\n 'search_grounding',\n 'structured_output',\n 'thinking',\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 GeminiGenerationConfigOptions &\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 'code_execution',\n 'file_search',\n 'function_calling',\n 'search_grounding',\n 'structured_output',\n 'thinking',\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 GeminiGenerationConfigOptions &\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: [\n 'batch_api',\n 'caching',\n 'file_search',\n 'image_generation',\n 'structured_output',\n ],\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 GeminiGenerationConfigOptions &\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', 'file_search'],\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 GeminiGenerationConfigOptions &\n GeminiCachedContentOptions\n>\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 'code_execution',\n 'function_calling',\n 'grounding_with_gmaps',\n 'search_grounding',\n 'structured_output',\n 'thinking',\n 'url_context',\n ],\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 GeminiGenerationConfigOptions &\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 'code_execution',\n 'function_calling',\n 'search_grounding',\n 'structured_output',\n 'thinking',\n 'url_context',\n ],\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 GeminiGenerationConfigOptions &\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 'code_execution',\n 'function_calling',\n 'grounding_with_gmaps',\n 'live_api',\n 'search_grounding',\n 'structured_output',\n ],\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 GeminiGenerationConfigOptions &\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'],\n capabilities: [\n 'batch_api',\n 'caching',\n 'image_generation',\n 'structured_output',\n ],\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 GeminiGenerationConfigOptions &\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 },\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 GeminiGenerationConfigOptions &\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 GeminiGenerationConfigOptions &\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 GeminiGenerationConfigOptions &\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 GeminiGenerationConfigOptions &\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 GeminiGenerationConfigOptions &\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_PRO.name,\n GEMINI_3_FLASH.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_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_2_5_FLASH_TTS.name,\n GEMINI_2_5_PRO_TTS.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_PRO.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiGenerationConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n [GEMINI_3_FLASH.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiGenerationConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n [GEMINI_2_5_PRO.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiGenerationConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n [GEMINI_2_5_FLASH.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiGenerationConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n [GEMINI_2_5_FLASH_PREVIEW.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiGenerationConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n [GEMINI_2_5_FLASH_LITE.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiGenerationConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n [GEMINI_2_5_FLASH_LITE_PREVIEW.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiGenerationConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n // Models with structured output but no thinking support\n [GEMINI_2_FLASH.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiGenerationConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions\n [GEMINI_2_FLASH_LITE.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiGenerationConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions\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_PRO.name]: typeof GEMINI_3_PRO.supports.input\n [GEMINI_3_FLASH.name]: typeof GEMINI_3_FLASH.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":"AAgDA,MAAM,eAAe;AAAA,EACnB,MAAM;AA2BR;AASA,MAAM,iBAAiB;AAAA,EACrB,MAAM;AA2BR;AASA,MAAM,qBAAqB;AAAA,EACzB,MAAM;AAuBR;AASA,MAAM,iBAAiB;AAAA,EACrB,MAAM;AA4BR;AASA,MAAM,qBAAqB;AAAA,EACzB,MAAM;AAiBR;AAOA,MAAM,mBAAmB;AAAA,EACvB,MAAM;AA4BR;AASA,MAAM,2BAA2B;AAAA,EAC/B,MAAM;AA2BR;AASA,MAAM,yBAAyB;AAAA,EAC7B,MAAM;AAuBR;AAyCA,MAAM,uBAAuB;AAAA,EAC3B,MAAM;AAiBR;AAOA,MAAM,wBAAwB;AAAA,EAC5B,MAAM;AA2BR;AASA,MAAM,gCAAgC;AAAA,EACpC,MAAM;AA0BR;AASA,MAAM,iBAAiB;AAAA,EACrB,MAAM;AA0BR;AAQA,MAAM,uBAAuB;AAAA,EAC3B,MAAM;AAsBR;AAyCA,MAAM,sBAAsB;AAAA,EAC1B,MAAM;AAsBR;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,aAAa;AAAA,EACb,eAAe;AAAA,EACf,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,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,mBAAmB;AACrB;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 GeminiThinkingAdvancedOptions,\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 | 'code_execution'\n | 'file_search'\n | 'function_calling'\n | 'grounding_with_gmaps'\n | 'image_generation'\n | 'live_api'\n | 'search_grounding'\n | 'structured_output'\n | 'thinking'\n | 'url_context'\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_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 'code_execution',\n 'file_search',\n 'function_calling',\n 'search_grounding',\n 'structured_output',\n 'thinking',\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 GeminiThinkingAdvancedOptions\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 'code_execution',\n 'file_search',\n 'function_calling',\n 'search_grounding',\n 'structured_output',\n 'thinking',\n 'url_context',\n ],\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 GeminiThinkingAdvancedOptions\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: [\n 'batch_api',\n 'image_generation',\n 'search_grounding',\n 'structured_output',\n 'thinking',\n ],\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 GeminiThinkingAdvancedOptions\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 'code_execution',\n 'file_search',\n 'function_calling',\n 'grounding_with_gmaps',\n 'search_grounding',\n 'structured_output',\n 'thinking',\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', 'file_search'],\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 'code_execution',\n 'file_search',\n 'function_calling',\n 'grounding_with_gmaps',\n 'search_grounding',\n 'structured_output',\n 'thinking',\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 'code_execution',\n 'file_search',\n 'function_calling',\n 'search_grounding',\n 'structured_output',\n 'thinking',\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_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: [\n 'batch_api',\n 'caching',\n 'file_search',\n 'image_generation',\n 'structured_output',\n ],\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', 'file_search'],\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\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 'code_execution',\n 'function_calling',\n 'grounding_with_gmaps',\n 'search_grounding',\n 'structured_output',\n 'thinking',\n 'url_context',\n ],\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 'code_execution',\n 'function_calling',\n 'search_grounding',\n 'structured_output',\n 'thinking',\n 'url_context',\n ],\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 'code_execution',\n 'function_calling',\n 'grounding_with_gmaps',\n 'live_api',\n 'search_grounding',\n 'structured_output',\n ],\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'],\n capabilities: [\n 'batch_api',\n 'caching',\n 'image_generation',\n 'structured_output',\n ],\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 },\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_PRO.name,\n GEMINI_3_FLASH.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_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_2_5_FLASH_TTS.name,\n GEMINI_2_5_PRO_TTS.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_PRO.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions &\n GeminiThinkingAdvancedOptions\n [GEMINI_3_FLASH.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions &\n GeminiThinkingAdvancedOptions\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 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_PRO.name]: typeof GEMINI_3_PRO.supports.input\n [GEMINI_3_FLASH.name]: typeof GEMINI_3_FLASH.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":"AAiDA,MAAM,eAAe;AAAA,EACnB,MAAM;AA2BR;AAUA,MAAM,iBAAiB;AAAA,EACrB,MAAM;AA2BR;AAUA,MAAM,qBAAqB;AAAA,EACzB,MAAM;AAuBR;AAUA,MAAM,iBAAiB;AAAA,EACrB,MAAM;AA4BR;AASA,MAAM,qBAAqB;AAAA,EACzB,MAAM;AAiBR;AAOA,MAAM,mBAAmB;AAAA,EACvB,MAAM;AA4BR;AASA,MAAM,2BAA2B;AAAA,EAC/B,MAAM;AA2BR;AASA,MAAM,yBAAyB;AAAA,EAC7B,MAAM;AAuBR;AAyCA,MAAM,uBAAuB;AAAA,EAC3B,MAAM;AAiBR;AAOA,MAAM,wBAAwB;AAAA,EAC5B,MAAM;AA2BR;AASA,MAAM,gCAAgC;AAAA,EACpC,MAAM;AA0BR;AASA,MAAM,iBAAiB;AAAA,EACrB,MAAM;AA0BR;AAQA,MAAM,uBAAuB;AAAA,EAC3B,MAAM;AAsBR;AAyCA,MAAM,sBAAsB;AAAA,EAC1B,MAAM;AAsBR;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,aAAa;AAAA,EACb,eAAe;AAAA,EACf,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,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,mBAAmB;AACrB;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;"}
@@ -13,104 +13,102 @@ export interface GeminiSafetyOptions {
13
13
  */
14
14
  safetySettings?: Array<SafetySetting>;
15
15
  }
16
- export interface GeminiGenerationConfigOptions {
16
+ export interface GeminiCommonConfigOptions {
17
17
  /**
18
18
  * Configuration options for model generation and outputs.
19
19
  */
20
- generationConfig?: {
21
- /**
22
- * The set of character sequences (up to 5) that will stop output generation. If specified, the API will stop at the first appearance of a stop_sequence. The stop sequence will not be included as part of the response.
23
- */
24
- stopSequences?: Array<string>;
25
- /**
26
- * The requested modalities of the response. Represents the set of modalities that the model can return, and should be expected in the response. This is an exact match to the modalities of the response.
27
-
28
- A model may have multiple combinations of supported modalities. If the requested modalities do not match any of the supported combinations, an error will be returned.
29
- */
30
- responseModalities?: Array<'MODALITY_UNSPECIFIED' | 'TEXT' | 'IMAGE' | 'AUDIO'>;
31
- /**
32
- * Number of generated responses to return. If unset, this will default to 1. Please note that this doesn't work for previous generation models (Gemini 1.0 family)
33
- */
34
- candidateCount?: number;
35
- /**
36
- * The maximum number of tokens to consider when sampling.
37
-
38
- Gemini models use Top-p (nucleus) sampling or a combination of Top-k and nucleus sampling. Top-k sampling considers the set of topK most probable tokens. Models running with nucleus sampling don't allow topK setting.
39
-
40
- Note: The default value varies by Model and is specified by theModel.top_p attribute returned from the getModel function. An empty topK attribute indicates that the model doesn't apply top-k sampling and doesn't allow setting topK on requests.
41
- */
42
- topK?: number;
43
- /**
44
- * Seed used in decoding. If not set, the request uses a randomly generated seed.
45
- */
46
- seed?: number;
47
- /**
48
- * Presence penalty applied to the next token's logprobs if the token has already been seen in the response.
49
-
50
- This penalty is binary on/off and not dependant on the number of times the token is used (after the first). Use frequencyPenalty for a penalty that increases with each use.
51
-
52
- A positive penalty will discourage the use of tokens that have already been used in the response, increasing the vocabulary.
53
-
54
- A negative penalty will encourage the use of tokens that have already been used in the response, decreasing the vocabulary.
55
- */
56
- presencePenalty?: number;
57
- /**
58
- * Frequency penalty applied to the next token's logprobs, multiplied by the number of times each token has been seen in the respponse so far.
59
-
60
- A positive penalty will discourage the use of tokens that have already been used, proportional to the number of times the token has been used: The more a token is used, the more difficult it is for the model to use that token again increasing the vocabulary of responses.
61
-
62
- Caution: A negative penalty will encourage the model to reuse tokens proportional to the number of times the token has been used. Small negative values will reduce the vocabulary of a response. Larger negative values will cause the model to start repeating a common token until it hits the maxOutputTokens limit.
63
- */
64
- frequencyPenalty?: number;
65
- /**
66
- * If true, export the logprobs results in response.
67
- */
68
- responseLogprobs?: boolean;
69
- /**
70
- * Only valid if responseLogprobs=True. This sets the number of top logprobs to return at each decoding step in the Candidate.logprobs_result. The number must be in the range of [0, 20].
71
- */
72
- logprobs?: number;
73
- /**
74
- * Enables enhanced civic answers. It may not be available for all models.
75
- */
76
- enableEnhancedCivicAnswers?: boolean;
77
- /**
78
- * The speech generation config.
79
- */
80
- speechConfig?: {
81
- voiceConfig: {
82
- prebuiltVoiceConfig: {
83
- voiceName: string;
84
- };
85
- };
86
- multiSpeakerVoiceConfig?: {
87
- speakerVoiceConfigs?: Array<{
88
- speaker: string;
89
- voiceConfig: {
90
- prebuiltVoiceConfig: {
91
- voiceName: string;
92
- };
93
- };
94
- }>;
20
+ /**
21
+ * The set of character sequences (up to 5) that will stop output generation. If specified, the API will stop at the first appearance of a stop_sequence. The stop sequence will not be included as part of the response.
22
+ */
23
+ stopSequences?: Array<string>;
24
+ /**
25
+ * The requested modalities of the response. Represents the set of modalities that the model can return, and should be expected in the response. This is an exact match to the modalities of the response.
26
+
27
+ A model may have multiple combinations of supported modalities. If the requested modalities do not match any of the supported combinations, an error will be returned.
28
+ */
29
+ responseModalities?: Array<'MODALITY_UNSPECIFIED' | 'TEXT' | 'IMAGE' | 'AUDIO'>;
30
+ /**
31
+ * Number of generated responses to return. If unset, this will default to 1. Please note that this doesn't work for previous generation models (Gemini 1.0 family)
32
+ */
33
+ candidateCount?: number;
34
+ /**
35
+ * The maximum number of tokens to consider when sampling.
36
+
37
+ Gemini models use Top-p (nucleus) sampling or a combination of Top-k and nucleus sampling. Top-k sampling considers the set of topK most probable tokens. Models running with nucleus sampling don't allow topK setting.
38
+
39
+ Note: The default value varies by Model and is specified by theModel.top_p attribute returned from the getModel function. An empty topK attribute indicates that the model doesn't apply top-k sampling and doesn't allow setting topK on requests.
40
+ */
41
+ topK?: number;
42
+ /**
43
+ * Seed used in decoding. If not set, the request uses a randomly generated seed.
44
+ */
45
+ seed?: number;
46
+ /**
47
+ * Presence penalty applied to the next token's logprobs if the token has already been seen in the response.
48
+
49
+ This penalty is binary on/off and not dependant on the number of times the token is used (after the first). Use frequencyPenalty for a penalty that increases with each use.
50
+
51
+ A positive penalty will discourage the use of tokens that have already been used in the response, increasing the vocabulary.
52
+
53
+ A negative penalty will encourage the use of tokens that have already been used in the response, decreasing the vocabulary.
54
+ */
55
+ presencePenalty?: number;
56
+ /**
57
+ * Frequency penalty applied to the next token's logprobs, multiplied by the number of times each token has been seen in the respponse so far.
58
+
59
+ A positive penalty will discourage the use of tokens that have already been used, proportional to the number of times the token has been used: The more a token is used, the more difficult it is for the model to use that token again increasing the vocabulary of responses.
60
+
61
+ Caution: A negative penalty will encourage the model to reuse tokens proportional to the number of times the token has been used. Small negative values will reduce the vocabulary of a response. Larger negative values will cause the model to start repeating a common token until it hits the maxOutputTokens limit.
62
+ */
63
+ frequencyPenalty?: number;
64
+ /**
65
+ * If true, export the logprobs results in response.
66
+ */
67
+ responseLogprobs?: boolean;
68
+ /**
69
+ * Only valid if responseLogprobs=True. This sets the number of top logprobs to return at each decoding step in the Candidate.logprobs_result. The number must be in the range of [0, 20].
70
+ */
71
+ logprobs?: number;
72
+ /**
73
+ * Enables enhanced civic answers. It may not be available for all models.
74
+ */
75
+ enableEnhancedCivicAnswers?: boolean;
76
+ /**
77
+ * The speech generation config.
78
+ */
79
+ speechConfig?: {
80
+ voiceConfig: {
81
+ prebuiltVoiceConfig: {
82
+ voiceName: string;
95
83
  };
96
- /**
97
- * Language code (in BCP 47 format, e.g. "en-US") for speech synthesis.
98
-
99
- Valid values are: de-DE, en-AU, en-GB, en-IN, en-US, es-US, fr-FR, hi-IN, pt-BR, ar-XA, es-ES, fr-CA, id-ID, it-IT, ja-JP, tr-TR, vi-VN, bn-IN, gu-IN, kn-IN, ml-IN, mr-IN, ta-IN, te-IN, nl-NL, ko-KR, cmn-CN, pl-PL, ru-RU, and th-TH.
100
- */
101
- languageCode?: 'de-DE' | 'en-AU' | 'en-GB' | 'en-IN' | 'en-US' | 'es-US' | 'fr-FR' | 'hi-IN' | 'pt-BR' | 'ar-XA' | 'es-ES' | 'fr-CA' | 'id-ID' | 'it-IT' | 'ja-JP' | 'tr-TR' | 'vi-VN' | 'bn-IN' | 'gu-IN' | 'kn-IN' | 'ml-IN' | 'mr-IN' | 'ta-IN' | 'te-IN' | 'nl-NL' | 'ko-KR' | 'cmn-CN' | 'pl-PL' | 'ru-RU' | 'th-TH';
102
84
  };
103
- /**
104
- * Config for image generation. An error will be returned if this field is set for models that don't support these config options.
105
- */
106
- imageConfig?: {
107
- aspectRatio?: '1:1' | '2:3' | '3:2' | '3:4' | '4:3' | '9:16' | '16:9' | '21:9';
85
+ multiSpeakerVoiceConfig?: {
86
+ speakerVoiceConfigs?: Array<{
87
+ speaker: string;
88
+ voiceConfig: {
89
+ prebuiltVoiceConfig: {
90
+ voiceName: string;
91
+ };
92
+ };
93
+ }>;
108
94
  };
109
95
  /**
110
- * If specified, the media resolution specified will be used.
111
- */
112
- mediaResolution?: MediaResolution;
113
- } & GeminiThinkingOptions & GeminiStructuredOutputOptions;
96
+ * Language code (in BCP 47 format, e.g. "en-US") for speech synthesis.
97
+
98
+ Valid values are: de-DE, en-AU, en-GB, en-IN, en-US, es-US, fr-FR, hi-IN, pt-BR, ar-XA, es-ES, fr-CA, id-ID, it-IT, ja-JP, tr-TR, vi-VN, bn-IN, gu-IN, kn-IN, ml-IN, mr-IN, ta-IN, te-IN, nl-NL, ko-KR, cmn-CN, pl-PL, ru-RU, and th-TH.
99
+ */
100
+ languageCode?: 'de-DE' | 'en-AU' | 'en-GB' | 'en-IN' | 'en-US' | 'es-US' | 'fr-FR' | 'hi-IN' | 'pt-BR' | 'ar-XA' | 'es-ES' | 'fr-CA' | 'id-ID' | 'it-IT' | 'ja-JP' | 'tr-TR' | 'vi-VN' | 'bn-IN' | 'gu-IN' | 'kn-IN' | 'ml-IN' | 'mr-IN' | 'ta-IN' | 'te-IN' | 'nl-NL' | 'ko-KR' | 'cmn-CN' | 'pl-PL' | 'ru-RU' | 'th-TH';
101
+ };
102
+ /**
103
+ * Config for image generation. An error will be returned if this field is set for models that don't support these config options.
104
+ */
105
+ imageConfig?: {
106
+ aspectRatio?: '1:1' | '2:3' | '3:2' | '3:4' | '4:3' | '9:16' | '16:9' | '21:9';
107
+ };
108
+ /**
109
+ * If specified, the media resolution specified will be used.
110
+ */
111
+ mediaResolution?: MediaResolution;
114
112
  }
115
113
  export interface GeminiCachedContentOptions {
116
114
  /**
@@ -174,11 +172,18 @@ export interface GeminiThinkingOptions {
174
172
  /**
175
173
  * The number of thoughts tokens that the model should generate.
176
174
  */
177
- thinkingBudget: number;
175
+ thinkingBudget?: number;
176
+ };
177
+ }
178
+ export interface GeminiThinkingAdvancedOptions {
179
+ /**
180
+ * Config for thinking features. An error will be returned if this field is set for models that don't support thinking.
181
+ */
182
+ thinkingConfig?: {
178
183
  /**
179
184
  * The level of thoughts tokens that the model should generate.
180
185
  */
181
- thinkingLevel?: ThinkingLevel;
186
+ thinkingLevel?: keyof typeof ThinkingLevel;
182
187
  };
183
188
  }
184
- export type ExternalTextProviderOptions = GeminiToolConfigOptions & GeminiSafetyOptions & GeminiGenerationConfigOptions & GeminiCachedContentOptions;
189
+ export type ExternalTextProviderOptions = GeminiToolConfigOptions & GeminiSafetyOptions & GeminiCommonConfigOptions & GeminiCachedContentOptions & GeminiThinkingOptions & GeminiThinkingAdvancedOptions & GeminiStructuredOutputOptions;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/ai-gemini",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Google Gemini adapter for TanStack AI",
5
5
  "author": "",
6
6
  "license": "MIT",
@@ -33,12 +33,12 @@
33
33
  "@google/genai": "^1.30.0"
34
34
  },
35
35
  "peerDependencies": {
36
- "@tanstack/ai": "^0.2.1"
36
+ "@tanstack/ai": "^0.2.2"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@vitest/coverage-v8": "4.0.14",
40
40
  "vite": "^7.2.7",
41
- "@tanstack/ai": "0.2.1"
41
+ "@tanstack/ai": "0.2.2"
42
42
  },
43
43
  "scripts": {
44
44
  "build": "vite build",
@@ -20,6 +20,7 @@ import type {
20
20
  GenerateContentResponse,
21
21
  GoogleGenAI,
22
22
  Part,
23
+ ThinkingLevel,
23
24
  } from '@google/genai'
24
25
  import type {
25
26
  ContentPart,
@@ -212,15 +213,26 @@ export class GeminiTextAdapter<
212
213
 
213
214
  for (const part of parts) {
214
215
  if (part.text) {
215
- accumulatedContent += part.text
216
- yield {
217
- type: 'content',
218
- id: generateId(this.name),
219
- model,
220
- timestamp,
221
- delta: part.text,
222
- content: accumulatedContent,
223
- role: 'assistant',
216
+ if (part.thought) {
217
+ yield {
218
+ type: 'thinking',
219
+ content: part.text,
220
+ delta: part.text,
221
+ id: generateId(this.name),
222
+ model,
223
+ timestamp,
224
+ }
225
+ } else {
226
+ accumulatedContent += part.text
227
+ yield {
228
+ type: 'content',
229
+ id: generateId(this.name),
230
+ model,
231
+ timestamp,
232
+ delta: part.text,
233
+ content: accumulatedContent,
234
+ role: 'assistant',
235
+ }
224
236
  }
225
237
  }
226
238
 
@@ -476,19 +488,29 @@ export class GeminiTextAdapter<
476
488
  })
477
489
  }
478
490
 
479
- private mapCommonOptionsToGemini(options: TextOptions) {
480
- const providerOpts = options.modelOptions
491
+ private mapCommonOptionsToGemini(
492
+ options: TextOptions<GeminiTextProviderOptions>,
493
+ ) {
494
+ const modelOpts = options.modelOptions
495
+ const thinkingConfig = modelOpts?.thinkingConfig
481
496
  const requestOptions: GenerateContentParameters = {
482
497
  model: options.model,
483
498
  contents: this.formatMessages(options.messages),
484
499
  config: {
485
- ...providerOpts,
500
+ ...modelOpts,
486
501
  temperature: options.temperature,
487
502
  topP: options.topP,
488
503
  maxOutputTokens: options.maxTokens,
504
+ thinkingConfig: thinkingConfig
505
+ ? {
506
+ ...thinkingConfig,
507
+ thinkingLevel: thinkingConfig.thinkingLevel
508
+ ? // Enum is provided by the SDK, we use it for the type but cast it to string constants, here we just cast them back
509
+ (thinkingConfig.thinkingLevel as ThinkingLevel)
510
+ : undefined,
511
+ }
512
+ : undefined,
489
513
  systemInstruction: options.systemPrompts?.join('\n'),
490
- ...((providerOpts as Record<string, unknown> | undefined)
491
- ?.generationConfig as Record<string, unknown> | undefined),
492
514
  tools: convertToolsToProviderFormat(options.tools),
493
515
  },
494
516
  }
package/src/model-meta.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import type {
2
2
  GeminiCachedContentOptions,
3
- GeminiGenerationConfigOptions,
3
+ GeminiCommonConfigOptions,
4
4
  GeminiSafetyOptions,
5
5
  GeminiStructuredOutputOptions,
6
+ GeminiThinkingAdvancedOptions,
6
7
  GeminiThinkingOptions,
7
8
  GeminiToolConfigOptions,
8
9
  } from './text/text-provider-options'
@@ -77,10 +78,11 @@ const GEMINI_3_PRO = {
77
78
  } as const satisfies ModelMeta<
78
79
  GeminiToolConfigOptions &
79
80
  GeminiSafetyOptions &
80
- GeminiGenerationConfigOptions &
81
+ GeminiCommonConfigOptions &
81
82
  GeminiCachedContentOptions &
82
83
  GeminiStructuredOutputOptions &
83
- GeminiThinkingOptions
84
+ GeminiThinkingOptions &
85
+ GeminiThinkingAdvancedOptions
84
86
  >
85
87
 
86
88
  const GEMINI_3_FLASH = {
@@ -114,10 +116,11 @@ const GEMINI_3_FLASH = {
114
116
  } as const satisfies ModelMeta<
115
117
  GeminiToolConfigOptions &
116
118
  GeminiSafetyOptions &
117
- GeminiGenerationConfigOptions &
119
+ GeminiCommonConfigOptions &
118
120
  GeminiCachedContentOptions &
119
121
  GeminiStructuredOutputOptions &
120
- GeminiThinkingOptions
122
+ GeminiThinkingOptions &
123
+ GeminiThinkingAdvancedOptions
121
124
  >
122
125
 
123
126
  const GEMINI_3_PRO_IMAGE = {
@@ -147,10 +150,11 @@ const GEMINI_3_PRO_IMAGE = {
147
150
  } as const satisfies ModelMeta<
148
151
  GeminiToolConfigOptions &
149
152
  GeminiSafetyOptions &
150
- GeminiGenerationConfigOptions &
153
+ GeminiCommonConfigOptions &
151
154
  GeminiCachedContentOptions &
152
155
  GeminiStructuredOutputOptions &
153
- GeminiThinkingOptions
156
+ GeminiThinkingOptions &
157
+ GeminiThinkingAdvancedOptions
154
158
  >
155
159
 
156
160
  const GEMINI_2_5_PRO = {
@@ -185,7 +189,7 @@ const GEMINI_2_5_PRO = {
185
189
  } as const satisfies ModelMeta<
186
190
  GeminiToolConfigOptions &
187
191
  GeminiSafetyOptions &
188
- GeminiGenerationConfigOptions &
192
+ GeminiCommonConfigOptions &
189
193
  GeminiCachedContentOptions &
190
194
  GeminiStructuredOutputOptions &
191
195
  GeminiThinkingOptions
@@ -212,7 +216,7 @@ const GEMINI_2_5_PRO_TTS = {
212
216
  } as const satisfies ModelMeta<
213
217
  GeminiToolConfigOptions &
214
218
  GeminiSafetyOptions &
215
- GeminiGenerationConfigOptions &
219
+ GeminiCommonConfigOptions &
216
220
  GeminiCachedContentOptions
217
221
  >
218
222
 
@@ -248,7 +252,7 @@ const GEMINI_2_5_FLASH = {
248
252
  } as const satisfies ModelMeta<
249
253
  GeminiToolConfigOptions &
250
254
  GeminiSafetyOptions &
251
- GeminiGenerationConfigOptions &
255
+ GeminiCommonConfigOptions &
252
256
  GeminiCachedContentOptions &
253
257
  GeminiStructuredOutputOptions &
254
258
  GeminiThinkingOptions
@@ -285,7 +289,7 @@ const GEMINI_2_5_FLASH_PREVIEW = {
285
289
  } as const satisfies ModelMeta<
286
290
  GeminiToolConfigOptions &
287
291
  GeminiSafetyOptions &
288
- GeminiGenerationConfigOptions &
292
+ GeminiCommonConfigOptions &
289
293
  GeminiCachedContentOptions &
290
294
  GeminiStructuredOutputOptions &
291
295
  GeminiThinkingOptions
@@ -318,7 +322,7 @@ const GEMINI_2_5_FLASH_IMAGE = {
318
322
  } as const satisfies ModelMeta<
319
323
  GeminiToolConfigOptions &
320
324
  GeminiSafetyOptions &
321
- GeminiGenerationConfigOptions &
325
+ GeminiCommonConfigOptions &
322
326
  GeminiCachedContentOptions
323
327
  >
324
328
  /**
@@ -377,7 +381,7 @@ const GEMINI_2_5_FLASH_TTS = {
377
381
  } as const satisfies ModelMeta<
378
382
  GeminiToolConfigOptions &
379
383
  GeminiSafetyOptions &
380
- GeminiGenerationConfigOptions &
384
+ GeminiCommonConfigOptions &
381
385
  GeminiCachedContentOptions
382
386
  >
383
387
 
@@ -412,7 +416,7 @@ const GEMINI_2_5_FLASH_LITE = {
412
416
  } as const satisfies ModelMeta<
413
417
  GeminiToolConfigOptions &
414
418
  GeminiSafetyOptions &
415
- GeminiGenerationConfigOptions &
419
+ GeminiCommonConfigOptions &
416
420
  GeminiCachedContentOptions &
417
421
  GeminiStructuredOutputOptions &
418
422
  GeminiThinkingOptions
@@ -448,7 +452,7 @@ const GEMINI_2_5_FLASH_LITE_PREVIEW = {
448
452
  } as const satisfies ModelMeta<
449
453
  GeminiToolConfigOptions &
450
454
  GeminiSafetyOptions &
451
- GeminiGenerationConfigOptions &
455
+ GeminiCommonConfigOptions &
452
456
  GeminiCachedContentOptions &
453
457
  GeminiStructuredOutputOptions &
454
458
  GeminiThinkingOptions
@@ -484,7 +488,7 @@ const GEMINI_2_FLASH = {
484
488
  } as const satisfies ModelMeta<
485
489
  GeminiToolConfigOptions &
486
490
  GeminiSafetyOptions &
487
- GeminiGenerationConfigOptions &
491
+ GeminiCommonConfigOptions &
488
492
  GeminiCachedContentOptions &
489
493
  GeminiStructuredOutputOptions
490
494
  >
@@ -515,7 +519,7 @@ const GEMINI_2_FLASH_IMAGE = {
515
519
  } as const satisfies ModelMeta<
516
520
  GeminiToolConfigOptions &
517
521
  GeminiSafetyOptions &
518
- GeminiGenerationConfigOptions &
522
+ GeminiCommonConfigOptions &
519
523
  GeminiCachedContentOptions
520
524
  >
521
525
  /*
@@ -579,7 +583,7 @@ const GEMINI_2_FLASH_LITE = {
579
583
  } as const satisfies ModelMeta<
580
584
  GeminiToolConfigOptions &
581
585
  GeminiSafetyOptions &
582
- GeminiGenerationConfigOptions &
586
+ GeminiCommonConfigOptions &
583
587
  GeminiCachedContentOptions &
584
588
  GeminiStructuredOutputOptions
585
589
  >
@@ -603,7 +607,7 @@ const IMAGEN_4_GENERATE = {
603
607
  } as const satisfies ModelMeta<
604
608
  GeminiToolConfigOptions &
605
609
  GeminiSafetyOptions &
606
- GeminiGenerationConfigOptions &
610
+ GeminiCommonConfigOptions &
607
611
  GeminiCachedContentOptions
608
612
  >
609
613
 
@@ -626,7 +630,7 @@ const IMAGEN_4_GENERATE_ULTRA = {
626
630
  } as const satisfies ModelMeta<
627
631
  GeminiToolConfigOptions &
628
632
  GeminiSafetyOptions &
629
- GeminiGenerationConfigOptions &
633
+ GeminiCommonConfigOptions &
630
634
  GeminiCachedContentOptions
631
635
  >
632
636
 
@@ -649,7 +653,7 @@ const IMAGEN_4_GENERATE_FAST = {
649
653
  } as const satisfies ModelMeta<
650
654
  GeminiToolConfigOptions &
651
655
  GeminiSafetyOptions &
652
- GeminiGenerationConfigOptions &
656
+ GeminiCommonConfigOptions &
653
657
  GeminiCachedContentOptions
654
658
  >
655
659
 
@@ -671,7 +675,7 @@ const IMAGEN_3 = {
671
675
  } as const satisfies ModelMeta<
672
676
  GeminiToolConfigOptions &
673
677
  GeminiSafetyOptions &
674
- GeminiGenerationConfigOptions &
678
+ GeminiCommonConfigOptions &
675
679
  GeminiCachedContentOptions
676
680
  >
677
681
  /**
@@ -909,55 +913,57 @@ export type GeminiChatModelProviderOptionsByName = {
909
913
  // Models with thinking and structured output support
910
914
  [GEMINI_3_PRO.name]: GeminiToolConfigOptions &
911
915
  GeminiSafetyOptions &
912
- GeminiGenerationConfigOptions &
916
+ GeminiCommonConfigOptions &
913
917
  GeminiCachedContentOptions &
914
918
  GeminiStructuredOutputOptions &
915
- GeminiThinkingOptions
919
+ GeminiThinkingOptions &
920
+ GeminiThinkingAdvancedOptions
916
921
  [GEMINI_3_FLASH.name]: GeminiToolConfigOptions &
917
922
  GeminiSafetyOptions &
918
- GeminiGenerationConfigOptions &
923
+ GeminiCommonConfigOptions &
919
924
  GeminiCachedContentOptions &
920
925
  GeminiStructuredOutputOptions &
921
- GeminiThinkingOptions
926
+ GeminiThinkingOptions &
927
+ GeminiThinkingAdvancedOptions
922
928
  [GEMINI_2_5_PRO.name]: GeminiToolConfigOptions &
923
929
  GeminiSafetyOptions &
924
- GeminiGenerationConfigOptions &
930
+ GeminiCommonConfigOptions &
925
931
  GeminiCachedContentOptions &
926
932
  GeminiStructuredOutputOptions &
927
933
  GeminiThinkingOptions
928
934
  [GEMINI_2_5_FLASH.name]: GeminiToolConfigOptions &
929
935
  GeminiSafetyOptions &
930
- GeminiGenerationConfigOptions &
936
+ GeminiCommonConfigOptions &
931
937
  GeminiCachedContentOptions &
932
938
  GeminiStructuredOutputOptions &
933
939
  GeminiThinkingOptions
934
940
  [GEMINI_2_5_FLASH_PREVIEW.name]: GeminiToolConfigOptions &
935
941
  GeminiSafetyOptions &
936
- GeminiGenerationConfigOptions &
942
+ GeminiCommonConfigOptions &
937
943
  GeminiCachedContentOptions &
938
944
  GeminiStructuredOutputOptions &
939
945
  GeminiThinkingOptions
940
946
  [GEMINI_2_5_FLASH_LITE.name]: GeminiToolConfigOptions &
941
947
  GeminiSafetyOptions &
942
- GeminiGenerationConfigOptions &
948
+ GeminiCommonConfigOptions &
943
949
  GeminiCachedContentOptions &
944
950
  GeminiStructuredOutputOptions &
945
951
  GeminiThinkingOptions
946
952
  [GEMINI_2_5_FLASH_LITE_PREVIEW.name]: GeminiToolConfigOptions &
947
953
  GeminiSafetyOptions &
948
- GeminiGenerationConfigOptions &
954
+ GeminiCommonConfigOptions &
949
955
  GeminiCachedContentOptions &
950
956
  GeminiStructuredOutputOptions &
951
957
  GeminiThinkingOptions
952
958
  // Models with structured output but no thinking support
953
959
  [GEMINI_2_FLASH.name]: GeminiToolConfigOptions &
954
960
  GeminiSafetyOptions &
955
- GeminiGenerationConfigOptions &
961
+ GeminiCommonConfigOptions &
956
962
  GeminiCachedContentOptions &
957
963
  GeminiStructuredOutputOptions
958
964
  [GEMINI_2_FLASH_LITE.name]: GeminiToolConfigOptions &
959
965
  GeminiSafetyOptions &
960
- GeminiGenerationConfigOptions &
966
+ GeminiCommonConfigOptions &
961
967
  GeminiCachedContentOptions &
962
968
  GeminiStructuredOutputOptions
963
969
  }
@@ -22,40 +22,39 @@ This will be enforced on the GenerateContentRequest.contents and GenerateContent
22
22
  safetySettings?: Array<SafetySetting>
23
23
  }
24
24
 
25
- export interface GeminiGenerationConfigOptions {
25
+ export interface GeminiCommonConfigOptions {
26
26
  /**
27
27
  * Configuration options for model generation and outputs.
28
28
  */
29
- generationConfig?: {
30
- /**
31
- * The set of character sequences (up to 5) that will stop output generation. If specified, the API will stop at the first appearance of a stop_sequence. The stop sequence will not be included as part of the response.
32
- */
33
- stopSequences?: Array<string>
34
- /**
29
+ /**
30
+ * The set of character sequences (up to 5) that will stop output generation. If specified, the API will stop at the first appearance of a stop_sequence. The stop sequence will not be included as part of the response.
31
+ */
32
+ stopSequences?: Array<string>
33
+ /**
35
34
  * The requested modalities of the response. Represents the set of modalities that the model can return, and should be expected in the response. This is an exact match to the modalities of the response.
36
35
 
37
36
  A model may have multiple combinations of supported modalities. If the requested modalities do not match any of the supported combinations, an error will be returned.
38
37
  */
39
- responseModalities?: Array<
40
- 'MODALITY_UNSPECIFIED' | 'TEXT' | 'IMAGE' | 'AUDIO'
41
- >
42
- /**
43
- * Number of generated responses to return. If unset, this will default to 1. Please note that this doesn't work for previous generation models (Gemini 1.0 family)
44
- */
45
- candidateCount?: number
46
- /**
38
+ responseModalities?: Array<
39
+ 'MODALITY_UNSPECIFIED' | 'TEXT' | 'IMAGE' | 'AUDIO'
40
+ >
41
+ /**
42
+ * Number of generated responses to return. If unset, this will default to 1. Please note that this doesn't work for previous generation models (Gemini 1.0 family)
43
+ */
44
+ candidateCount?: number
45
+ /**
47
46
  * The maximum number of tokens to consider when sampling.
48
47
 
49
48
  Gemini models use Top-p (nucleus) sampling or a combination of Top-k and nucleus sampling. Top-k sampling considers the set of topK most probable tokens. Models running with nucleus sampling don't allow topK setting.
50
49
 
51
50
  Note: The default value varies by Model and is specified by theModel.top_p attribute returned from the getModel function. An empty topK attribute indicates that the model doesn't apply top-k sampling and doesn't allow setting topK on requests.
52
51
  */
53
- topK?: number
54
- /**
55
- * Seed used in decoding. If not set, the request uses a randomly generated seed.
56
- */
57
- seed?: number
58
- /**
52
+ topK?: number
53
+ /**
54
+ * Seed used in decoding. If not set, the request uses a randomly generated seed.
55
+ */
56
+ seed?: number
57
+ /**
59
58
  * Presence penalty applied to the next token's logprobs if the token has already been seen in the response.
60
59
 
61
60
  This penalty is binary on/off and not dependant on the number of times the token is used (after the first). Use frequencyPenalty for a penalty that increases with each use.
@@ -64,107 +63,105 @@ A positive penalty will discourage the use of tokens that have already been used
64
63
 
65
64
  A negative penalty will encourage the use of tokens that have already been used in the response, decreasing the vocabulary.
66
65
  */
67
- presencePenalty?: number
68
- /**
66
+ presencePenalty?: number
67
+ /**
69
68
  * Frequency penalty applied to the next token's logprobs, multiplied by the number of times each token has been seen in the respponse so far.
70
69
 
71
70
  A positive penalty will discourage the use of tokens that have already been used, proportional to the number of times the token has been used: The more a token is used, the more difficult it is for the model to use that token again increasing the vocabulary of responses.
72
71
 
73
72
  Caution: A negative penalty will encourage the model to reuse tokens proportional to the number of times the token has been used. Small negative values will reduce the vocabulary of a response. Larger negative values will cause the model to start repeating a common token until it hits the maxOutputTokens limit.
74
73
  */
75
- frequencyPenalty?: number
76
- /**
77
- * If true, export the logprobs results in response.
78
- */
79
- responseLogprobs?: boolean
74
+ frequencyPenalty?: number
75
+ /**
76
+ * If true, export the logprobs results in response.
77
+ */
78
+ responseLogprobs?: boolean
80
79
 
81
- /**
82
- * Only valid if responseLogprobs=True. This sets the number of top logprobs to return at each decoding step in the Candidate.logprobs_result. The number must be in the range of [0, 20].
83
- */
84
- logprobs?: number
80
+ /**
81
+ * Only valid if responseLogprobs=True. This sets the number of top logprobs to return at each decoding step in the Candidate.logprobs_result. The number must be in the range of [0, 20].
82
+ */
83
+ logprobs?: number
85
84
 
86
- /**
87
- * Enables enhanced civic answers. It may not be available for all models.
88
- */
89
- enableEnhancedCivicAnswers?: boolean
85
+ /**
86
+ * Enables enhanced civic answers. It may not be available for all models.
87
+ */
88
+ enableEnhancedCivicAnswers?: boolean
90
89
 
91
- /**
92
- * The speech generation config.
93
- */
94
- speechConfig?: {
95
- voiceConfig: {
96
- prebuiltVoiceConfig: {
97
- voiceName: string
98
- }
90
+ /**
91
+ * The speech generation config.
92
+ */
93
+ speechConfig?: {
94
+ voiceConfig: {
95
+ prebuiltVoiceConfig: {
96
+ voiceName: string
99
97
  }
98
+ }
100
99
 
101
- multiSpeakerVoiceConfig?: {
102
- speakerVoiceConfigs?: Array<{
103
- speaker: string
104
- voiceConfig: {
105
- prebuiltVoiceConfig: {
106
- voiceName: string
107
- }
100
+ multiSpeakerVoiceConfig?: {
101
+ speakerVoiceConfigs?: Array<{
102
+ speaker: string
103
+ voiceConfig: {
104
+ prebuiltVoiceConfig: {
105
+ voiceName: string
108
106
  }
109
- }>
110
- }
111
- /**
107
+ }
108
+ }>
109
+ }
110
+ /**
112
111
  * Language code (in BCP 47 format, e.g. "en-US") for speech synthesis.
113
112
 
114
113
  Valid values are: de-DE, en-AU, en-GB, en-IN, en-US, es-US, fr-FR, hi-IN, pt-BR, ar-XA, es-ES, fr-CA, id-ID, it-IT, ja-JP, tr-TR, vi-VN, bn-IN, gu-IN, kn-IN, ml-IN, mr-IN, ta-IN, te-IN, nl-NL, ko-KR, cmn-CN, pl-PL, ru-RU, and th-TH.
115
114
  */
116
- languageCode?:
117
- | 'de-DE'
118
- | 'en-AU'
119
- | 'en-GB'
120
- | 'en-IN'
121
- | 'en-US'
122
- | 'es-US'
123
- | 'fr-FR'
124
- | 'hi-IN'
125
- | 'pt-BR'
126
- | 'ar-XA'
127
- | 'es-ES'
128
- | 'fr-CA'
129
- | 'id-ID'
130
- | 'it-IT'
131
- | 'ja-JP'
132
- | 'tr-TR'
133
- | 'vi-VN'
134
- | 'bn-IN'
135
- | 'gu-IN'
136
- | 'kn-IN'
137
- | 'ml-IN'
138
- | 'mr-IN'
139
- | 'ta-IN'
140
- | 'te-IN'
141
- | 'nl-NL'
142
- | 'ko-KR'
143
- | 'cmn-CN'
144
- | 'pl-PL'
145
- | 'ru-RU'
146
- | 'th-TH'
147
- }
148
- /**
149
- * Config for image generation. An error will be returned if this field is set for models that don't support these config options.
150
- */
151
- imageConfig?: {
152
- aspectRatio?:
153
- | '1:1'
154
- | '2:3'
155
- | '3:2'
156
- | '3:4'
157
- | '4:3'
158
- | '9:16'
159
- | '16:9'
160
- | '21:9'
161
- }
162
- /**
163
- * If specified, the media resolution specified will be used.
164
- */
165
- mediaResolution?: MediaResolution
166
- } & GeminiThinkingOptions &
167
- GeminiStructuredOutputOptions
115
+ languageCode?:
116
+ | 'de-DE'
117
+ | 'en-AU'
118
+ | 'en-GB'
119
+ | 'en-IN'
120
+ | 'en-US'
121
+ | 'es-US'
122
+ | 'fr-FR'
123
+ | 'hi-IN'
124
+ | 'pt-BR'
125
+ | 'ar-XA'
126
+ | 'es-ES'
127
+ | 'fr-CA'
128
+ | 'id-ID'
129
+ | 'it-IT'
130
+ | 'ja-JP'
131
+ | 'tr-TR'
132
+ | 'vi-VN'
133
+ | 'bn-IN'
134
+ | 'gu-IN'
135
+ | 'kn-IN'
136
+ | 'ml-IN'
137
+ | 'mr-IN'
138
+ | 'ta-IN'
139
+ | 'te-IN'
140
+ | 'nl-NL'
141
+ | 'ko-KR'
142
+ | 'cmn-CN'
143
+ | 'pl-PL'
144
+ | 'ru-RU'
145
+ | 'th-TH'
146
+ }
147
+ /**
148
+ * Config for image generation. An error will be returned if this field is set for models that don't support these config options.
149
+ */
150
+ imageConfig?: {
151
+ aspectRatio?:
152
+ | '1:1'
153
+ | '2:3'
154
+ | '3:2'
155
+ | '3:4'
156
+ | '4:3'
157
+ | '9:16'
158
+ | '16:9'
159
+ | '21:9'
160
+ }
161
+ /**
162
+ * If specified, the media resolution specified will be used.
163
+ */
164
+ mediaResolution?: MediaResolution
168
165
  }
169
166
 
170
167
  export interface GeminiCachedContentOptions {
@@ -232,15 +229,26 @@ export interface GeminiThinkingOptions {
232
229
  /**
233
230
  * The number of thoughts tokens that the model should generate.
234
231
  */
235
- thinkingBudget: number
232
+ thinkingBudget?: number
233
+ }
234
+ }
235
+
236
+ export interface GeminiThinkingAdvancedOptions {
237
+ /**
238
+ * Config for thinking features. An error will be returned if this field is set for models that don't support thinking.
239
+ */
240
+ thinkingConfig?: {
236
241
  /**
237
242
  * The level of thoughts tokens that the model should generate.
238
243
  */
239
- thinkingLevel?: ThinkingLevel
244
+ thinkingLevel?: keyof typeof ThinkingLevel
240
245
  }
241
246
  }
242
247
 
243
248
  export type ExternalTextProviderOptions = GeminiToolConfigOptions &
244
249
  GeminiSafetyOptions &
245
- GeminiGenerationConfigOptions &
246
- GeminiCachedContentOptions
250
+ GeminiCommonConfigOptions &
251
+ GeminiCachedContentOptions &
252
+ GeminiThinkingOptions &
253
+ GeminiThinkingAdvancedOptions &
254
+ GeminiStructuredOutputOptions