@umituz/react-native-ai-gemini-provider 1.14.36 → 1.14.38

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.14.36",
3
+ "version": "1.14.38",
4
4
  "description": "Google Gemini AI provider for React Native applications",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -1,17 +1,24 @@
1
1
  /**
2
2
  * Gemini Model Constants
3
3
  * Centralized model configuration for all AI operations
4
+ * Updated: 2026-01 with latest pricing and free tier info
4
5
  */
5
6
 
6
7
  /**
7
8
  * Available Gemini models
8
- * Updated: 2025-12 with latest stable and preview models
9
+ * Pricing (per 1M tokens):
10
+ * - Flash-Lite: $0.10 input / $0.40 output (FREE: 1000 req/day)
11
+ * - Flash: $0.15 input / $0.60 output (FREE: 20 req/day)
12
+ * - Pro: $1.25 input / $10.00 output (FREE: 25 req/day)
9
13
  */
10
14
  export const GEMINI_MODELS = {
11
- // Text generation models
15
+ // Text generation models (ordered by cost: cheapest first)
12
16
  TEXT: {
13
- FLASH: "gemini-2.5-flash",
17
+ /** Most cost-effective, 1000 free requests/day */
14
18
  FLASH_LITE: "gemini-2.5-flash-lite",
19
+ /** Good balance of speed and quality */
20
+ FLASH: "gemini-2.5-flash",
21
+ /** Highest quality, best for complex reasoning */
15
22
  PRO: "gemini-2.5-pro",
16
23
  },
17
24
 
@@ -45,13 +52,24 @@ export const GEMINI_MODELS = {
45
52
  /**
46
53
  * Default models for each operation type
47
54
  * Optimized for cost-effectiveness while maintaining quality
55
+ * Using Flash-Lite as default for best free tier (1000 req/day)
48
56
  */
49
57
  export const DEFAULT_MODELS = {
50
- TEXT: GEMINI_MODELS.TEXT.FLASH_LITE, // Most cost-effective for text
58
+ /** Flash-Lite: Cheapest & highest free tier (1000/day) */
59
+ TEXT: GEMINI_MODELS.TEXT.FLASH_LITE,
51
60
  TEXT_TO_IMAGE: GEMINI_MODELS.TEXT_TO_IMAGE.DEFAULT,
52
- IMAGE_EDIT: GEMINI_MODELS.IMAGE_EDIT.DEFAULT, // Uses gemini-2.5-flash-image (free tier)
61
+ IMAGE_EDIT: GEMINI_MODELS.IMAGE_EDIT.DEFAULT,
53
62
  VIDEO: GEMINI_MODELS.VIDEO.FLASH,
54
- VIDEO_GENERATION: GEMINI_MODELS.VIDEO_GENERATION.DEFAULT, // veo-3.1-generate-preview
63
+ VIDEO_GENERATION: GEMINI_MODELS.VIDEO_GENERATION.DEFAULT,
64
+ } as const;
65
+
66
+ /**
67
+ * Model pricing information (per 1M tokens)
68
+ */
69
+ export const MODEL_PRICING = {
70
+ [GEMINI_MODELS.TEXT.FLASH_LITE]: { input: 0.10, output: 0.40, freePerDay: 1000 },
71
+ [GEMINI_MODELS.TEXT.FLASH]: { input: 0.15, output: 0.60, freePerDay: 20 },
72
+ [GEMINI_MODELS.TEXT.PRO]: { input: 1.25, output: 10.00, freePerDay: 25 },
55
73
  } as const;
56
74
 
57
75
  /**
package/src/index.ts CHANGED
@@ -36,7 +36,7 @@ export type {
36
36
  ResponseModality,
37
37
  } from "./domain/entities";
38
38
 
39
- export { GeminiErrorType, GeminiError, GEMINI_MODELS, DEFAULT_MODELS, RESPONSE_MODALITIES } from "./domain/entities";
39
+ export { GeminiErrorType, GeminiError, GEMINI_MODELS, DEFAULT_MODELS, MODEL_PRICING, RESPONSE_MODALITIES } from "./domain/entities";
40
40
 
41
41
  // Feature Models
42
42
  export {
@@ -54,6 +54,7 @@ export {
54
54
  geminiClientCoreService,
55
55
  geminiRetryService,
56
56
  geminiTextGenerationService,
57
+ geminiStructuredTextService,
57
58
  geminiImageGenerationService,
58
59
  geminiImageEditService,
59
60
  geminiStreamingService,
@@ -6,6 +6,7 @@
6
6
  export { geminiClientCoreService } from "./gemini-client-core.service";
7
7
  export { geminiRetryService } from "./gemini-retry.service";
8
8
  export { geminiTextGenerationService } from "./gemini-text-generation.service";
9
+ export { geminiStructuredTextService } from "./gemini-structured-text.service";
9
10
  export { geminiImageGenerationService } from "./gemini-image-generation.service";
10
11
  export { geminiImageEditService } from "./gemini-image-edit.service";
11
12
  export { geminiStreamingService } from "./gemini-streaming.service";
@@ -1,34 +1,52 @@
1
1
  /**
2
2
  * useGemini Hook
3
3
  * React hook for Gemini AI generation
4
+ * Supports text, structured JSON, and multimodal generation
4
5
  */
5
6
 
6
7
  import { useState, useCallback, useRef } from "react";
7
8
  import type { GeminiGenerationConfig } from "../../domain/entities";
9
+ import { DEFAULT_MODELS } from "../../domain/entities";
8
10
  import { geminiTextGenerationService } from "../../infrastructure/services";
11
+ import { geminiStructuredTextService } from "../../infrastructure/services";
9
12
 
10
13
  export interface UseGeminiOptions {
14
+ /** Model to use (default: gemini-2.5-flash-lite) */
11
15
  model?: string;
16
+ /** Generation configuration */
12
17
  generationConfig?: GeminiGenerationConfig;
18
+ /** Called on successful generation */
13
19
  onSuccess?: (result: string) => void;
20
+ /** Called on error */
14
21
  onError?: (error: string) => void;
15
22
  }
16
23
 
17
24
  export interface UseGeminiReturn {
25
+ /** Generate text from prompt */
18
26
  generate: (prompt: string) => Promise<void>;
27
+ /** Generate text with image input */
19
28
  generateWithImage: (
20
29
  prompt: string,
21
30
  imageBase64: string,
22
31
  mimeType: string,
23
32
  ) => Promise<void>;
33
+ /** Generate structured JSON response */
34
+ generateJSON: <T>(prompt: string, schema?: Record<string, unknown>) => Promise<T | null>;
35
+ /** Current result */
24
36
  result: string | null;
37
+ /** JSON result (when using generateJSON) */
38
+ jsonResult: unknown | null;
39
+ /** Loading state */
25
40
  isGenerating: boolean;
41
+ /** Error message */
26
42
  error: string | null;
43
+ /** Reset state */
27
44
  reset: () => void;
28
45
  }
29
46
 
30
47
  export function useGemini(options: UseGeminiOptions = {}): UseGeminiReturn {
31
48
  const [result, setResult] = useState<string | null>(null);
49
+ const [jsonResult, setJsonResult] = useState<unknown | null>(null);
32
50
  const [isGenerating, setIsGenerating] = useState(false);
33
51
  const [error, setError] = useState<string | null>(null);
34
52
 
@@ -40,9 +58,10 @@ export function useGemini(options: UseGeminiOptions = {}): UseGeminiReturn {
40
58
  setIsGenerating(true);
41
59
  setError(null);
42
60
  setResult(null);
61
+ setJsonResult(null);
43
62
 
44
63
  try {
45
- const model = options.model ?? "gemini-1.5-flash";
64
+ const model = options.model ?? DEFAULT_MODELS.TEXT;
46
65
  const text = await geminiTextGenerationService.generateText(
47
66
  model,
48
67
  prompt,
@@ -69,15 +88,79 @@ export function useGemini(options: UseGeminiOptions = {}): UseGeminiReturn {
69
88
  [options],
70
89
  );
71
90
 
91
+ const generateJSON = useCallback(
92
+ async <T>(prompt: string, schema?: Record<string, unknown>): Promise<T | null> => {
93
+ abortRef.current = false;
94
+ setIsGenerating(true);
95
+ setError(null);
96
+ setResult(null);
97
+ setJsonResult(null);
98
+
99
+ try {
100
+ const model = options.model ?? DEFAULT_MODELS.TEXT;
101
+
102
+ let parsed: T;
103
+
104
+ if (schema) {
105
+ // Use structured text service with schema
106
+ parsed = await geminiStructuredTextService.generateStructuredText<T>(
107
+ model,
108
+ prompt,
109
+ schema,
110
+ options.generationConfig,
111
+ );
112
+ } else {
113
+ // Generate text and parse JSON manually
114
+ const text = await geminiTextGenerationService.generateText(
115
+ model,
116
+ prompt,
117
+ {
118
+ ...options.generationConfig,
119
+ responseMimeType: "application/json",
120
+ },
121
+ );
122
+
123
+ // Clean and parse JSON
124
+ const cleanedText = text
125
+ .replace(/```json\n?/g, "")
126
+ .replace(/```\n?/g, "")
127
+ .trim();
128
+ parsed = JSON.parse(cleanedText) as T;
129
+ }
130
+
131
+ if (abortRef.current) return null;
132
+
133
+ setJsonResult(parsed);
134
+ setResult(JSON.stringify(parsed, null, 2));
135
+ options.onSuccess?.(JSON.stringify(parsed));
136
+ return parsed;
137
+ } catch (err) {
138
+ if (abortRef.current) return null;
139
+
140
+ const errorMessage =
141
+ err instanceof Error ? err.message : "JSON generation failed";
142
+ setError(errorMessage);
143
+ options.onError?.(errorMessage);
144
+ return null;
145
+ } finally {
146
+ if (!abortRef.current) {
147
+ setIsGenerating(false);
148
+ }
149
+ }
150
+ },
151
+ [options],
152
+ );
153
+
72
154
  const generateWithImage = useCallback(
73
155
  async (prompt: string, imageBase64: string, mimeType: string) => {
74
156
  abortRef.current = false;
75
157
  setIsGenerating(true);
76
158
  setError(null);
77
159
  setResult(null);
160
+ setJsonResult(null);
78
161
 
79
162
  try {
80
- const model = options.model ?? "gemini-1.5-flash";
163
+ const model = options.model ?? DEFAULT_MODELS.TEXT;
81
164
  const response = await geminiTextGenerationService.generateWithImages(
82
165
  model,
83
166
  prompt,
@@ -115,6 +198,7 @@ export function useGemini(options: UseGeminiOptions = {}): UseGeminiReturn {
115
198
  const reset = useCallback(() => {
116
199
  abortRef.current = true;
117
200
  setResult(null);
201
+ setJsonResult(null);
118
202
  setIsGenerating(false);
119
203
  setError(null);
120
204
  }, []);
@@ -122,7 +206,9 @@ export function useGemini(options: UseGeminiOptions = {}): UseGeminiReturn {
122
206
  return {
123
207
  generate,
124
208
  generateWithImage,
209
+ generateJSON,
125
210
  result,
211
+ jsonResult,
126
212
  isGenerating,
127
213
  error,
128
214
  reset,