@umituz/react-native-ai-gemini-provider 3.0.18 → 3.0.19

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": "3.0.18",
3
+ "version": "3.0.19",
4
4
  "description": "Google Gemini AI text generation provider for React Native applications",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./dist/index.d.ts",
@@ -111,3 +111,48 @@ export interface GeminiUsageMetadata {
111
111
  /** Total number of tokens used */
112
112
  totalTokenCount?: number;
113
113
  }
114
+
115
+ /**
116
+ * Safety setting for a single harm category
117
+ */
118
+ export interface GeminiSafetySetting {
119
+ category: GeminiHarmCategory;
120
+ threshold: GeminiHarmBlockThreshold;
121
+ }
122
+
123
+ /**
124
+ * Inline data part for binary content (images, audio)
125
+ */
126
+ export interface GeminiInlineDataPart {
127
+ inlineData: { mimeType: string; data: string };
128
+ }
129
+
130
+ /**
131
+ * A message part that can be text or inline data
132
+ */
133
+ export type GeminiMessagePart = GeminiPart | GeminiInlineDataPart;
134
+
135
+ /**
136
+ * Options for creating a generative model instance
137
+ */
138
+ export interface GeminiModelOptions {
139
+ model?: string;
140
+ systemInstruction?: string;
141
+ safetySettings?: GeminiSafetySetting[];
142
+ }
143
+
144
+ /**
145
+ * Configuration for a chat session
146
+ */
147
+ export interface GeminiChatConfig {
148
+ /** Model name override */
149
+ model?: string;
150
+ /** System instruction for the model */
151
+ systemInstruction?: string;
152
+ /** Safety settings (defaults to BLOCK_NONE for all categories) */
153
+ safetySettings?: GeminiSafetySetting[];
154
+ /** Generation config (temperature, maxOutputTokens, etc.) */
155
+ generationConfig?: GeminiGenerationConfig;
156
+ /** Initial conversation history */
157
+ history?: GeminiContent[];
158
+ }
@@ -6,6 +6,10 @@ export const GEMINI_MODELS = {
6
6
  TEXT: {
7
7
  /** Lightweight flash model for fast text generation */
8
8
  FLASH_LITE: "gemini-2.5-flash-lite",
9
+ /** Balanced flash model for general use */
10
+ FLASH: "gemini-2.5-flash",
11
+ /** Premium model for complex tasks */
12
+ PRO: "gemini-2.5-pro",
9
13
  },
10
14
  } as const;
11
15
 
@@ -15,4 +19,6 @@ export const GEMINI_MODELS = {
15
19
  export const DEFAULT_MODELS = {
16
20
  /** Default model for text generation */
17
21
  TEXT: GEMINI_MODELS.TEXT.FLASH_LITE,
22
+ /** Default model for chat sessions */
23
+ CHAT: GEMINI_MODELS.TEXT.FLASH,
18
24
  } as const;
package/src/index.ts CHANGED
@@ -11,6 +11,11 @@ export type {
11
11
  GeminiHarmBlockThreshold,
12
12
  GeminiContent,
13
13
  GeminiPart,
14
+ GeminiInlineDataPart,
15
+ GeminiMessagePart,
16
+ GeminiSafetySetting,
17
+ GeminiModelOptions,
18
+ GeminiChatConfig,
14
19
  GeminiResponse,
15
20
  GeminiCandidate,
16
21
  GeminiFinishReason,
@@ -29,6 +34,7 @@ export {
29
34
 
30
35
  // Services
31
36
  export { geminiClient } from "./infrastructure/services/GeminiClient";
37
+ export { createChatSession } from "./infrastructure/services/ChatSession";
32
38
  export { textGeneration } from "./infrastructure/services/TextGeneration";
33
39
  export { structuredText } from "./infrastructure/services/StructuredText";
34
40
  export { streaming } from "./infrastructure/services/Streaming";
@@ -0,0 +1,54 @@
1
+ import type { ChatSession as SdkChatSession, Part } from "@google/generative-ai";
2
+ import { geminiClient } from "./GeminiClient";
3
+ import { DEFAULT_MODELS } from "../../domain/entities";
4
+ import type {
5
+ GeminiChatConfig,
6
+ GeminiContent,
7
+ GeminiMessagePart,
8
+ } from "../../domain/entities";
9
+
10
+ /**
11
+ * Creates a Gemini chat session with full support for system instructions,
12
+ * safety settings, generation config, and multi-turn conversation history.
13
+ *
14
+ * Usage:
15
+ * ```ts
16
+ * const session = createChatSession({
17
+ * model: "gemini-2.5-flash",
18
+ * systemInstruction: "You are a helpful assistant.",
19
+ * generationConfig: { temperature: 0.7, maxOutputTokens: 512 },
20
+ * history: geminiHistory,
21
+ * });
22
+ *
23
+ * const text = await session.send([{ text: "Hello" }]);
24
+ * ```
25
+ */
26
+ export function createChatSession(config: GeminiChatConfig = {}) {
27
+ const model = geminiClient.getModel({
28
+ model: config.model ?? DEFAULT_MODELS.CHAT,
29
+ systemInstruction: config.systemInstruction,
30
+ safetySettings: config.safetySettings,
31
+ });
32
+
33
+ const historyForChat = (config.history ?? []).map((turn) => ({
34
+ role: turn.role === "model" ? ("model" as const) : ("user" as const),
35
+ parts: turn.parts as Part[],
36
+ }));
37
+
38
+ const chat: SdkChatSession = model.startChat({
39
+ history: historyForChat,
40
+ ...(config.generationConfig && { generationConfig: config.generationConfig }),
41
+ });
42
+
43
+ return {
44
+ /**
45
+ * Send a message and return the full response text.
46
+ * Accepts text parts and/or inline data parts (images, audio).
47
+ */
48
+ async send(parts: GeminiMessagePart[]): Promise<string> {
49
+ const result = await chat.sendMessage(parts as Part[]);
50
+ if (!result.response) throw new Error("No response from Gemini SDK");
51
+ return result.response.text();
52
+ },
53
+ };
54
+ }
@@ -1,11 +1,25 @@
1
- import { GoogleGenerativeAI, type GenerativeModel } from "@google/generative-ai";
1
+ import {
2
+ GoogleGenerativeAI,
3
+ HarmCategory,
4
+ HarmBlockThreshold,
5
+ type GenerativeModel,
6
+ type SafetySetting,
7
+ } from "@google/generative-ai";
2
8
  import { DEFAULT_MODELS } from "../../domain/entities";
3
- import type { GeminiConfig } from "../../domain/entities";
9
+ import type { GeminiConfig, GeminiModelOptions } from "../../domain/entities";
4
10
 
5
11
  const DEFAULT_CONFIG: Partial<GeminiConfig> = {
6
12
  textModel: DEFAULT_MODELS.TEXT,
7
13
  };
8
14
 
15
+ /** All categories set to BLOCK_NONE */
16
+ const PERMISSIVE_SAFETY: SafetySetting[] = [
17
+ { category: HarmCategory.HARM_CATEGORY_HARASSMENT, threshold: HarmBlockThreshold.BLOCK_NONE },
18
+ { category: HarmCategory.HARM_CATEGORY_HATE_SPEECH, threshold: HarmBlockThreshold.BLOCK_NONE },
19
+ { category: HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT, threshold: HarmBlockThreshold.BLOCK_NONE },
20
+ { category: HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, threshold: HarmBlockThreshold.BLOCK_NONE },
21
+ ];
22
+
9
23
  class GeminiClient {
10
24
  private client: GoogleGenerativeAI | null = null;
11
25
  private config: GeminiConfig | null = null;
@@ -35,18 +49,40 @@ class GeminiClient {
35
49
  return this.client;
36
50
  }
37
51
 
38
- getModel(modelName?: string): GenerativeModel {
52
+ /**
53
+ * Returns a GenerativeModel configured with optional safety settings and system instruction.
54
+ * When no safety settings are provided, defaults to BLOCK_NONE for all categories.
55
+ */
56
+ getModel(modelNameOrOptions?: string | GeminiModelOptions): GenerativeModel {
39
57
  if (!this.client || !this.initialized) {
40
58
  throw new Error("Gemini client not initialized. Call initialize() first.");
41
59
  }
42
60
 
43
- const effectiveModel = modelName || this.config?.textModel || DEFAULT_MODELS.TEXT;
61
+ // Normalize args
62
+ const opts: GeminiModelOptions =
63
+ typeof modelNameOrOptions === "string"
64
+ ? { model: modelNameOrOptions }
65
+ : modelNameOrOptions ?? {};
66
+
67
+ const effectiveModel = opts.model || this.config?.textModel || DEFAULT_MODELS.TEXT;
44
68
 
45
69
  if (!effectiveModel.startsWith("gemini-")) {
46
70
  throw new Error('Model name must start with "gemini-"');
47
71
  }
48
72
 
49
- return this.client.getGenerativeModel({ model: effectiveModel });
73
+ // Map package safety settings to SDK format
74
+ const sdkSafety: SafetySetting[] = opts.safetySettings
75
+ ? opts.safetySettings.map((s) => ({
76
+ category: s.category as unknown as HarmCategory,
77
+ threshold: s.threshold as unknown as HarmBlockThreshold,
78
+ }))
79
+ : PERMISSIVE_SAFETY;
80
+
81
+ return this.client.getGenerativeModel({
82
+ model: effectiveModel,
83
+ ...(opts.systemInstruction && { systemInstruction: opts.systemInstruction }),
84
+ safetySettings: sdkSafety,
85
+ });
50
86
  }
51
87
 
52
88
  reset(): void {
@@ -3,3 +3,4 @@ export { textGeneration } from "./TextGeneration";
3
3
  export { structuredText } from "./StructuredText";
4
4
  export { streaming } from "./Streaming";
5
5
  export { geminiProvider, GeminiProvider } from "./GeminiProvider";
6
+ export { createChatSession } from "./ChatSession";