@umituz/react-native-ai-gemini-provider 3.0.22 → 3.0.24
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/dist/index.d.ts +1 -1
- package/dist/infrastructure/services/ChatSession.d.ts +56 -4
- package/dist/infrastructure/services/index.d.ts +1 -1
- package/package.json +1 -1
- package/src/global.d.ts +1 -0
- package/src/index.ts +11 -1
- package/src/infrastructure/services/ChatSession.ts +222 -4
- package/src/infrastructure/services/GeminiClient.ts +6 -0
- package/src/infrastructure/services/index.ts +11 -1
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
export type { GeminiConfig, GeminiGenerationConfig, GeminiHarmCategory, GeminiHarmBlockThreshold, GeminiContent, GeminiPart, GeminiInlineDataPart, GeminiMessagePart, GeminiSafetySetting, GeminiModelOptions, GeminiChatConfig, GeminiResponse, GeminiCandidate, GeminiFinishReason, GeminiSafetyRating, GeminiUsageMetadata, GeminiErrorInfo, GeminiApiError, } from "./domain/entities";
|
|
6
6
|
export { GeminiErrorType, GeminiError, GEMINI_MODELS, DEFAULT_MODELS } from "./domain/entities";
|
|
7
7
|
export { geminiClient } from "./infrastructure/services/GeminiClient";
|
|
8
|
-
export { createChatSession, type ChatSendResult } from "./infrastructure/services/ChatSession";
|
|
8
|
+
export { createChatSession, sendChatMessage, buildChatHistory, trimChatHistory, resolveAudioMimeType, resolveImageMimeType, type ChatSendResult, type ChatHistoryMessage, type SendChatMessageOptions, } from "./infrastructure/services/ChatSession";
|
|
9
9
|
export { textGeneration } from "./infrastructure/services/TextGeneration";
|
|
10
10
|
export { structuredText } from "./infrastructure/services/StructuredText";
|
|
11
11
|
export { streaming } from "./infrastructure/services/Streaming";
|
|
@@ -1,15 +1,67 @@
|
|
|
1
|
-
import type { GeminiChatConfig, GeminiMessagePart } from "../../domain/entities";
|
|
1
|
+
import type { GeminiChatConfig, GeminiGenerationConfig, GeminiContent, GeminiInlineDataPart, GeminiMessagePart, GeminiSafetySetting } from "../../domain/entities";
|
|
2
2
|
export interface ChatSendResult {
|
|
3
3
|
text: string;
|
|
4
4
|
finishReason?: string;
|
|
5
5
|
}
|
|
6
|
+
/** A simple chat message (user/assistant/system) */
|
|
7
|
+
export interface ChatHistoryMessage {
|
|
8
|
+
readonly role: "user" | "assistant" | "system";
|
|
9
|
+
readonly content: string;
|
|
10
|
+
}
|
|
11
|
+
/** Options for the high-level sendChatMessage() */
|
|
12
|
+
export interface SendChatMessageOptions {
|
|
13
|
+
/** Conversation history */
|
|
14
|
+
history: ChatHistoryMessage[];
|
|
15
|
+
/** Current user message text */
|
|
16
|
+
message: string;
|
|
17
|
+
/** System instruction for the model */
|
|
18
|
+
systemPrompt?: string;
|
|
19
|
+
/** Model name (defaults to gemini-2.5-flash) */
|
|
20
|
+
model?: string;
|
|
21
|
+
/** Generation config (temperature, maxOutputTokens, etc.) */
|
|
22
|
+
generationConfig?: GeminiGenerationConfig;
|
|
23
|
+
/** Safety settings (defaults to BLOCK_NONE for all) */
|
|
24
|
+
safetySettings?: GeminiSafetySetting[];
|
|
25
|
+
/** Pre-built attachments (base64 inline data parts for images/audio) */
|
|
26
|
+
attachments?: GeminiInlineDataPart[];
|
|
27
|
+
/** Max character budget for history trimming (default 12000) */
|
|
28
|
+
historyMaxChars?: number;
|
|
29
|
+
/** Min messages to always keep regardless of budget (default 4) */
|
|
30
|
+
historyMinMessages?: number;
|
|
31
|
+
}
|
|
32
|
+
/** Resolve MIME type for an audio file extension */
|
|
33
|
+
export declare function resolveAudioMimeType(extension: string): string;
|
|
34
|
+
/** Resolve MIME type for an image file extension */
|
|
35
|
+
export declare function resolveImageMimeType(extension: string): string;
|
|
36
|
+
/**
|
|
37
|
+
* Converts chat messages (user/assistant/system) to Gemini SDK content format.
|
|
38
|
+
* Skips system messages, merges consecutive same-role messages.
|
|
39
|
+
*/
|
|
40
|
+
export declare function buildChatHistory(history: readonly ChatHistoryMessage[]): GeminiContent[];
|
|
41
|
+
/**
|
|
42
|
+
* Trims conversation history to fit within a character budget.
|
|
43
|
+
* Keeps at least `minMessages` entries regardless of budget.
|
|
44
|
+
*/
|
|
45
|
+
export declare function trimChatHistory(history: ChatHistoryMessage[], maxChars?: number, minMessages?: number): ChatHistoryMessage[];
|
|
6
46
|
/**
|
|
7
47
|
* Creates a Gemini chat session with full support for system instructions,
|
|
8
48
|
* safety settings, generation config, and multi-turn conversation history.
|
|
9
49
|
*/
|
|
10
50
|
export declare function createChatSession(config?: GeminiChatConfig): {
|
|
11
|
-
/**
|
|
12
|
-
* Send a message and return the response text + finish reason.
|
|
13
|
-
*/
|
|
14
51
|
send(parts: GeminiMessagePart[]): Promise<ChatSendResult>;
|
|
15
52
|
};
|
|
53
|
+
/**
|
|
54
|
+
* All-in-one: trims history, builds session, sends message, handles safety.
|
|
55
|
+
* Returns the AI response text.
|
|
56
|
+
*
|
|
57
|
+
* ```ts
|
|
58
|
+
* const text = await sendChatMessage({
|
|
59
|
+
* history: messages,
|
|
60
|
+
* message: "hello",
|
|
61
|
+
* systemPrompt: "You are Aria...",
|
|
62
|
+
* model: GEMINI_MODELS.TEXT.FLASH,
|
|
63
|
+
* generationConfig: { temperature: 0.7, maxOutputTokens: 512 },
|
|
64
|
+
* });
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export declare function sendChatMessage(opts: SendChatMessageOptions): Promise<string>;
|
|
@@ -3,4 +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, type ChatSendResult } from "./ChatSession";
|
|
6
|
+
export { createChatSession, sendChatMessage, buildChatHistory, trimChatHistory, resolveAudioMimeType, resolveImageMimeType, type ChatSendResult, type ChatHistoryMessage, type SendChatMessageOptions, } from "./ChatSession";
|
package/package.json
CHANGED
package/src/global.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare const __DEV__: boolean;
|
package/src/index.ts
CHANGED
|
@@ -34,7 +34,17 @@ export {
|
|
|
34
34
|
|
|
35
35
|
// Services
|
|
36
36
|
export { geminiClient } from "./infrastructure/services/GeminiClient";
|
|
37
|
-
export {
|
|
37
|
+
export {
|
|
38
|
+
createChatSession,
|
|
39
|
+
sendChatMessage,
|
|
40
|
+
buildChatHistory,
|
|
41
|
+
trimChatHistory,
|
|
42
|
+
resolveAudioMimeType,
|
|
43
|
+
resolveImageMimeType,
|
|
44
|
+
type ChatSendResult,
|
|
45
|
+
type ChatHistoryMessage,
|
|
46
|
+
type SendChatMessageOptions,
|
|
47
|
+
} from "./infrastructure/services/ChatSession";
|
|
38
48
|
export { textGeneration } from "./infrastructure/services/TextGeneration";
|
|
39
49
|
export { structuredText } from "./infrastructure/services/StructuredText";
|
|
40
50
|
export { streaming } from "./infrastructure/services/Streaming";
|
|
@@ -3,14 +3,130 @@ import { geminiClient } from "./GeminiClient";
|
|
|
3
3
|
import { DEFAULT_MODELS } from "../../domain/entities";
|
|
4
4
|
import type {
|
|
5
5
|
GeminiChatConfig,
|
|
6
|
+
GeminiGenerationConfig,
|
|
7
|
+
GeminiContent,
|
|
8
|
+
GeminiInlineDataPart,
|
|
6
9
|
GeminiMessagePart,
|
|
10
|
+
GeminiSafetySetting,
|
|
7
11
|
} from "../../domain/entities";
|
|
8
12
|
|
|
13
|
+
// ─── Types ───────────────────────────────────────────────────────────────────
|
|
14
|
+
|
|
9
15
|
export interface ChatSendResult {
|
|
10
16
|
text: string;
|
|
11
17
|
finishReason?: string;
|
|
12
18
|
}
|
|
13
19
|
|
|
20
|
+
/** A simple chat message (user/assistant/system) */
|
|
21
|
+
export interface ChatHistoryMessage {
|
|
22
|
+
readonly role: "user" | "assistant" | "system";
|
|
23
|
+
readonly content: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Options for the high-level sendChatMessage() */
|
|
27
|
+
export interface SendChatMessageOptions {
|
|
28
|
+
/** Conversation history */
|
|
29
|
+
history: ChatHistoryMessage[];
|
|
30
|
+
/** Current user message text */
|
|
31
|
+
message: string;
|
|
32
|
+
/** System instruction for the model */
|
|
33
|
+
systemPrompt?: string;
|
|
34
|
+
/** Model name (defaults to gemini-2.5-flash) */
|
|
35
|
+
model?: string;
|
|
36
|
+
/** Generation config (temperature, maxOutputTokens, etc.) */
|
|
37
|
+
generationConfig?: GeminiGenerationConfig;
|
|
38
|
+
/** Safety settings (defaults to BLOCK_NONE for all) */
|
|
39
|
+
safetySettings?: GeminiSafetySetting[];
|
|
40
|
+
/** Pre-built attachments (base64 inline data parts for images/audio) */
|
|
41
|
+
attachments?: GeminiInlineDataPart[];
|
|
42
|
+
/** Max character budget for history trimming (default 12000) */
|
|
43
|
+
historyMaxChars?: number;
|
|
44
|
+
/** Min messages to always keep regardless of budget (default 4) */
|
|
45
|
+
historyMinMessages?: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// ─── MIME Utilities ──────────────────────────────────────────────────────────
|
|
49
|
+
|
|
50
|
+
const AUDIO_MIME: Record<string, string> = {
|
|
51
|
+
mp3: "audio/mpeg",
|
|
52
|
+
wav: "audio/wav",
|
|
53
|
+
ogg: "audio/ogg",
|
|
54
|
+
flac: "audio/flac",
|
|
55
|
+
aac: "audio/aac",
|
|
56
|
+
mp4: "audio/mp4",
|
|
57
|
+
m4a: "audio/mp4",
|
|
58
|
+
caf: "audio/mp4",
|
|
59
|
+
"3gp": "audio/3gpp",
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/** Resolve MIME type for an audio file extension */
|
|
63
|
+
export function resolveAudioMimeType(extension: string): string {
|
|
64
|
+
return AUDIO_MIME[extension.toLowerCase()] ?? "audio/mp4";
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Resolve MIME type for an image file extension */
|
|
68
|
+
export function resolveImageMimeType(extension: string): string {
|
|
69
|
+
return extension.toLowerCase() === "png" ? "image/png" : "image/jpeg";
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// ─── History Utilities ───────────────────────────────────────────────────────
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Converts chat messages (user/assistant/system) to Gemini SDK content format.
|
|
76
|
+
* Skips system messages, merges consecutive same-role messages.
|
|
77
|
+
*/
|
|
78
|
+
export function buildChatHistory(
|
|
79
|
+
history: readonly ChatHistoryMessage[],
|
|
80
|
+
): GeminiContent[] {
|
|
81
|
+
const result: GeminiContent[] = [];
|
|
82
|
+
let seenUser = false;
|
|
83
|
+
|
|
84
|
+
for (const m of history) {
|
|
85
|
+
if (m.role === "system") continue;
|
|
86
|
+
if (!seenUser && m.role !== "user") continue;
|
|
87
|
+
seenUser = true;
|
|
88
|
+
|
|
89
|
+
const role = m.role === "assistant" ? "model" : "user";
|
|
90
|
+
const last = result[result.length - 1];
|
|
91
|
+
|
|
92
|
+
if (last && last.role === role) {
|
|
93
|
+
const existingText =
|
|
94
|
+
"text" in last.parts[0] ? (last.parts[0].text ?? "") : "";
|
|
95
|
+
last.parts[0] = { text: existingText + "\n" + m.content };
|
|
96
|
+
} else {
|
|
97
|
+
result.push({ role, parts: [{ text: m.content }] });
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Trims conversation history to fit within a character budget.
|
|
106
|
+
* Keeps at least `minMessages` entries regardless of budget.
|
|
107
|
+
*/
|
|
108
|
+
export function trimChatHistory(
|
|
109
|
+
history: ChatHistoryMessage[],
|
|
110
|
+
maxChars = 12000,
|
|
111
|
+
minMessages = 4,
|
|
112
|
+
): ChatHistoryMessage[] {
|
|
113
|
+
if (history.length <= minMessages) return history;
|
|
114
|
+
|
|
115
|
+
let totalChars = 0;
|
|
116
|
+
const trimmed: ChatHistoryMessage[] = [];
|
|
117
|
+
|
|
118
|
+
for (let i = history.length - 1; i >= 0; i--) {
|
|
119
|
+
const chars = history[i].content.length;
|
|
120
|
+
if (trimmed.length >= minMessages && totalChars + chars > maxChars) break;
|
|
121
|
+
trimmed.unshift(history[i]);
|
|
122
|
+
totalChars += chars;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return trimmed;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// ─── Low-level: createChatSession ────────────────────────────────────────────
|
|
129
|
+
|
|
14
130
|
/**
|
|
15
131
|
* Creates a Gemini chat session with full support for system instructions,
|
|
16
132
|
* safety settings, generation config, and multi-turn conversation history.
|
|
@@ -33,17 +149,119 @@ export function createChatSession(config: GeminiChatConfig = {}) {
|
|
|
33
149
|
});
|
|
34
150
|
|
|
35
151
|
return {
|
|
36
|
-
/**
|
|
37
|
-
* Send a message and return the response text + finish reason.
|
|
38
|
-
*/
|
|
39
152
|
async send(parts: GeminiMessagePart[]): Promise<ChatSendResult> {
|
|
153
|
+
if (__DEV__) {
|
|
154
|
+
console.log("[ChatSession.send] >>> SENDING TO GEMINI SDK");
|
|
155
|
+
console.log("[ChatSession.send] parts count:", parts.length);
|
|
156
|
+
parts.forEach((p, i) => {
|
|
157
|
+
if ("text" in p) console.log(`[ChatSession.send] part[${i}] text:`, (p.text ?? "").substring(0, 200));
|
|
158
|
+
if ("inlineData" in p) console.log(`[ChatSession.send] part[${i}] inlineData: mime=${(p as GeminiInlineDataPart).inlineData.mimeType}, size=${(p as GeminiInlineDataPart).inlineData.data.length}`);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
40
162
|
const result = await chat.sendMessage(parts as Part[]);
|
|
41
163
|
if (!result.response) throw new Error("No response from Gemini SDK");
|
|
42
164
|
const candidate = result.response.candidates?.[0];
|
|
165
|
+
const text = result.response.text();
|
|
166
|
+
|
|
167
|
+
if (__DEV__) {
|
|
168
|
+
console.log("[ChatSession.send] <<< GEMINI SDK RESPONSE");
|
|
169
|
+
console.log("[ChatSession.send] finishReason:", candidate?.finishReason ?? "N/A");
|
|
170
|
+
console.log("[ChatSession.send] safetyRatings:", JSON.stringify(candidate?.safetyRatings ?? []));
|
|
171
|
+
console.log("[ChatSession.send] response text length:", text.length);
|
|
172
|
+
console.log("[ChatSession.send] response text:", text.substring(0, 500));
|
|
173
|
+
console.log("[ChatSession.send] response FULL text:", text);
|
|
174
|
+
}
|
|
175
|
+
|
|
43
176
|
return {
|
|
44
|
-
text
|
|
177
|
+
text,
|
|
45
178
|
finishReason: candidate?.finishReason ?? undefined,
|
|
46
179
|
};
|
|
47
180
|
},
|
|
48
181
|
};
|
|
49
182
|
}
|
|
183
|
+
|
|
184
|
+
// ─── High-level: sendChatMessage ─────────────────────────────────────────────
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* All-in-one: trims history, builds session, sends message, handles safety.
|
|
188
|
+
* Returns the AI response text.
|
|
189
|
+
*
|
|
190
|
+
* ```ts
|
|
191
|
+
* const text = await sendChatMessage({
|
|
192
|
+
* history: messages,
|
|
193
|
+
* message: "hello",
|
|
194
|
+
* systemPrompt: "You are Aria...",
|
|
195
|
+
* model: GEMINI_MODELS.TEXT.FLASH,
|
|
196
|
+
* generationConfig: { temperature: 0.7, maxOutputTokens: 512 },
|
|
197
|
+
* });
|
|
198
|
+
* ```
|
|
199
|
+
*/
|
|
200
|
+
export async function sendChatMessage(
|
|
201
|
+
opts: SendChatMessageOptions,
|
|
202
|
+
): Promise<string> {
|
|
203
|
+
if (__DEV__) {
|
|
204
|
+
console.log("═══════════════════════════════════════════════════");
|
|
205
|
+
console.log("[sendChatMessage] >>> START");
|
|
206
|
+
console.log("[sendChatMessage] model:", opts.model ?? DEFAULT_MODELS.CHAT);
|
|
207
|
+
console.log("[sendChatMessage] message:", opts.message.substring(0, 200));
|
|
208
|
+
console.log("[sendChatMessage] history count:", opts.history.length);
|
|
209
|
+
console.log("[sendChatMessage] systemPrompt length:", opts.systemPrompt?.length ?? 0);
|
|
210
|
+
console.log("[sendChatMessage] systemPrompt (first 500):", opts.systemPrompt?.substring(0, 500));
|
|
211
|
+
console.log("[sendChatMessage] generationConfig:", JSON.stringify(opts.generationConfig));
|
|
212
|
+
console.log("[sendChatMessage] safetySettings:", opts.safetySettings ? JSON.stringify(opts.safetySettings) : "USING DEFAULT (BLOCK_NONE)");
|
|
213
|
+
console.log("[sendChatMessage] attachments:", opts.attachments?.length ?? 0);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const trimmed = trimChatHistory(
|
|
217
|
+
opts.history,
|
|
218
|
+
opts.historyMaxChars,
|
|
219
|
+
opts.historyMinMessages,
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
if (__DEV__) {
|
|
223
|
+
console.log("[sendChatMessage] history after trim:", trimmed.length, "messages");
|
|
224
|
+
trimmed.forEach((m, i) => console.log(`[sendChatMessage] history[${i}]: role=${m.role}, content=${m.content.substring(0, 100)}`));
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const geminiHistory = buildChatHistory(trimmed);
|
|
228
|
+
|
|
229
|
+
if (__DEV__) {
|
|
230
|
+
console.log("[sendChatMessage] geminiHistory (SDK format):", geminiHistory.length, "turns");
|
|
231
|
+
geminiHistory.forEach((h, i) => {
|
|
232
|
+
const text = "text" in h.parts[0] ? (h.parts[0] as { text: string }).text : "[non-text]";
|
|
233
|
+
console.log(`[sendChatMessage] geminiHistory[${i}]: role=${h.role}, text=${text.substring(0, 100)}`);
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const session = createChatSession({
|
|
238
|
+
model: opts.model ?? DEFAULT_MODELS.CHAT,
|
|
239
|
+
systemInstruction: opts.systemPrompt,
|
|
240
|
+
safetySettings: opts.safetySettings,
|
|
241
|
+
generationConfig: opts.generationConfig,
|
|
242
|
+
history: geminiHistory,
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
const parts: GeminiMessagePart[] = [{ text: opts.message }];
|
|
246
|
+
if (opts.attachments) {
|
|
247
|
+
parts.push(...opts.attachments);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const result = await session.send(parts);
|
|
251
|
+
|
|
252
|
+
if (__DEV__) {
|
|
253
|
+
console.log("[sendChatMessage] finishReason:", result.finishReason);
|
|
254
|
+
console.log("[sendChatMessage] response text length:", result.text.length);
|
|
255
|
+
console.log("[sendChatMessage] response FULL:", result.text);
|
|
256
|
+
console.log("[sendChatMessage] <<< END");
|
|
257
|
+
console.log("═══════════════════════════════════════════════════");
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (result.finishReason === "SAFETY") {
|
|
261
|
+
if (__DEV__) console.warn("[sendChatMessage] ⚠️ SAFETY FILTER TRIGGERED but has text, returning partial");
|
|
262
|
+
if (result.text.trim()) return result.text;
|
|
263
|
+
throw new Error("Response blocked by safety filter.");
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
return result.text;
|
|
267
|
+
}
|
|
@@ -78,6 +78,12 @@ class GeminiClient {
|
|
|
78
78
|
}))
|
|
79
79
|
: PERMISSIVE_SAFETY;
|
|
80
80
|
|
|
81
|
+
if (__DEV__) {
|
|
82
|
+
console.log("[GeminiClient.getModel] model:", effectiveModel);
|
|
83
|
+
console.log("[GeminiClient.getModel] systemInstruction length:", opts.systemInstruction?.length ?? 0);
|
|
84
|
+
console.log("[GeminiClient.getModel] safetySettings:", JSON.stringify(sdkSafety.map(s => ({ category: s.category, threshold: s.threshold }))));
|
|
85
|
+
}
|
|
86
|
+
|
|
81
87
|
return this.client.getGenerativeModel({
|
|
82
88
|
model: effectiveModel,
|
|
83
89
|
...(opts.systemInstruction && { systemInstruction: opts.systemInstruction }),
|
|
@@ -3,4 +3,14 @@ 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 {
|
|
6
|
+
export {
|
|
7
|
+
createChatSession,
|
|
8
|
+
sendChatMessage,
|
|
9
|
+
buildChatHistory,
|
|
10
|
+
trimChatHistory,
|
|
11
|
+
resolveAudioMimeType,
|
|
12
|
+
resolveImageMimeType,
|
|
13
|
+
type ChatSendResult,
|
|
14
|
+
type ChatHistoryMessage,
|
|
15
|
+
type SendChatMessageOptions,
|
|
16
|
+
} from "./ChatSession";
|