@tanstack/ai-gemini 0.5.0 → 0.7.0

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.
package/README.md CHANGED
@@ -47,7 +47,7 @@ A powerful, type-safe AI SDK for building AI-powered applications.
47
47
  - **Enhanced integration with TanStack Start** - Share implementations between AI tools and server functions
48
48
  - **Observability events** - Structured, typed events for text, tools, image, speech, transcription, and video ([docs](./docs/guides/observability.md))
49
49
 
50
- ### <a href="https://tanstack.com/ai">Read the docs →</b></a>
50
+ ### <a href="https://tanstack.com/ai">Read the docs →</a>
51
51
 
52
52
  ## Tree-Shakeable Adapters
53
53
 
@@ -13,14 +13,16 @@ export type GeminiImageModel = (typeof GEMINI_IMAGE_MODELS)[number];
13
13
  /**
14
14
  * Gemini Image Generation Adapter
15
15
  *
16
- * Tree-shakeable adapter for Gemini Imagen image generation functionality.
17
- * Supports Imagen 3 and Imagen 4 models.
16
+ * Tree-shakeable adapter for Gemini image generation functionality.
17
+ * Supports Imagen 3/4 models (via generateImages API) and Gemini native
18
+ * image models like Nano Banana 2 (via generateContent API).
18
19
  *
19
20
  * Features:
20
21
  * - Aspect ratio-based image sizing
21
22
  * - Person generation controls
22
23
  * - Safety filtering
23
24
  * - Watermark options
25
+ * - Extended resolution tiers (Nano Banana 2)
24
26
  */
25
27
  export declare class GeminiImageAdapter<TModel extends GeminiImageModel> extends BaseImageAdapter<TModel, GeminiImageProviderOptions, GeminiImageModelProviderOptionsByName, GeminiImageModelSizeByName> {
26
28
  readonly kind: "image";
@@ -33,8 +35,11 @@ export declare class GeminiImageAdapter<TModel extends GeminiImageModel> extends
33
35
  private client;
34
36
  constructor(config: GeminiImageConfig, model: TModel);
35
37
  generateImages(options: ImageGenerationOptions<GeminiImageProviderOptions>): Promise<ImageGenerationResult>;
36
- private buildConfig;
37
- private transformResponse;
38
+ private isGeminiImageModel;
39
+ private generateWithGeminiApi;
40
+ private transformGeminiResponse;
41
+ private buildImagenConfig;
42
+ private transformImagenResponse;
38
43
  }
39
44
  /**
40
45
  * Creates a Gemini image adapter with explicit API key.
@@ -1,6 +1,6 @@
1
1
  import { BaseImageAdapter } from "@tanstack/ai/adapters";
2
2
  import { createGeminiClient, generateId, getGeminiApiKeyFromEnv } from "../utils/client.js";
3
- import { validatePrompt, validateImageSize, validateNumberOfImages, sizeToAspectRatio } from "../image/image-provider-options.js";
3
+ import { validatePrompt, validateImageSize, validateNumberOfImages, parseNativeImageSize, sizeToAspectRatio } from "../image/image-provider-options.js";
4
4
  class GeminiImageAdapter extends BaseImageAdapter {
5
5
  constructor(config, model) {
6
6
  super({}, model);
@@ -9,19 +9,66 @@ class GeminiImageAdapter extends BaseImageAdapter {
9
9
  this.client = createGeminiClient(config);
10
10
  }
11
11
  async generateImages(options) {
12
- const { model, prompt, numberOfImages, size } = options;
12
+ const { model, prompt } = options;
13
13
  validatePrompt({ prompt, model });
14
- validateImageSize(model, size);
15
- validateNumberOfImages(model, numberOfImages);
16
- const config = this.buildConfig(options);
14
+ if (this.isGeminiImageModel(model)) {
15
+ return this.generateWithGeminiApi(options);
16
+ }
17
+ validateImageSize(model, options.size);
18
+ validateNumberOfImages(model, options.numberOfImages);
19
+ const config = this.buildImagenConfig(options);
17
20
  const response = await this.client.models.generateImages({
18
21
  model,
19
22
  prompt,
20
23
  config
21
24
  });
22
- return this.transformResponse(model, response);
25
+ return this.transformImagenResponse(model, response);
23
26
  }
24
- buildConfig(options) {
27
+ isGeminiImageModel(model) {
28
+ return model.startsWith("gemini-");
29
+ }
30
+ async generateWithGeminiApi(options) {
31
+ const { model, prompt, size, numberOfImages, modelOptions } = options;
32
+ const parsedSize = size ? parseNativeImageSize(size) : void 0;
33
+ const augmentedPrompt = numberOfImages && numberOfImages > 1 ? `${prompt} Generate ${numberOfImages} distinct images.` : prompt;
34
+ const config = {
35
+ // Include TEXT so the model can interleave descriptions between images
36
+ responseModalities: ["TEXT", "IMAGE"],
37
+ ...parsedSize && {
38
+ imageConfig: {
39
+ ...parsedSize.aspectRatio && {
40
+ aspectRatio: parsedSize.aspectRatio
41
+ },
42
+ ...parsedSize.resolution && {
43
+ imageSize: parsedSize.resolution
44
+ }
45
+ }
46
+ },
47
+ ...modelOptions
48
+ };
49
+ const response = await this.client.models.generateContent({
50
+ model,
51
+ contents: augmentedPrompt,
52
+ config
53
+ });
54
+ return this.transformGeminiResponse(model, response);
55
+ }
56
+ transformGeminiResponse(model, response) {
57
+ const images = [];
58
+ const parts = response.candidates?.[0]?.content?.parts ?? [];
59
+ for (const part of parts) {
60
+ if (part.inlineData?.data && typeof part.inlineData.data === "string" && part.inlineData.data.length > 0) {
61
+ images.push({ b64Json: part.inlineData.data });
62
+ }
63
+ }
64
+ return {
65
+ id: generateId(this.name),
66
+ model,
67
+ images,
68
+ usage: void 0
69
+ };
70
+ }
71
+ buildImagenConfig(options) {
25
72
  const { size, numberOfImages, modelOptions } = options;
26
73
  return {
27
74
  numberOfImages: numberOfImages ?? 1,
@@ -30,7 +77,7 @@ class GeminiImageAdapter extends BaseImageAdapter {
30
77
  ...modelOptions
31
78
  };
32
79
  }
33
- transformResponse(model, response) {
80
+ transformImagenResponse(model, response) {
34
81
  const images = (response.generatedImages ?? []).map(
35
82
  (item) => ({
36
83
  b64Json: item.image?.imageBytes,
@@ -1 +1 @@
1
- {"version":3,"file":"image.js","sources":["../../../src/adapters/image.ts"],"sourcesContent":["import { BaseImageAdapter } from '@tanstack/ai/adapters'\nimport {\n createGeminiClient,\n generateId,\n getGeminiApiKeyFromEnv,\n} from '../utils'\nimport {\n sizeToAspectRatio,\n validateImageSize,\n validateNumberOfImages,\n validatePrompt,\n} from '../image/image-provider-options'\nimport type { GEMINI_IMAGE_MODELS } from '../model-meta'\nimport type {\n GeminiImageModelProviderOptionsByName,\n GeminiImageModelSizeByName,\n GeminiImageProviderOptions,\n} from '../image/image-provider-options'\nimport type {\n GeneratedImage,\n ImageGenerationOptions,\n ImageGenerationResult,\n} from '@tanstack/ai'\nimport type {\n GenerateImagesConfig,\n GenerateImagesResponse,\n GoogleGenAI,\n} from '@google/genai'\nimport type { GeminiClientConfig } from '../utils'\n\n/**\n * Configuration for Gemini image adapter\n */\nexport interface GeminiImageConfig extends GeminiClientConfig {}\n\n/** Model type for Gemini Image */\nexport type GeminiImageModel = (typeof GEMINI_IMAGE_MODELS)[number]\n\n/**\n * Gemini Image Generation Adapter\n *\n * Tree-shakeable adapter for Gemini Imagen image generation functionality.\n * Supports Imagen 3 and Imagen 4 models.\n *\n * Features:\n * - Aspect ratio-based image sizing\n * - Person generation controls\n * - Safety filtering\n * - Watermark options\n */\nexport class GeminiImageAdapter<\n TModel extends GeminiImageModel,\n> extends BaseImageAdapter<\n TModel,\n GeminiImageProviderOptions,\n GeminiImageModelProviderOptionsByName,\n GeminiImageModelSizeByName\n> {\n readonly kind = 'image' as const\n readonly name = 'gemini' as const\n\n // Type-only property - never assigned at runtime\n declare '~types': {\n providerOptions: GeminiImageProviderOptions\n modelProviderOptionsByName: GeminiImageModelProviderOptionsByName\n modelSizeByName: GeminiImageModelSizeByName\n }\n\n private client: GoogleGenAI\n\n constructor(config: GeminiImageConfig, model: TModel) {\n super({}, model)\n this.client = createGeminiClient(config)\n }\n\n async generateImages(\n options: ImageGenerationOptions<GeminiImageProviderOptions>,\n ): Promise<ImageGenerationResult> {\n const { model, prompt, numberOfImages, size } = options\n\n // Validate inputs\n validatePrompt({ prompt, model })\n validateImageSize(model, size)\n validateNumberOfImages(model, numberOfImages)\n\n // Build request config\n const config = this.buildConfig(options)\n\n const response = await this.client.models.generateImages({\n model,\n prompt,\n config,\n })\n\n return this.transformResponse(model, response)\n }\n\n private buildConfig(\n options: ImageGenerationOptions<GeminiImageProviderOptions>,\n ): GenerateImagesConfig {\n const { size, numberOfImages, modelOptions } = options\n\n return {\n numberOfImages: numberOfImages ?? 1,\n // Map size to aspect ratio if provided (modelOptions.aspectRatio will override)\n aspectRatio: size ? sizeToAspectRatio(size) : undefined,\n ...modelOptions,\n }\n }\n\n private transformResponse(\n model: string,\n response: GenerateImagesResponse,\n ): ImageGenerationResult {\n const images: Array<GeneratedImage> = (response.generatedImages ?? []).map(\n (item) => ({\n b64Json: item.image?.imageBytes,\n revisedPrompt: item.enhancedPrompt,\n }),\n )\n\n return {\n id: generateId(this.name),\n model,\n images,\n usage: undefined,\n }\n }\n}\n\n/**\n * Creates a Gemini image adapter with explicit API key.\n * Type resolution happens here at the call site.\n *\n * @param model - The model name (e.g., 'imagen-3.0-generate-002')\n * @param apiKey - Your Google API key\n * @param config - Optional additional configuration\n * @returns Configured Gemini image adapter instance with resolved types\n *\n * @example\n * ```typescript\n * const adapter = createGeminiImage('imagen-3.0-generate-002', \"your-api-key\");\n *\n * const result = await generateImage({\n * adapter,\n * prompt: 'A cute baby sea otter'\n * });\n * ```\n */\nexport function createGeminiImage<TModel extends GeminiImageModel>(\n model: TModel,\n apiKey: string,\n config?: Omit<GeminiImageConfig, 'apiKey'>,\n): GeminiImageAdapter<TModel> {\n return new GeminiImageAdapter({ apiKey, ...config }, model)\n}\n\n/**\n * Creates a Gemini image adapter with automatic API key detection from environment variables.\n * Type resolution happens here at the call site.\n *\n * Looks for `GOOGLE_API_KEY` or `GEMINI_API_KEY` in:\n * - `process.env` (Node.js)\n * - `window.env` (Browser with injected env)\n *\n * @param model - The model name (e.g., 'imagen-4.0-generate-001')\n * @param config - Optional configuration (excluding apiKey which is auto-detected)\n * @returns Configured Gemini image adapter instance with resolved types\n * @throws Error if GOOGLE_API_KEY or GEMINI_API_KEY is not found in environment\n *\n * @example\n * ```typescript\n * // Automatically uses GOOGLE_API_KEY from environment\n * const adapter = geminiImage('imagen-4.0-generate-001');\n *\n * const result = await generateImage({\n * adapter,\n * prompt: 'A beautiful sunset over mountains'\n * });\n * ```\n */\nexport function geminiImage<TModel extends GeminiImageModel>(\n model: TModel,\n config?: Omit<GeminiImageConfig, 'apiKey'>,\n): GeminiImageAdapter<TModel> {\n const apiKey = getGeminiApiKeyFromEnv()\n return createGeminiImage(model, apiKey, config)\n}\n"],"names":[],"mappings":";;;AAkDO,MAAM,2BAEH,iBAKR;AAAA,EAaA,YAAY,QAA2B,OAAe;AACpD,UAAM,CAAA,GAAI,KAAK;AAbjB,SAAS,OAAO;AAChB,SAAS,OAAO;AAad,SAAK,SAAS,mBAAmB,MAAM;AAAA,EACzC;AAAA,EAEA,MAAM,eACJ,SACgC;AAChC,UAAM,EAAE,OAAO,QAAQ,gBAAgB,SAAS;AAGhD,mBAAe,EAAE,QAAQ,OAAO;AAChC,sBAAkB,OAAO,IAAI;AAC7B,2BAAuB,OAAO,cAAc;AAG5C,UAAM,SAAS,KAAK,YAAY,OAAO;AAEvC,UAAM,WAAW,MAAM,KAAK,OAAO,OAAO,eAAe;AAAA,MACvD;AAAA,MACA;AAAA,MACA;AAAA,IAAA,CACD;AAED,WAAO,KAAK,kBAAkB,OAAO,QAAQ;AAAA,EAC/C;AAAA,EAEQ,YACN,SACsB;AACtB,UAAM,EAAE,MAAM,gBAAgB,aAAA,IAAiB;AAE/C,WAAO;AAAA,MACL,gBAAgB,kBAAkB;AAAA;AAAA,MAElC,aAAa,OAAO,kBAAkB,IAAI,IAAI;AAAA,MAC9C,GAAG;AAAA,IAAA;AAAA,EAEP;AAAA,EAEQ,kBACN,OACA,UACuB;AACvB,UAAM,UAAiC,SAAS,mBAAmB,CAAA,GAAI;AAAA,MACrE,CAAC,UAAU;AAAA,QACT,SAAS,KAAK,OAAO;AAAA,QACrB,eAAe,KAAK;AAAA,MAAA;AAAA,IACtB;AAGF,WAAO;AAAA,MACL,IAAI,WAAW,KAAK,IAAI;AAAA,MACxB;AAAA,MACA;AAAA,MACA,OAAO;AAAA,IAAA;AAAA,EAEX;AACF;AAqBO,SAAS,kBACd,OACA,QACA,QAC4B;AAC5B,SAAO,IAAI,mBAAmB,EAAE,QAAQ,GAAG,OAAA,GAAU,KAAK;AAC5D;AA0BO,SAAS,YACd,OACA,QAC4B;AAC5B,QAAM,SAAS,uBAAA;AACf,SAAO,kBAAkB,OAAO,QAAQ,MAAM;AAChD;"}
1
+ {"version":3,"file":"image.js","sources":["../../../src/adapters/image.ts"],"sourcesContent":["import { BaseImageAdapter } from '@tanstack/ai/adapters'\nimport {\n createGeminiClient,\n generateId,\n getGeminiApiKeyFromEnv,\n} from '../utils'\nimport {\n parseNativeImageSize,\n sizeToAspectRatio,\n validateImageSize,\n validateNumberOfImages,\n validatePrompt,\n} from '../image/image-provider-options'\nimport type { GEMINI_IMAGE_MODELS } from '../model-meta'\nimport type {\n GeminiImageModelProviderOptionsByName,\n GeminiImageModelSizeByName,\n GeminiImageProviderOptions,\n} from '../image/image-provider-options'\nimport type {\n GeneratedImage,\n ImageGenerationOptions,\n ImageGenerationResult,\n} from '@tanstack/ai'\nimport type {\n GenerateContentConfig,\n GenerateContentResponse,\n GenerateImagesConfig,\n GenerateImagesResponse,\n GoogleGenAI,\n} from '@google/genai'\nimport type { GeminiClientConfig } from '../utils'\n\n/**\n * Configuration for Gemini image adapter\n */\nexport interface GeminiImageConfig extends GeminiClientConfig {}\n\n/** Model type for Gemini Image */\nexport type GeminiImageModel = (typeof GEMINI_IMAGE_MODELS)[number]\n\n/**\n * Gemini Image Generation Adapter\n *\n * Tree-shakeable adapter for Gemini image generation functionality.\n * Supports Imagen 3/4 models (via generateImages API) and Gemini native\n * image models like Nano Banana 2 (via generateContent API).\n *\n * Features:\n * - Aspect ratio-based image sizing\n * - Person generation controls\n * - Safety filtering\n * - Watermark options\n * - Extended resolution tiers (Nano Banana 2)\n */\nexport class GeminiImageAdapter<\n TModel extends GeminiImageModel,\n> extends BaseImageAdapter<\n TModel,\n GeminiImageProviderOptions,\n GeminiImageModelProviderOptionsByName,\n GeminiImageModelSizeByName\n> {\n readonly kind = 'image' as const\n readonly name = 'gemini' as const\n\n // Type-only property - never assigned at runtime\n declare '~types': {\n providerOptions: GeminiImageProviderOptions\n modelProviderOptionsByName: GeminiImageModelProviderOptionsByName\n modelSizeByName: GeminiImageModelSizeByName\n }\n\n private client: GoogleGenAI\n\n constructor(config: GeminiImageConfig, model: TModel) {\n super({}, model)\n this.client = createGeminiClient(config)\n }\n\n async generateImages(\n options: ImageGenerationOptions<GeminiImageProviderOptions>,\n ): Promise<ImageGenerationResult> {\n const { model, prompt } = options\n\n validatePrompt({ prompt, model })\n\n if (this.isGeminiImageModel(model)) {\n return this.generateWithGeminiApi(options)\n }\n\n // Imagen models path (generateImages API)\n validateImageSize(model, options.size)\n validateNumberOfImages(model, options.numberOfImages)\n\n const config = this.buildImagenConfig(options)\n\n const response = await this.client.models.generateImages({\n model,\n prompt,\n config,\n })\n\n return this.transformImagenResponse(model, response)\n }\n\n private isGeminiImageModel(model: string): boolean {\n return model.startsWith('gemini-')\n }\n\n private async generateWithGeminiApi(\n options: ImageGenerationOptions<GeminiImageProviderOptions>,\n ): Promise<ImageGenerationResult> {\n const { model, prompt, size, numberOfImages, modelOptions } = options\n\n const parsedSize = size ? parseNativeImageSize(size) : undefined\n\n // The generateContent API has no numberOfImages parameter.\n // Instead, augment the prompt to request multiple images when needed.\n const augmentedPrompt =\n numberOfImages && numberOfImages > 1\n ? `${prompt} Generate ${numberOfImages} distinct images.`\n : prompt\n\n const config: GenerateContentConfig = {\n // Include TEXT so the model can interleave descriptions between images\n responseModalities: ['TEXT', 'IMAGE'],\n ...(parsedSize && {\n imageConfig: {\n ...(parsedSize.aspectRatio && {\n aspectRatio: parsedSize.aspectRatio,\n }),\n ...(parsedSize.resolution && {\n imageSize: parsedSize.resolution,\n }),\n },\n }),\n ...modelOptions,\n }\n\n const response = await this.client.models.generateContent({\n model,\n contents: augmentedPrompt,\n config,\n })\n\n return this.transformGeminiResponse(model, response)\n }\n\n private transformGeminiResponse(\n model: string,\n response: GenerateContentResponse,\n ): ImageGenerationResult {\n const images: Array<GeneratedImage> = []\n const parts = response.candidates?.[0]?.content?.parts ?? []\n\n for (const part of parts) {\n if (\n part.inlineData?.data &&\n typeof part.inlineData.data === 'string' &&\n part.inlineData.data.length > 0\n ) {\n images.push({ b64Json: part.inlineData.data })\n }\n }\n\n return {\n id: generateId(this.name),\n model,\n images,\n usage: undefined,\n }\n }\n\n private buildImagenConfig(\n options: ImageGenerationOptions<GeminiImageProviderOptions>,\n ): GenerateImagesConfig {\n const { size, numberOfImages, modelOptions } = options\n\n return {\n numberOfImages: numberOfImages ?? 1,\n // Map size to aspect ratio if provided (modelOptions.aspectRatio will override)\n aspectRatio: size ? sizeToAspectRatio(size) : undefined,\n ...modelOptions,\n }\n }\n\n private transformImagenResponse(\n model: string,\n response: GenerateImagesResponse,\n ): ImageGenerationResult {\n const images: Array<GeneratedImage> = (response.generatedImages ?? []).map(\n (item) => ({\n b64Json: item.image?.imageBytes,\n revisedPrompt: item.enhancedPrompt,\n }),\n )\n\n return {\n id: generateId(this.name),\n model,\n images,\n usage: undefined,\n }\n }\n}\n\n/**\n * Creates a Gemini image adapter with explicit API key.\n * Type resolution happens here at the call site.\n *\n * @param model - The model name (e.g., 'imagen-3.0-generate-002')\n * @param apiKey - Your Google API key\n * @param config - Optional additional configuration\n * @returns Configured Gemini image adapter instance with resolved types\n *\n * @example\n * ```typescript\n * const adapter = createGeminiImage('imagen-3.0-generate-002', \"your-api-key\");\n *\n * const result = await generateImage({\n * adapter,\n * prompt: 'A cute baby sea otter'\n * });\n * ```\n */\nexport function createGeminiImage<TModel extends GeminiImageModel>(\n model: TModel,\n apiKey: string,\n config?: Omit<GeminiImageConfig, 'apiKey'>,\n): GeminiImageAdapter<TModel> {\n return new GeminiImageAdapter({ apiKey, ...config }, model)\n}\n\n/**\n * Creates a Gemini image adapter with automatic API key detection from environment variables.\n * Type resolution happens here at the call site.\n *\n * Looks for `GOOGLE_API_KEY` or `GEMINI_API_KEY` in:\n * - `process.env` (Node.js)\n * - `window.env` (Browser with injected env)\n *\n * @param model - The model name (e.g., 'imagen-4.0-generate-001')\n * @param config - Optional configuration (excluding apiKey which is auto-detected)\n * @returns Configured Gemini image adapter instance with resolved types\n * @throws Error if GOOGLE_API_KEY or GEMINI_API_KEY is not found in environment\n *\n * @example\n * ```typescript\n * // Automatically uses GOOGLE_API_KEY from environment\n * const adapter = geminiImage('imagen-4.0-generate-001');\n *\n * const result = await generateImage({\n * adapter,\n * prompt: 'A beautiful sunset over mountains'\n * });\n * ```\n */\nexport function geminiImage<TModel extends GeminiImageModel>(\n model: TModel,\n config?: Omit<GeminiImageConfig, 'apiKey'>,\n): GeminiImageAdapter<TModel> {\n const apiKey = getGeminiApiKeyFromEnv()\n return createGeminiImage(model, apiKey, config)\n}\n"],"names":[],"mappings":";;;AAuDO,MAAM,2BAEH,iBAKR;AAAA,EAaA,YAAY,QAA2B,OAAe;AACpD,UAAM,CAAA,GAAI,KAAK;AAbjB,SAAS,OAAO;AAChB,SAAS,OAAO;AAad,SAAK,SAAS,mBAAmB,MAAM;AAAA,EACzC;AAAA,EAEA,MAAM,eACJ,SACgC;AAChC,UAAM,EAAE,OAAO,OAAA,IAAW;AAE1B,mBAAe,EAAE,QAAQ,OAAO;AAEhC,QAAI,KAAK,mBAAmB,KAAK,GAAG;AAClC,aAAO,KAAK,sBAAsB,OAAO;AAAA,IAC3C;AAGA,sBAAkB,OAAO,QAAQ,IAAI;AACrC,2BAAuB,OAAO,QAAQ,cAAc;AAEpD,UAAM,SAAS,KAAK,kBAAkB,OAAO;AAE7C,UAAM,WAAW,MAAM,KAAK,OAAO,OAAO,eAAe;AAAA,MACvD;AAAA,MACA;AAAA,MACA;AAAA,IAAA,CACD;AAED,WAAO,KAAK,wBAAwB,OAAO,QAAQ;AAAA,EACrD;AAAA,EAEQ,mBAAmB,OAAwB;AACjD,WAAO,MAAM,WAAW,SAAS;AAAA,EACnC;AAAA,EAEA,MAAc,sBACZ,SACgC;AAChC,UAAM,EAAE,OAAO,QAAQ,MAAM,gBAAgB,iBAAiB;AAE9D,UAAM,aAAa,OAAO,qBAAqB,IAAI,IAAI;AAIvD,UAAM,kBACJ,kBAAkB,iBAAiB,IAC/B,GAAG,MAAM,aAAa,cAAc,sBACpC;AAEN,UAAM,SAAgC;AAAA;AAAA,MAEpC,oBAAoB,CAAC,QAAQ,OAAO;AAAA,MACpC,GAAI,cAAc;AAAA,QAChB,aAAa;AAAA,UACX,GAAI,WAAW,eAAe;AAAA,YAC5B,aAAa,WAAW;AAAA,UAAA;AAAA,UAE1B,GAAI,WAAW,cAAc;AAAA,YAC3B,WAAW,WAAW;AAAA,UAAA;AAAA,QACxB;AAAA,MACF;AAAA,MAEF,GAAG;AAAA,IAAA;AAGL,UAAM,WAAW,MAAM,KAAK,OAAO,OAAO,gBAAgB;AAAA,MACxD;AAAA,MACA,UAAU;AAAA,MACV;AAAA,IAAA,CACD;AAED,WAAO,KAAK,wBAAwB,OAAO,QAAQ;AAAA,EACrD;AAAA,EAEQ,wBACN,OACA,UACuB;AACvB,UAAM,SAAgC,CAAA;AACtC,UAAM,QAAQ,SAAS,aAAa,CAAC,GAAG,SAAS,SAAS,CAAA;AAE1D,eAAW,QAAQ,OAAO;AACxB,UACE,KAAK,YAAY,QACjB,OAAO,KAAK,WAAW,SAAS,YAChC,KAAK,WAAW,KAAK,SAAS,GAC9B;AACA,eAAO,KAAK,EAAE,SAAS,KAAK,WAAW,MAAM;AAAA,MAC/C;AAAA,IACF;AAEA,WAAO;AAAA,MACL,IAAI,WAAW,KAAK,IAAI;AAAA,MACxB;AAAA,MACA;AAAA,MACA,OAAO;AAAA,IAAA;AAAA,EAEX;AAAA,EAEQ,kBACN,SACsB;AACtB,UAAM,EAAE,MAAM,gBAAgB,aAAA,IAAiB;AAE/C,WAAO;AAAA,MACL,gBAAgB,kBAAkB;AAAA;AAAA,MAElC,aAAa,OAAO,kBAAkB,IAAI,IAAI;AAAA,MAC9C,GAAG;AAAA,IAAA;AAAA,EAEP;AAAA,EAEQ,wBACN,OACA,UACuB;AACvB,UAAM,UAAiC,SAAS,mBAAmB,CAAA,GAAI;AAAA,MACrE,CAAC,UAAU;AAAA,QACT,SAAS,KAAK,OAAO;AAAA,QACrB,eAAe,KAAK;AAAA,MAAA;AAAA,IACtB;AAGF,WAAO;AAAA,MACL,IAAI,WAAW,KAAK,IAAI;AAAA,MACxB;AAAA,MACA;AAAA,MACA,OAAO;AAAA,IAAA;AAAA,EAEX;AACF;AAqBO,SAAS,kBACd,OACA,QACA,QAC4B;AAC5B,SAAO,IAAI,mBAAmB,EAAE,QAAQ,GAAG,OAAA,GAAU,KAAK;AAC5D;AA0BO,SAAS,YACd,OACA,QAC4B;AAC5B,QAAM,SAAS,uBAAA;AACf,SAAO,kBAAkB,OAAO,QAAQ,MAAM;AAChD;"}
@@ -103,11 +103,32 @@ export type GeminiImageModelProviderOptionsByName = {
103
103
  */
104
104
  export type GeminiImageSize = '1024x1024' | '512x512' | '1024x768' | '1536x1024' | '1792x1024' | '1920x1080' | '768x1024' | '1024x1536' | '1024x1792' | '1080x1920';
105
105
  /**
106
- * Model-specific size options mapping
107
- * All Imagen models use the same size options
106
+ * Aspect ratios supported by Gemini native image models (via generateContent API).
107
+ * Matches the SDK's ImageConfig.aspectRatio values.
108
+ */
109
+ export type GeminiNativeImageAspectRatio = '1:1' | '2:3' | '3:2' | '3:4' | '4:3' | '9:16' | '16:9' | '21:9';
110
+ /**
111
+ * Resolution tiers for Gemini native image models.
112
+ * Matches the SDK's ImageConfig.imageSize values.
113
+ */
114
+ export type GeminiNativeImageResolution = '1K' | '2K' | '4K';
115
+ /**
116
+ * Template literal size type for Gemini native image models: "16:9_4K", "1:1_2K", etc.
117
+ */
118
+ export type GeminiNativeImageSize = `${GeminiNativeImageAspectRatio}_${GeminiNativeImageResolution}`;
119
+ /**
120
+ * Gemini native image models that use the generateContent API path.
121
+ * These models support template literal sizes (aspectRatio_resolution).
122
+ */
123
+ export type GeminiNativeImageModels = 'gemini-3.1-flash-image-preview' | 'gemini-3-pro-image-preview' | 'gemini-2.5-flash-image' | 'gemini-2.0-flash-preview-image-generation';
124
+ /**
125
+ * Model-specific size options mapping.
126
+ * Gemini native image models use template literal sizes, Imagen models use pixel sizes.
108
127
  */
109
128
  export type GeminiImageModelSizeByName = {
110
- [K in GeminiImageModels]: GeminiImageSize;
129
+ [K in GeminiNativeImageModels]: GeminiNativeImageSize;
130
+ } & {
131
+ [K in Exclude<GeminiImageModels, GeminiNativeImageModels>]: GeminiImageSize;
111
132
  };
112
133
  /**
113
134
  * Valid sizes for Gemini Imagen models
@@ -137,3 +158,11 @@ export declare function validatePrompt(options: {
137
158
  prompt: string;
138
159
  model: string;
139
160
  }): void;
161
+ /**
162
+ * Parses a Gemini native image size string into its components.
163
+ * Format: "aspectRatio_resolution" e.g. "16:9_4K" → { aspectRatio: "16:9", resolution: "4K" }
164
+ */
165
+ export declare function parseNativeImageSize(size: string): {
166
+ aspectRatio: string;
167
+ resolution: string;
168
+ } | undefined;
@@ -43,8 +43,14 @@ function validatePrompt(options) {
43
43
  throw new Error(`Prompt cannot be empty for model "${model}".`);
44
44
  }
45
45
  }
46
+ function parseNativeImageSize(size) {
47
+ const match = size.match(/^(\d+:\d+)_(.+)$/);
48
+ if (!match) return void 0;
49
+ return { aspectRatio: match[1], resolution: match[2] };
50
+ }
46
51
  export {
47
52
  GEMINI_SIZE_TO_ASPECT_RATIO,
53
+ parseNativeImageSize,
48
54
  sizeToAspectRatio,
49
55
  validateImageSize,
50
56
  validateNumberOfImages,
@@ -1 +1 @@
1
- {"version":3,"file":"image-provider-options.js","sources":["../../../src/image/image-provider-options.ts"],"sourcesContent":["import type { GeminiImageModels } from '../model-meta'\nimport type {\n ImagePromptLanguage,\n PersonGeneration,\n SafetyFilterLevel,\n} from '@google/genai'\n\n// Re-export SDK types so users can use them directly\nexport type { ImagePromptLanguage, PersonGeneration, SafetyFilterLevel }\n\n/**\n * Gemini Imagen aspect ratio options\n * Controls the aspect ratio of generated images\n */\nexport type GeminiAspectRatio =\n | '1:1'\n | '3:4'\n | '4:3'\n | '9:16'\n | '16:9'\n | '9:21'\n | '21:9'\n\n/**\n * Provider options for Gemini image generation\n * These options match the @google/genai GenerateImagesConfig interface\n * and can be spread directly into the API request.\n */\nexport interface GeminiImageProviderOptions {\n /**\n * The aspect ratio of generated images\n * @default '1:1'\n */\n aspectRatio?: GeminiAspectRatio\n\n /**\n * Controls whether people can appear in generated images\n * Use PersonGeneration enum values: DONT_ALLOW, ALLOW_ADULT, ALLOW_ALL\n * @default 'ALLOW_ADULT'\n */\n personGeneration?: PersonGeneration\n\n /**\n * Safety filter level for content filtering\n * Use SafetyFilterLevel enum values\n */\n safetyFilterLevel?: SafetyFilterLevel\n\n /**\n * Optional seed for reproducible image generation\n * When the same seed is used with the same prompt and settings,\n * you should get similar (though not identical) results\n */\n seed?: number\n\n /**\n * Whether to add a SynthID watermark to generated images\n * SynthID helps identify AI-generated content\n * @default true\n */\n addWatermark?: boolean\n\n /**\n * Language of the prompt\n * Use ImagePromptLanguage enum values\n */\n language?: ImagePromptLanguage\n\n /**\n * Negative prompt - what to avoid in the generated image\n * Not all models support negative prompts\n */\n negativePrompt?: string\n\n /**\n * Output MIME type for the generated image\n * @default 'image/png'\n */\n outputMimeType?: 'image/png' | 'image/jpeg' | 'image/webp'\n\n /**\n * Compression quality for JPEG outputs (0-100)\n * Higher values mean better quality but larger file sizes\n * @default 75\n */\n outputCompressionQuality?: number\n\n /**\n * Controls how much the model adheres to the text prompt\n * Large values increase output and prompt alignment,\n * but may compromise image quality\n */\n guidanceScale?: number\n\n /**\n * Whether to use the prompt rewriting logic\n */\n enhancePrompt?: boolean\n\n /**\n * Whether to report the safety scores of each generated image\n * and the positive prompt in the response\n */\n includeSafetyAttributes?: boolean\n\n /**\n * Whether to include the Responsible AI filter reason\n * if the image is filtered out of the response\n */\n includeRaiReason?: boolean\n\n /**\n * Cloud Storage URI used to store the generated images\n */\n outputGcsUri?: string\n\n /**\n * User specified labels to track billing usage\n */\n labels?: Record<string, string>\n}\n\n/**\n * Model-specific provider options mapping\n * Currently all Imagen models use the same options structure\n */\nexport type GeminiImageModelProviderOptionsByName = {\n [K in GeminiImageModels]: GeminiImageProviderOptions\n}\n\n/**\n * Supported size strings for Gemini Imagen models\n * These map to aspect ratios internally\n */\nexport type GeminiImageSize =\n | '1024x1024'\n | '512x512'\n | '1024x768'\n | '1536x1024'\n | '1792x1024'\n | '1920x1080'\n | '768x1024'\n | '1024x1536'\n | '1024x1792'\n | '1080x1920'\n\n/**\n * Model-specific size options mapping\n * All Imagen models use the same size options\n */\nexport type GeminiImageModelSizeByName = {\n [K in GeminiImageModels]: GeminiImageSize\n}\n\n/**\n * Valid sizes for Gemini Imagen models\n * Gemini uses aspect ratios, but we map common WIDTHxHEIGHT formats to aspect ratios\n * These are approximate mappings based on common image dimensions\n */\nexport const GEMINI_SIZE_TO_ASPECT_RATIO: Record<string, GeminiAspectRatio> = {\n // Square\n '1024x1024': '1:1',\n '512x512': '1:1',\n // Landscape\n '1024x768': '4:3',\n '1536x1024': '4:3',\n '1792x1024': '16:9',\n '1920x1080': '16:9',\n // Portrait\n '768x1024': '3:4',\n '1024x1536': '3:4', // Inverted\n '1024x1792': '9:16',\n '1080x1920': '9:16',\n}\n\n/**\n * Maps a WIDTHxHEIGHT size string to a Gemini aspect ratio\n * Returns undefined if the size cannot be mapped\n */\nexport function sizeToAspectRatio(\n size: string | undefined,\n): GeminiAspectRatio | undefined {\n if (!size) return undefined\n return GEMINI_SIZE_TO_ASPECT_RATIO[size]\n}\n\n/**\n * Validates that the provided size can be mapped to an aspect ratio\n * Throws an error if the size is invalid\n */\nexport function validateImageSize(\n model: string,\n size: string | undefined,\n): void {\n if (!size) return\n\n const aspectRatio = sizeToAspectRatio(size)\n if (!aspectRatio) {\n const validSizes = Object.keys(GEMINI_SIZE_TO_ASPECT_RATIO)\n throw new Error(\n `Invalid size \"${size}\" for model \"${model}\". ` +\n `Gemini Imagen uses aspect ratios. Valid sizes that map to aspect ratios: ${validSizes.join(', ')}. ` +\n `Alternatively, use providerOptions.aspectRatio directly with values: 1:1, 3:4, 4:3, 9:16, 16:9, 9:21, 21:9`,\n )\n }\n}\n\n/**\n * Validates the number of images requested\n * Imagen models support 1-8 images per request (varies by model)\n */\nexport function validateNumberOfImages(\n model: string,\n numberOfImages: number | undefined,\n): void {\n if (numberOfImages === undefined) return\n\n // Most Imagen models support 1-4 images, some support up to 8\n const maxImages = 4\n if (numberOfImages < 1 || numberOfImages > maxImages) {\n throw new Error(\n `Invalid numberOfImages \"${numberOfImages}\" for model \"${model}\". ` +\n `Must be between 1 and ${maxImages}.`,\n )\n }\n}\n\n/**\n * Validates the prompt is not empty\n */\nexport function validatePrompt(options: {\n prompt: string\n model: string\n}): void {\n const { prompt, model } = options\n if (!prompt || prompt.trim().length === 0) {\n throw new Error(`Prompt cannot be empty for model \"${model}\".`)\n }\n}\n"],"names":[],"mappings":"AA+JO,MAAM,8BAAiE;AAAA;AAAA,EAE5E,aAAa;AAAA,EACb,WAAW;AAAA;AAAA,EAEX,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA;AAAA,EAEb,YAAY;AAAA,EACZ,aAAa;AAAA;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AACf;AAMO,SAAS,kBACd,MAC+B;AAC/B,MAAI,CAAC,KAAM,QAAO;AAClB,SAAO,4BAA4B,IAAI;AACzC;AAMO,SAAS,kBACd,OACA,MACM;AACN,MAAI,CAAC,KAAM;AAEX,QAAM,cAAc,kBAAkB,IAAI;AAC1C,MAAI,CAAC,aAAa;AAChB,UAAM,aAAa,OAAO,KAAK,2BAA2B;AAC1D,UAAM,IAAI;AAAA,MACR,iBAAiB,IAAI,gBAAgB,KAAK,+EACoC,WAAW,KAAK,IAAI,CAAC;AAAA,IAAA;AAAA,EAGvG;AACF;AAMO,SAAS,uBACd,OACA,gBACM;AACN,MAAI,mBAAmB,OAAW;AAGlC,QAAM,YAAY;AAClB,MAAI,iBAAiB,KAAK,iBAAiB,WAAW;AACpD,UAAM,IAAI;AAAA,MACR,2BAA2B,cAAc,gBAAgB,KAAK,4BACnC,SAAS;AAAA,IAAA;AAAA,EAExC;AACF;AAKO,SAAS,eAAe,SAGtB;AACP,QAAM,EAAE,QAAQ,MAAA,IAAU;AAC1B,MAAI,CAAC,UAAU,OAAO,KAAA,EAAO,WAAW,GAAG;AACzC,UAAM,IAAI,MAAM,qCAAqC,KAAK,IAAI;AAAA,EAChE;AACF;"}
1
+ {"version":3,"file":"image-provider-options.js","sources":["../../../src/image/image-provider-options.ts"],"sourcesContent":["import type { GeminiImageModels } from '../model-meta'\nimport type {\n ImagePromptLanguage,\n PersonGeneration,\n SafetyFilterLevel,\n} from '@google/genai'\n\n// Re-export SDK types so users can use them directly\nexport type { ImagePromptLanguage, PersonGeneration, SafetyFilterLevel }\n\n/**\n * Gemini Imagen aspect ratio options\n * Controls the aspect ratio of generated images\n */\nexport type GeminiAspectRatio =\n | '1:1'\n | '3:4'\n | '4:3'\n | '9:16'\n | '16:9'\n | '9:21'\n | '21:9'\n\n/**\n * Provider options for Gemini image generation\n * These options match the @google/genai GenerateImagesConfig interface\n * and can be spread directly into the API request.\n */\nexport interface GeminiImageProviderOptions {\n /**\n * The aspect ratio of generated images\n * @default '1:1'\n */\n aspectRatio?: GeminiAspectRatio\n\n /**\n * Controls whether people can appear in generated images\n * Use PersonGeneration enum values: DONT_ALLOW, ALLOW_ADULT, ALLOW_ALL\n * @default 'ALLOW_ADULT'\n */\n personGeneration?: PersonGeneration\n\n /**\n * Safety filter level for content filtering\n * Use SafetyFilterLevel enum values\n */\n safetyFilterLevel?: SafetyFilterLevel\n\n /**\n * Optional seed for reproducible image generation\n * When the same seed is used with the same prompt and settings,\n * you should get similar (though not identical) results\n */\n seed?: number\n\n /**\n * Whether to add a SynthID watermark to generated images\n * SynthID helps identify AI-generated content\n * @default true\n */\n addWatermark?: boolean\n\n /**\n * Language of the prompt\n * Use ImagePromptLanguage enum values\n */\n language?: ImagePromptLanguage\n\n /**\n * Negative prompt - what to avoid in the generated image\n * Not all models support negative prompts\n */\n negativePrompt?: string\n\n /**\n * Output MIME type for the generated image\n * @default 'image/png'\n */\n outputMimeType?: 'image/png' | 'image/jpeg' | 'image/webp'\n\n /**\n * Compression quality for JPEG outputs (0-100)\n * Higher values mean better quality but larger file sizes\n * @default 75\n */\n outputCompressionQuality?: number\n\n /**\n * Controls how much the model adheres to the text prompt\n * Large values increase output and prompt alignment,\n * but may compromise image quality\n */\n guidanceScale?: number\n\n /**\n * Whether to use the prompt rewriting logic\n */\n enhancePrompt?: boolean\n\n /**\n * Whether to report the safety scores of each generated image\n * and the positive prompt in the response\n */\n includeSafetyAttributes?: boolean\n\n /**\n * Whether to include the Responsible AI filter reason\n * if the image is filtered out of the response\n */\n includeRaiReason?: boolean\n\n /**\n * Cloud Storage URI used to store the generated images\n */\n outputGcsUri?: string\n\n /**\n * User specified labels to track billing usage\n */\n labels?: Record<string, string>\n}\n\n/**\n * Model-specific provider options mapping\n * Currently all Imagen models use the same options structure\n */\nexport type GeminiImageModelProviderOptionsByName = {\n [K in GeminiImageModels]: GeminiImageProviderOptions\n}\n\n/**\n * Supported size strings for Gemini Imagen models\n * These map to aspect ratios internally\n */\nexport type GeminiImageSize =\n | '1024x1024'\n | '512x512'\n | '1024x768'\n | '1536x1024'\n | '1792x1024'\n | '1920x1080'\n | '768x1024'\n | '1024x1536'\n | '1024x1792'\n | '1080x1920'\n\n/**\n * Aspect ratios supported by Gemini native image models (via generateContent API).\n * Matches the SDK's ImageConfig.aspectRatio values.\n */\nexport type GeminiNativeImageAspectRatio =\n | '1:1'\n | '2:3'\n | '3:2'\n | '3:4'\n | '4:3'\n | '9:16'\n | '16:9'\n | '21:9'\n\n/**\n * Resolution tiers for Gemini native image models.\n * Matches the SDK's ImageConfig.imageSize values.\n */\nexport type GeminiNativeImageResolution = '1K' | '2K' | '4K'\n\n/**\n * Template literal size type for Gemini native image models: \"16:9_4K\", \"1:1_2K\", etc.\n */\nexport type GeminiNativeImageSize =\n `${GeminiNativeImageAspectRatio}_${GeminiNativeImageResolution}`\n\n/**\n * Gemini native image models that use the generateContent API path.\n * These models support template literal sizes (aspectRatio_resolution).\n */\nexport type GeminiNativeImageModels =\n | 'gemini-3.1-flash-image-preview'\n | 'gemini-3-pro-image-preview'\n | 'gemini-2.5-flash-image'\n | 'gemini-2.0-flash-preview-image-generation'\n\n/**\n * Model-specific size options mapping.\n * Gemini native image models use template literal sizes, Imagen models use pixel sizes.\n */\nexport type GeminiImageModelSizeByName = {\n [K in GeminiNativeImageModels]: GeminiNativeImageSize\n} & {\n [K in Exclude<GeminiImageModels, GeminiNativeImageModels>]: GeminiImageSize\n}\n\n/**\n * Valid sizes for Gemini Imagen models\n * Gemini uses aspect ratios, but we map common WIDTHxHEIGHT formats to aspect ratios\n * These are approximate mappings based on common image dimensions\n */\nexport const GEMINI_SIZE_TO_ASPECT_RATIO: Record<string, GeminiAspectRatio> = {\n // Square\n '1024x1024': '1:1',\n '512x512': '1:1',\n // Landscape\n '1024x768': '4:3',\n '1536x1024': '4:3',\n '1792x1024': '16:9',\n '1920x1080': '16:9',\n // Portrait\n '768x1024': '3:4',\n '1024x1536': '3:4', // Inverted\n '1024x1792': '9:16',\n '1080x1920': '9:16',\n}\n\n/**\n * Maps a WIDTHxHEIGHT size string to a Gemini aspect ratio\n * Returns undefined if the size cannot be mapped\n */\nexport function sizeToAspectRatio(\n size: string | undefined,\n): GeminiAspectRatio | undefined {\n if (!size) return undefined\n return GEMINI_SIZE_TO_ASPECT_RATIO[size]\n}\n\n/**\n * Validates that the provided size can be mapped to an aspect ratio\n * Throws an error if the size is invalid\n */\nexport function validateImageSize(\n model: string,\n size: string | undefined,\n): void {\n if (!size) return\n\n const aspectRatio = sizeToAspectRatio(size)\n if (!aspectRatio) {\n const validSizes = Object.keys(GEMINI_SIZE_TO_ASPECT_RATIO)\n throw new Error(\n `Invalid size \"${size}\" for model \"${model}\". ` +\n `Gemini Imagen uses aspect ratios. Valid sizes that map to aspect ratios: ${validSizes.join(', ')}. ` +\n `Alternatively, use providerOptions.aspectRatio directly with values: 1:1, 3:4, 4:3, 9:16, 16:9, 9:21, 21:9`,\n )\n }\n}\n\n/**\n * Validates the number of images requested\n * Imagen models support 1-8 images per request (varies by model)\n */\nexport function validateNumberOfImages(\n model: string,\n numberOfImages: number | undefined,\n): void {\n if (numberOfImages === undefined) return\n\n // Most Imagen models support 1-4 images, some support up to 8\n const maxImages = 4\n if (numberOfImages < 1 || numberOfImages > maxImages) {\n throw new Error(\n `Invalid numberOfImages \"${numberOfImages}\" for model \"${model}\". ` +\n `Must be between 1 and ${maxImages}.`,\n )\n }\n}\n\n/**\n * Validates the prompt is not empty\n */\nexport function validatePrompt(options: {\n prompt: string\n model: string\n}): void {\n const { prompt, model } = options\n if (!prompt || prompt.trim().length === 0) {\n throw new Error(`Prompt cannot be empty for model \"${model}\".`)\n }\n}\n\n/**\n * Parses a Gemini native image size string into its components.\n * Format: \"aspectRatio_resolution\" e.g. \"16:9_4K\" → { aspectRatio: \"16:9\", resolution: \"4K\" }\n */\nexport function parseNativeImageSize(\n size: string,\n): { aspectRatio: string; resolution: string } | undefined {\n const match = size.match(/^(\\d+:\\d+)_(.+)$/)\n if (!match) return undefined\n return { aspectRatio: match[1]!, resolution: match[2]! }\n}\n"],"names":[],"mappings":"AAqMO,MAAM,8BAAiE;AAAA;AAAA,EAE5E,aAAa;AAAA,EACb,WAAW;AAAA;AAAA,EAEX,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA;AAAA,EAEb,YAAY;AAAA,EACZ,aAAa;AAAA;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AACf;AAMO,SAAS,kBACd,MAC+B;AAC/B,MAAI,CAAC,KAAM,QAAO;AAClB,SAAO,4BAA4B,IAAI;AACzC;AAMO,SAAS,kBACd,OACA,MACM;AACN,MAAI,CAAC,KAAM;AAEX,QAAM,cAAc,kBAAkB,IAAI;AAC1C,MAAI,CAAC,aAAa;AAChB,UAAM,aAAa,OAAO,KAAK,2BAA2B;AAC1D,UAAM,IAAI;AAAA,MACR,iBAAiB,IAAI,gBAAgB,KAAK,+EACoC,WAAW,KAAK,IAAI,CAAC;AAAA,IAAA;AAAA,EAGvG;AACF;AAMO,SAAS,uBACd,OACA,gBACM;AACN,MAAI,mBAAmB,OAAW;AAGlC,QAAM,YAAY;AAClB,MAAI,iBAAiB,KAAK,iBAAiB,WAAW;AACpD,UAAM,IAAI;AAAA,MACR,2BAA2B,cAAc,gBAAgB,KAAK,4BACnC,SAAS;AAAA,IAAA;AAAA,EAExC;AACF;AAKO,SAAS,eAAe,SAGtB;AACP,QAAM,EAAE,QAAQ,MAAA,IAAU;AAC1B,MAAI,CAAC,UAAU,OAAO,KAAA,EAAO,WAAW,GAAG;AACzC,UAAM,IAAI,MAAM,qCAAqC,KAAK,IAAI;AAAA,EAChE;AACF;AAMO,SAAS,qBACd,MACyD;AACzD,QAAM,QAAQ,KAAK,MAAM,kBAAkB;AAC3C,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO,EAAE,aAAa,MAAM,CAAC,GAAI,YAAY,MAAM,CAAC,EAAA;AACtD;"}
@@ -6,6 +6,7 @@ export type { GeminiImageProviderOptions, GeminiImageModelProviderOptionsByName,
6
6
  * @experimental Gemini TTS is an experimental feature and may change.
7
7
  */
8
8
  export { GeminiTTSAdapter, createGeminiSpeech, geminiSpeech, type GeminiTTSConfig, type GeminiTTSProviderOptions, } from './adapters/tts.js';
9
+ export { GEMINI_MODELS } from './model-meta.js';
9
10
  export { GEMINI_MODELS as GeminiTextModels } from './model-meta.js';
10
11
  export { GEMINI_IMAGE_MODELS as GeminiImageModels } from './model-meta.js';
11
12
  export { GEMINI_TTS_MODELS as GeminiTTSModels } from './model-meta.js';
package/dist/esm/index.js CHANGED
@@ -2,8 +2,9 @@ import { GeminiTextAdapter, createGeminiChat, geminiText } from "./adapters/text
2
2
  import { GeminiSummarizeAdapter, GeminiSummarizeModels, createGeminiSummarize, geminiSummarize } from "./adapters/summarize.js";
3
3
  import { GeminiImageAdapter, createGeminiImage, geminiImage } from "./adapters/image.js";
4
4
  import { GeminiTTSAdapter, createGeminiSpeech, geminiSpeech } from "./adapters/tts.js";
5
- import { GEMINI_IMAGE_MODELS, GEMINI_TTS_MODELS, GEMINI_TTS_VOICES, GEMINI_MODELS } from "./model-meta.js";
5
+ import { GEMINI_MODELS, GEMINI_IMAGE_MODELS, GEMINI_TTS_MODELS, GEMINI_TTS_VOICES, GEMINI_MODELS as GEMINI_MODELS2 } from "./model-meta.js";
6
6
  export {
7
+ GEMINI_MODELS,
7
8
  GeminiImageAdapter,
8
9
  GEMINI_IMAGE_MODELS as GeminiImageModels,
9
10
  GeminiSummarizeAdapter,
@@ -12,7 +13,7 @@ export {
12
13
  GEMINI_TTS_MODELS as GeminiTTSModels,
13
14
  GEMINI_TTS_VOICES as GeminiTTSVoices,
14
15
  GeminiTextAdapter,
15
- GEMINI_MODELS as GeminiTextModels,
16
+ GEMINI_MODELS2 as GeminiTextModels,
16
17
  createGeminiChat,
17
18
  createGeminiImage,
18
19
  createGeminiSpeech,
@@ -1,4 +1,23 @@
1
1
  import { GeminiCachedContentOptions, GeminiCommonConfigOptions, GeminiSafetyOptions, GeminiStructuredOutputOptions, GeminiThinkingAdvancedOptions, GeminiThinkingOptions, GeminiToolConfigOptions } from './text/text-provider-options.js';
2
+ declare const GEMINI_3_1_PRO: {
3
+ readonly name: "gemini-3.1-pro-preview";
4
+ readonly max_input_tokens: 1048576;
5
+ readonly max_output_tokens: 65536;
6
+ readonly knowledge_cutoff: "2025-01-01";
7
+ readonly supports: {
8
+ readonly input: ["text", "image", "audio", "video", "document"];
9
+ readonly output: ["text"];
10
+ readonly capabilities: ["batch_api", "caching", "code_execution", "file_search", "function_calling", "search_grounding", "structured_output", "thinking", "url_context"];
11
+ };
12
+ readonly pricing: {
13
+ readonly input: {
14
+ readonly normal: 2.5;
15
+ };
16
+ readonly output: {
17
+ readonly normal: 15;
18
+ };
19
+ };
20
+ };
2
21
  declare const GEMINI_3_PRO: {
3
22
  readonly name: "gemini-3-pro-preview";
4
23
  readonly max_input_tokens: 1048576;
@@ -284,10 +303,10 @@ const VEO_2 = {
284
303
  GeminiGenerationConfigOptions &
285
304
  GeminiCachedContentOptions
286
305
  > */
287
- export declare const GEMINI_MODELS: readonly ["gemini-3-pro-preview", "gemini-3-flash-preview", "gemini-2.5-pro", "gemini-2.5-flash", "gemini-2.5-flash-preview-09-2025", "gemini-2.5-flash-lite", "gemini-2.5-flash-lite-preview-09-2025", "gemini-2.0-flash", "gemini-2.0-flash-lite"];
306
+ export declare const GEMINI_MODELS: readonly ["gemini-3.1-pro-preview", "gemini-3-pro-preview", "gemini-3-flash-preview", "gemini-2.5-pro", "gemini-2.5-flash", "gemini-2.5-flash-preview-09-2025", "gemini-2.5-flash-lite", "gemini-2.5-flash-lite-preview-09-2025", "gemini-2.0-flash", "gemini-2.0-flash-lite"];
288
307
  export type GeminiModels = (typeof GEMINI_MODELS)[number];
289
308
  export type GeminiImageModels = (typeof GEMINI_IMAGE_MODELS)[number];
290
- export declare const GEMINI_IMAGE_MODELS: readonly ["gemini-3-pro-image-preview", "gemini-2.5-flash-image", "gemini-2.0-flash-preview-image-generation", "imagen-3.0-generate-002", "imagen-4.0-generate-001", "imagen-4.0-fast-generate-001", "imagen-4.0-ultra-generate-001"];
309
+ export declare const GEMINI_IMAGE_MODELS: readonly ["gemini-3.1-flash-image-preview", "gemini-3-pro-image-preview", "gemini-2.5-flash-image", "gemini-2.0-flash-preview-image-generation", "imagen-3.0-generate-002", "imagen-4.0-generate-001", "imagen-4.0-fast-generate-001", "imagen-4.0-ultra-generate-001"];
291
310
  /**
292
311
  * Text-to-speech models
293
312
  * @experimental Gemini TTS is an experimental feature and may change.
@@ -300,6 +319,7 @@ export declare const GEMINI_TTS_MODELS: readonly ["gemini-2.5-flash-preview-tts"
300
319
  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
320
  export type GeminiTTSVoice = (typeof GEMINI_TTS_VOICES)[number];
302
321
  export type GeminiChatModelProviderOptionsByName = {
322
+ [GEMINI_3_1_PRO.name]: GeminiToolConfigOptions & GeminiSafetyOptions & GeminiCommonConfigOptions & GeminiCachedContentOptions & GeminiStructuredOutputOptions & GeminiThinkingOptions & GeminiThinkingAdvancedOptions;
303
323
  [GEMINI_3_PRO.name]: GeminiToolConfigOptions & GeminiSafetyOptions & GeminiCommonConfigOptions & GeminiCachedContentOptions & GeminiStructuredOutputOptions & GeminiThinkingOptions & GeminiThinkingAdvancedOptions;
304
324
  [GEMINI_3_FLASH.name]: GeminiToolConfigOptions & GeminiSafetyOptions & GeminiCommonConfigOptions & GeminiCachedContentOptions & GeminiStructuredOutputOptions & GeminiThinkingOptions & GeminiThinkingAdvancedOptions;
305
325
  [GEMINI_2_5_PRO.name]: GeminiToolConfigOptions & GeminiSafetyOptions & GeminiCommonConfigOptions & GeminiCachedContentOptions & GeminiStructuredOutputOptions & GeminiThinkingOptions;
@@ -324,6 +344,7 @@ export type GeminiChatModelProviderOptionsByName = {
324
344
  * @see https://ai.google.dev/gemini-api/docs/document-processing
325
345
  */
326
346
  export type GeminiModelInputModalitiesByName = {
347
+ [GEMINI_3_1_PRO.name]: typeof GEMINI_3_1_PRO.supports.input;
327
348
  [GEMINI_3_PRO.name]: typeof GEMINI_3_PRO.supports.input;
328
349
  [GEMINI_3_FLASH.name]: typeof GEMINI_3_FLASH.supports.input;
329
350
  [GEMINI_2_5_PRO.name]: typeof GEMINI_2_5_PRO.supports.input;
@@ -1,3 +1,6 @@
1
+ const GEMINI_3_1_PRO = {
2
+ name: "gemini-3.1-pro-preview"
3
+ };
1
4
  const GEMINI_3_PRO = {
2
5
  name: "gemini-3-pro-preview"
3
6
  };
@@ -7,6 +10,9 @@ const GEMINI_3_FLASH = {
7
10
  const GEMINI_3_PRO_IMAGE = {
8
11
  name: "gemini-3-pro-image-preview"
9
12
  };
13
+ const GEMINI_3_1_FLASH_IMAGE = {
14
+ name: "gemini-3.1-flash-image-preview"
15
+ };
10
16
  const GEMINI_2_5_PRO = {
11
17
  name: "gemini-2.5-pro"
12
18
  };
@@ -53,6 +59,7 @@ const IMAGEN_3 = {
53
59
  name: "imagen-3.0-generate-002"
54
60
  };
55
61
  const GEMINI_MODELS = [
62
+ GEMINI_3_1_PRO.name,
56
63
  GEMINI_3_PRO.name,
57
64
  GEMINI_3_FLASH.name,
58
65
  GEMINI_2_5_PRO.name,
@@ -64,6 +71,7 @@ const GEMINI_MODELS = [
64
71
  GEMINI_2_FLASH_LITE.name
65
72
  ];
66
73
  const GEMINI_IMAGE_MODELS = [
74
+ GEMINI_3_1_FLASH_IMAGE.name,
67
75
  GEMINI_3_PRO_IMAGE.name,
68
76
  GEMINI_2_5_FLASH_IMAGE.name,
69
77
  GEMINI_2_FLASH_IMAGE.name,
@@ -1 +1 @@
1
- {"version":3,"file":"model-meta.js","sources":["../../src/model-meta.ts"],"sourcesContent":["import type {\n GeminiCachedContentOptions,\n GeminiCommonConfigOptions,\n GeminiSafetyOptions,\n GeminiStructuredOutputOptions,\n 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;"}
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_1_PRO = {\n name: 'gemini-3.1-pro-preview',\n max_input_tokens: 1_048_576,\n max_output_tokens: 65_536,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'image', 'audio', 'video', 'document'],\n output: ['text'],\n capabilities: [\n 'batch_api',\n 'caching',\n '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_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_3_1_FLASH_IMAGE = {\n name: 'gemini-3.1-flash-image-preview',\n max_input_tokens: 65_536,\n max_output_tokens: 65_536,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'image'],\n output: ['text', 'image'],\n capabilities: [\n 'batch_api',\n 'image_generation',\n 'search_grounding',\n 'structured_output',\n 'thinking',\n ],\n },\n pricing: {\n input: {\n normal: 0.25,\n },\n output: {\n normal: 1.5,\n },\n },\n} as const satisfies ModelMeta<\n GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions\n>\n\nconst GEMINI_2_5_PRO = {\n name: 'gemini-2.5-pro',\n max_input_tokens: 1_048_576,\n max_output_tokens: 65_536,\n knowledge_cutoff: '2025-01-01',\n supports: {\n input: ['text', 'image', 'audio', 'video', 'document'],\n output: ['text'],\n capabilities: [\n 'batch_api',\n 'caching',\n '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_1_PRO.name,\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_1_FLASH_IMAGE.name,\n GEMINI_3_PRO_IMAGE.name,\n GEMINI_2_5_FLASH_IMAGE.name,\n GEMINI_2_FLASH_IMAGE.name,\n IMAGEN_3.name,\n IMAGEN_4_GENERATE.name,\n IMAGEN_4_GENERATE_FAST.name,\n IMAGEN_4_GENERATE_ULTRA.name,\n] as const\n\n/**\n * Text-to-speech models\n * @experimental Gemini TTS is an experimental feature and may change.\n */\nexport const GEMINI_TTS_MODELS = [\n GEMINI_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_1_PRO.name]: GeminiToolConfigOptions &\n GeminiSafetyOptions &\n GeminiCommonConfigOptions &\n GeminiCachedContentOptions &\n GeminiStructuredOutputOptions &\n GeminiThinkingOptions &\n GeminiThinkingAdvancedOptions\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_1_PRO.name]: typeof GEMINI_3_1_PRO.supports.input\n [GEMINI_3_PRO.name]: typeof GEMINI_3_PRO.supports.input\n [GEMINI_3_FLASH.name]: typeof GEMINI_3_FLASH.supports.input\n [GEMINI_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,iBAAiB;AAAA,EACrB,MAAM;AA2BR;AAUA,MAAM,eAAe;AAAA,EACnB,MAAM;AA2BR;AAUA,MAAM,iBAAiB;AAAA,EACrB,MAAM;AA2BR;AAUA,MAAM,qBAAqB;AAAA,EACzB,MAAM;AAuBR;AAUA,MAAM,yBAAyB;AAAA,EAC7B,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,eAAe;AAAA,EACf,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,uBAAuB;AAAA,EACvB,mBAAmB;AAAA,EACnB,uBAAuB;AAAA,EACvB,qBAAqB;AAAA,EACrB,SAAS;AAAA,EACT,kBAAkB;AAAA,EAClB,uBAAuB;AAAA,EACvB,wBAAwB;AAC1B;AAMO,MAAM,oBAAoB;AAAA,EAC/B,qBAAqB;AAAA,EACrB,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;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/ai-gemini",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "Google Gemini adapter for TanStack AI",
5
5
  "author": "",
6
6
  "license": "MIT",
@@ -30,15 +30,15 @@
30
30
  "adapter"
31
31
  ],
32
32
  "dependencies": {
33
- "@google/genai": "^1.30.0"
33
+ "@google/genai": "^1.43.0"
34
34
  },
35
35
  "peerDependencies": {
36
- "@tanstack/ai": "^0.5.0"
36
+ "@tanstack/ai": "^0.6.1"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@vitest/coverage-v8": "4.0.14",
40
40
  "vite": "^7.2.7",
41
- "@tanstack/ai": "0.5.0"
41
+ "@tanstack/ai": "0.6.1"
42
42
  },
43
43
  "scripts": {
44
44
  "build": "vite build",
@@ -5,6 +5,7 @@ import {
5
5
  getGeminiApiKeyFromEnv,
6
6
  } from '../utils'
7
7
  import {
8
+ parseNativeImageSize,
8
9
  sizeToAspectRatio,
9
10
  validateImageSize,
10
11
  validateNumberOfImages,
@@ -22,6 +23,8 @@ import type {
22
23
  ImageGenerationResult,
23
24
  } from '@tanstack/ai'
24
25
  import type {
26
+ GenerateContentConfig,
27
+ GenerateContentResponse,
25
28
  GenerateImagesConfig,
26
29
  GenerateImagesResponse,
27
30
  GoogleGenAI,
@@ -39,14 +42,16 @@ export type GeminiImageModel = (typeof GEMINI_IMAGE_MODELS)[number]
39
42
  /**
40
43
  * Gemini Image Generation Adapter
41
44
  *
42
- * Tree-shakeable adapter for Gemini Imagen image generation functionality.
43
- * Supports Imagen 3 and Imagen 4 models.
45
+ * Tree-shakeable adapter for Gemini image generation functionality.
46
+ * Supports Imagen 3/4 models (via generateImages API) and Gemini native
47
+ * image models like Nano Banana 2 (via generateContent API).
44
48
  *
45
49
  * Features:
46
50
  * - Aspect ratio-based image sizing
47
51
  * - Person generation controls
48
52
  * - Safety filtering
49
53
  * - Watermark options
54
+ * - Extended resolution tiers (Nano Banana 2)
50
55
  */
51
56
  export class GeminiImageAdapter<
52
57
  TModel extends GeminiImageModel,
@@ -76,15 +81,19 @@ export class GeminiImageAdapter<
76
81
  async generateImages(
77
82
  options: ImageGenerationOptions<GeminiImageProviderOptions>,
78
83
  ): Promise<ImageGenerationResult> {
79
- const { model, prompt, numberOfImages, size } = options
84
+ const { model, prompt } = options
80
85
 
81
- // Validate inputs
82
86
  validatePrompt({ prompt, model })
83
- validateImageSize(model, size)
84
- validateNumberOfImages(model, numberOfImages)
85
87
 
86
- // Build request config
87
- const config = this.buildConfig(options)
88
+ if (this.isGeminiImageModel(model)) {
89
+ return this.generateWithGeminiApi(options)
90
+ }
91
+
92
+ // Imagen models path (generateImages API)
93
+ validateImageSize(model, options.size)
94
+ validateNumberOfImages(model, options.numberOfImages)
95
+
96
+ const config = this.buildImagenConfig(options)
88
97
 
89
98
  const response = await this.client.models.generateImages({
90
99
  model,
@@ -92,10 +101,78 @@ export class GeminiImageAdapter<
92
101
  config,
93
102
  })
94
103
 
95
- return this.transformResponse(model, response)
104
+ return this.transformImagenResponse(model, response)
105
+ }
106
+
107
+ private isGeminiImageModel(model: string): boolean {
108
+ return model.startsWith('gemini-')
109
+ }
110
+
111
+ private async generateWithGeminiApi(
112
+ options: ImageGenerationOptions<GeminiImageProviderOptions>,
113
+ ): Promise<ImageGenerationResult> {
114
+ const { model, prompt, size, numberOfImages, modelOptions } = options
115
+
116
+ const parsedSize = size ? parseNativeImageSize(size) : undefined
117
+
118
+ // The generateContent API has no numberOfImages parameter.
119
+ // Instead, augment the prompt to request multiple images when needed.
120
+ const augmentedPrompt =
121
+ numberOfImages && numberOfImages > 1
122
+ ? `${prompt} Generate ${numberOfImages} distinct images.`
123
+ : prompt
124
+
125
+ const config: GenerateContentConfig = {
126
+ // Include TEXT so the model can interleave descriptions between images
127
+ responseModalities: ['TEXT', 'IMAGE'],
128
+ ...(parsedSize && {
129
+ imageConfig: {
130
+ ...(parsedSize.aspectRatio && {
131
+ aspectRatio: parsedSize.aspectRatio,
132
+ }),
133
+ ...(parsedSize.resolution && {
134
+ imageSize: parsedSize.resolution,
135
+ }),
136
+ },
137
+ }),
138
+ ...modelOptions,
139
+ }
140
+
141
+ const response = await this.client.models.generateContent({
142
+ model,
143
+ contents: augmentedPrompt,
144
+ config,
145
+ })
146
+
147
+ return this.transformGeminiResponse(model, response)
148
+ }
149
+
150
+ private transformGeminiResponse(
151
+ model: string,
152
+ response: GenerateContentResponse,
153
+ ): ImageGenerationResult {
154
+ const images: Array<GeneratedImage> = []
155
+ const parts = response.candidates?.[0]?.content?.parts ?? []
156
+
157
+ for (const part of parts) {
158
+ if (
159
+ part.inlineData?.data &&
160
+ typeof part.inlineData.data === 'string' &&
161
+ part.inlineData.data.length > 0
162
+ ) {
163
+ images.push({ b64Json: part.inlineData.data })
164
+ }
165
+ }
166
+
167
+ return {
168
+ id: generateId(this.name),
169
+ model,
170
+ images,
171
+ usage: undefined,
172
+ }
96
173
  }
97
174
 
98
- private buildConfig(
175
+ private buildImagenConfig(
99
176
  options: ImageGenerationOptions<GeminiImageProviderOptions>,
100
177
  ): GenerateImagesConfig {
101
178
  const { size, numberOfImages, modelOptions } = options
@@ -108,7 +185,7 @@ export class GeminiImageAdapter<
108
185
  }
109
186
  }
110
187
 
111
- private transformResponse(
188
+ private transformImagenResponse(
112
189
  model: string,
113
190
  response: GenerateImagesResponse,
114
191
  ): ImageGenerationResult {
@@ -145,11 +145,49 @@ export type GeminiImageSize =
145
145
  | '1080x1920'
146
146
 
147
147
  /**
148
- * Model-specific size options mapping
149
- * All Imagen models use the same size options
148
+ * Aspect ratios supported by Gemini native image models (via generateContent API).
149
+ * Matches the SDK's ImageConfig.aspectRatio values.
150
+ */
151
+ export type GeminiNativeImageAspectRatio =
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
+ * Resolution tiers for Gemini native image models.
163
+ * Matches the SDK's ImageConfig.imageSize values.
164
+ */
165
+ export type GeminiNativeImageResolution = '1K' | '2K' | '4K'
166
+
167
+ /**
168
+ * Template literal size type for Gemini native image models: "16:9_4K", "1:1_2K", etc.
169
+ */
170
+ export type GeminiNativeImageSize =
171
+ `${GeminiNativeImageAspectRatio}_${GeminiNativeImageResolution}`
172
+
173
+ /**
174
+ * Gemini native image models that use the generateContent API path.
175
+ * These models support template literal sizes (aspectRatio_resolution).
176
+ */
177
+ export type GeminiNativeImageModels =
178
+ | 'gemini-3.1-flash-image-preview'
179
+ | 'gemini-3-pro-image-preview'
180
+ | 'gemini-2.5-flash-image'
181
+ | 'gemini-2.0-flash-preview-image-generation'
182
+
183
+ /**
184
+ * Model-specific size options mapping.
185
+ * Gemini native image models use template literal sizes, Imagen models use pixel sizes.
150
186
  */
151
187
  export type GeminiImageModelSizeByName = {
152
- [K in GeminiImageModels]: GeminiImageSize
188
+ [K in GeminiNativeImageModels]: GeminiNativeImageSize
189
+ } & {
190
+ [K in Exclude<GeminiImageModels, GeminiNativeImageModels>]: GeminiImageSize
153
191
  }
154
192
 
155
193
  /**
@@ -237,3 +275,15 @@ export function validatePrompt(options: {
237
275
  throw new Error(`Prompt cannot be empty for model "${model}".`)
238
276
  }
239
277
  }
278
+
279
+ /**
280
+ * Parses a Gemini native image size string into its components.
281
+ * Format: "aspectRatio_resolution" e.g. "16:9_4K" → { aspectRatio: "16:9", resolution: "4K" }
282
+ */
283
+ export function parseNativeImageSize(
284
+ size: string,
285
+ ): { aspectRatio: string; resolution: string } | undefined {
286
+ const match = size.match(/^(\d+:\d+)_(.+)$/)
287
+ if (!match) return undefined
288
+ return { aspectRatio: match[1]!, resolution: match[2]! }
289
+ }
package/src/index.ts CHANGED
@@ -52,6 +52,7 @@ export {
52
52
  } from './adapters/tts'
53
53
 
54
54
  // Re-export models from model-meta for convenience
55
+ export { GEMINI_MODELS } from './model-meta'
55
56
  export { GEMINI_MODELS as GeminiTextModels } from './model-meta'
56
57
  export { GEMINI_IMAGE_MODELS as GeminiImageModels } from './model-meta'
57
58
  export { GEMINI_TTS_MODELS as GeminiTTSModels } from './model-meta'
package/src/model-meta.ts CHANGED
@@ -47,6 +47,44 @@ interface ModelMeta<TProviderOptions = unknown> {
47
47
  providerOptions?: TProviderOptions
48
48
  }
49
49
 
50
+ const GEMINI_3_1_PRO = {
51
+ name: 'gemini-3.1-pro-preview',
52
+ max_input_tokens: 1_048_576,
53
+ max_output_tokens: 65_536,
54
+ knowledge_cutoff: '2025-01-01',
55
+ supports: {
56
+ input: ['text', 'image', 'audio', 'video', 'document'],
57
+ output: ['text'],
58
+ capabilities: [
59
+ 'batch_api',
60
+ 'caching',
61
+ 'code_execution',
62
+ 'file_search',
63
+ 'function_calling',
64
+ 'search_grounding',
65
+ 'structured_output',
66
+ 'thinking',
67
+ 'url_context',
68
+ ],
69
+ },
70
+ pricing: {
71
+ input: {
72
+ normal: 2.5,
73
+ },
74
+ output: {
75
+ normal: 15,
76
+ },
77
+ },
78
+ } as const satisfies ModelMeta<
79
+ GeminiToolConfigOptions &
80
+ GeminiSafetyOptions &
81
+ GeminiCommonConfigOptions &
82
+ GeminiCachedContentOptions &
83
+ GeminiStructuredOutputOptions &
84
+ GeminiThinkingOptions &
85
+ GeminiThinkingAdvancedOptions
86
+ >
87
+
50
88
  const GEMINI_3_PRO = {
51
89
  name: 'gemini-3-pro-preview',
52
90
  max_input_tokens: 1_048_576,
@@ -157,6 +195,39 @@ const GEMINI_3_PRO_IMAGE = {
157
195
  GeminiThinkingAdvancedOptions
158
196
  >
159
197
 
198
+ const GEMINI_3_1_FLASH_IMAGE = {
199
+ name: 'gemini-3.1-flash-image-preview',
200
+ max_input_tokens: 65_536,
201
+ max_output_tokens: 65_536,
202
+ knowledge_cutoff: '2025-01-01',
203
+ supports: {
204
+ input: ['text', 'image'],
205
+ output: ['text', 'image'],
206
+ capabilities: [
207
+ 'batch_api',
208
+ 'image_generation',
209
+ 'search_grounding',
210
+ 'structured_output',
211
+ 'thinking',
212
+ ],
213
+ },
214
+ pricing: {
215
+ input: {
216
+ normal: 0.25,
217
+ },
218
+ output: {
219
+ normal: 1.5,
220
+ },
221
+ },
222
+ } as const satisfies ModelMeta<
223
+ GeminiToolConfigOptions &
224
+ GeminiSafetyOptions &
225
+ GeminiCommonConfigOptions &
226
+ GeminiCachedContentOptions &
227
+ GeminiStructuredOutputOptions &
228
+ GeminiThinkingOptions
229
+ >
230
+
160
231
  const GEMINI_2_5_PRO = {
161
232
  name: 'gemini-2.5-pro',
162
233
  max_input_tokens: 1_048_576,
@@ -820,6 +891,7 @@ const VEO_2 = {
820
891
  } as const */
821
892
 
822
893
  export const GEMINI_MODELS = [
894
+ GEMINI_3_1_PRO.name,
823
895
  GEMINI_3_PRO.name,
824
896
  GEMINI_3_FLASH.name,
825
897
  GEMINI_2_5_PRO.name,
@@ -836,6 +908,7 @@ export type GeminiModels = (typeof GEMINI_MODELS)[number]
836
908
  export type GeminiImageModels = (typeof GEMINI_IMAGE_MODELS)[number]
837
909
 
838
910
  export const GEMINI_IMAGE_MODELS = [
911
+ GEMINI_3_1_FLASH_IMAGE.name,
839
912
  GEMINI_3_PRO_IMAGE.name,
840
913
  GEMINI_2_5_FLASH_IMAGE.name,
841
914
  GEMINI_2_FLASH_IMAGE.name,
@@ -911,6 +984,13 @@ export type GeminiTTSVoice = (typeof GEMINI_TTS_VOICES)[number]
911
984
  // Manual type map for per-model provider options
912
985
  export type GeminiChatModelProviderOptionsByName = {
913
986
  // Models with thinking and structured output support
987
+ [GEMINI_3_1_PRO.name]: GeminiToolConfigOptions &
988
+ GeminiSafetyOptions &
989
+ GeminiCommonConfigOptions &
990
+ GeminiCachedContentOptions &
991
+ GeminiStructuredOutputOptions &
992
+ GeminiThinkingOptions &
993
+ GeminiThinkingAdvancedOptions
914
994
  [GEMINI_3_PRO.name]: GeminiToolConfigOptions &
915
995
  GeminiSafetyOptions &
916
996
  GeminiCommonConfigOptions &
@@ -983,6 +1063,7 @@ export type GeminiChatModelProviderOptionsByName = {
983
1063
  */
984
1064
  export type GeminiModelInputModalitiesByName = {
985
1065
  // Models with full multimodal support (text, image, audio, video, document)
1066
+ [GEMINI_3_1_PRO.name]: typeof GEMINI_3_1_PRO.supports.input
986
1067
  [GEMINI_3_PRO.name]: typeof GEMINI_3_PRO.supports.input
987
1068
  [GEMINI_3_FLASH.name]: typeof GEMINI_3_FLASH.supports.input
988
1069
  [GEMINI_2_5_PRO.name]: typeof GEMINI_2_5_PRO.supports.input