@umituz/react-native-ai-gemini-provider 1.6.0 → 1.8.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-ai-gemini-provider",
3
- "version": "1.6.0",
3
+ "version": "1.8.0",
4
4
  "description": "Google Gemini AI provider for React Native applications",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -14,10 +14,9 @@ export const GEMINI_MODELS = {
14
14
  PRO: "gemini-1.5-pro",
15
15
  },
16
16
 
17
- // Image generation models
17
+ // Image generation models (Imagen 4.0)
18
18
  IMAGE: {
19
- FLASH: "gemini-2.5-flash-preview-image-generation",
20
- FLASH_STABLE: "gemini-2.0-flash-preview-image-generation",
19
+ DEFAULT: "imagen-4.0-generate-001",
21
20
  },
22
21
 
23
22
  // Video understanding models
@@ -31,7 +30,7 @@ export const GEMINI_MODELS = {
31
30
  */
32
31
  export const DEFAULT_MODELS = {
33
32
  TEXT: GEMINI_MODELS.TEXT.FLASH,
34
- IMAGE: GEMINI_MODELS.IMAGE.FLASH,
33
+ IMAGE: GEMINI_MODELS.IMAGE.DEFAULT,
35
34
  VIDEO: GEMINI_MODELS.VIDEO.FLASH,
36
35
  } as const;
37
36
 
@@ -4,10 +4,7 @@
4
4
  */
5
5
 
6
6
  import { GoogleGenerativeAI, type GenerativeModel } from "@google/generative-ai";
7
- import {
8
- DEFAULT_MODELS,
9
- RESPONSE_MODALITIES,
10
- } from "../../domain/entities";
7
+ import { DEFAULT_MODELS } from "../../domain/entities";
11
8
  import type {
12
9
  GeminiConfig,
13
10
  GeminiContent,
@@ -257,83 +254,84 @@ class GeminiClientService {
257
254
  }
258
255
 
259
256
  /**
260
- * Generate image from prompt and/or input images
261
- * Uses centralized model config with responseModalities for image output
257
+ * Generate image from prompt using Imagen API
258
+ * Uses REST API endpoint: /v1beta/models/{model}:predict
262
259
  */
263
260
  async generateImage(
264
261
  prompt: string,
265
- images?: Array<{ base64: string; mimeType: string }>,
266
- config?: GeminiGenerationConfig,
262
+ _images?: Array<{ base64: string; mimeType: string }>,
263
+ _config?: GeminiGenerationConfig,
267
264
  ): Promise<GeminiImageGenerationResult> {
265
+ this.validateInitialization();
266
+
268
267
  const imageModel = this.config?.imageModel || DEFAULT_MODELS.IMAGE;
268
+ const apiKey = this.config?.apiKey;
269
269
 
270
270
  if (typeof __DEV__ !== "undefined" && __DEV__) {
271
271
  // eslint-disable-next-line no-console
272
- console.log("[GeminiClient] generateImage() called", {
272
+ console.log("[GeminiClient] generateImage() called (Imagen API)", {
273
273
  model: imageModel,
274
274
  promptLength: prompt.length,
275
- hasInputImages: !!images?.length,
276
- inputImagesCount: images?.length ?? 0,
277
275
  });
278
276
  }
279
277
 
280
- const parts: GeminiContent["parts"] = [{ text: prompt }];
278
+ const url = `https://generativelanguage.googleapis.com/v1beta/models/${imageModel}:predict`;
281
279
 
282
- // Add input images if provided (for image-to-image generation)
283
- if (images && images.length > 0) {
284
- for (const image of images) {
285
- const base64Data = image.base64.includes(",")
286
- ? image.base64.split(",")[1]
287
- : image.base64;
288
-
289
- parts.push({
290
- inlineData: {
291
- mimeType: image.mimeType,
292
- data: base64Data,
293
- },
294
- });
295
- }
280
+ const requestBody = {
281
+ instances: [{ prompt }],
282
+ parameters: {
283
+ sampleCount: 1,
284
+ aspectRatio: "1:1",
285
+ },
286
+ };
287
+
288
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
289
+ // eslint-disable-next-line no-console
290
+ console.log("[GeminiClient] Imagen API request", {
291
+ url,
292
+ prompt: prompt.substring(0, 100) + "...",
293
+ });
296
294
  }
297
295
 
298
- const contents: GeminiContent[] = [{ parts, role: "user" }];
296
+ const response = await this.executeWithRetry(async () => {
297
+ const res = await fetch(url, {
298
+ method: "POST",
299
+ headers: {
300
+ "Content-Type": "application/json",
301
+ "x-goog-api-key": apiKey!,
302
+ },
303
+ body: JSON.stringify(requestBody),
304
+ });
299
305
 
300
- // Image generation requires responseModalities to include IMAGE
301
- const imageConfig: GeminiGenerationConfig = {
302
- ...config,
303
- responseModalities: [...RESPONSE_MODALITIES.TEXT_AND_IMAGE],
304
- };
306
+ if (!res.ok) {
307
+ const errorText = await res.text();
308
+ throw new Error(`Imagen API error (${res.status}): ${errorText}`);
309
+ }
305
310
 
306
- const response = await this.generateContent(imageModel, contents, imageConfig);
311
+ return res.json();
312
+ });
307
313
 
308
- // Extract generated image from response
309
314
  const result: GeminiImageGenerationResult = {
310
315
  text: undefined,
311
316
  imageUrl: undefined,
312
317
  imageBase64: undefined,
313
- mimeType: undefined,
318
+ mimeType: "image/png",
314
319
  };
315
320
 
316
- if (response.candidates && response.candidates.length > 0) {
317
- const candidate = response.candidates[0];
321
+ if (response.generatedImages && response.generatedImages.length > 0) {
322
+ const generatedImage = response.generatedImages[0];
323
+ const imageBytes = generatedImage.image?.imageBytes;
318
324
 
319
- for (const part of candidate.content.parts) {
320
- if ("text" in part && part.text) {
321
- result.text = part.text;
322
- }
323
- if ("inlineData" in part && part.inlineData) {
324
- result.imageBase64 = part.inlineData.data;
325
- result.mimeType = part.inlineData.mimeType;
326
- result.imageUrl = `data:${part.inlineData.mimeType};base64,${part.inlineData.data}`;
327
- }
325
+ if (imageBytes) {
326
+ result.imageBase64 = imageBytes;
327
+ result.imageUrl = `data:image/png;base64,${imageBytes}`;
328
328
  }
329
329
  }
330
330
 
331
331
  if (typeof __DEV__ !== "undefined" && __DEV__) {
332
332
  // eslint-disable-next-line no-console
333
- console.log("[GeminiClient] generateImage() completed", {
334
- hasText: !!result.text,
333
+ console.log("[GeminiClient] generateImage() completed (Imagen)", {
335
334
  hasImage: !!result.imageBase64,
336
- mimeType: result.mimeType,
337
335
  imageDataLength: result.imageBase64?.length ?? 0,
338
336
  });
339
337
  }