@umituz/react-native-ai-gemini-provider 3.0.41 → 3.0.43

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.
Files changed (89) hide show
  1. package/package.json +1 -1
  2. package/src/application/builders/config-builder.ts +102 -0
  3. package/src/application/builders/index.ts +8 -0
  4. package/src/application/dtos/generation-request.dto.ts +89 -0
  5. package/src/application/dtos/index.ts +8 -0
  6. package/src/application/index.ts +16 -0
  7. package/src/application/providers/gemini-provider.ts +135 -0
  8. package/src/application/providers/index.ts +6 -0
  9. package/src/application/use-cases/generate-json.use-case.ts +73 -0
  10. package/src/application/use-cases/generate-text.use-case.ts +81 -0
  11. package/src/application/use-cases/index.ts +20 -0
  12. package/src/application/use-cases/stream-content.use-case.ts +46 -0
  13. package/src/domain/entities/error.types.ts +0 -5
  14. package/src/domain/entities/gemini.types.ts +3 -1
  15. package/src/domain/index.ts +16 -0
  16. package/src/domain/repositories/index.ts +19 -0
  17. package/src/domain/repositories/streaming.repository.ts +41 -0
  18. package/src/domain/repositories/structured-text.repository.ts +41 -0
  19. package/src/domain/repositories/text-generation.repository.ts +38 -0
  20. package/src/domain/services/validation.service.ts +157 -0
  21. package/src/domain/value-objects/api-key.vo.ts +55 -0
  22. package/src/domain/value-objects/index.ts +8 -0
  23. package/src/domain/value-objects/model-name.vo.ts +66 -0
  24. package/src/domain/value-objects/timeout.vo.ts +69 -0
  25. package/src/index.ts +110 -25
  26. package/src/infrastructure/external/gemini-client.singleton.ts +49 -0
  27. package/src/infrastructure/external/gemini-sdk.adapter.ts +143 -0
  28. package/src/infrastructure/external/index.ts +7 -0
  29. package/src/infrastructure/index.ts +16 -0
  30. package/src/infrastructure/mappers/content.mapper.ts +80 -0
  31. package/src/infrastructure/mappers/error.mapper.ts +152 -0
  32. package/src/infrastructure/mappers/index.ts +7 -0
  33. package/src/infrastructure/mappers/response.mapper.ts +165 -0
  34. package/src/infrastructure/repositories/base-gemini.repository.ts +94 -0
  35. package/src/infrastructure/repositories/gemini-streaming.repository.impl.ts +119 -0
  36. package/src/infrastructure/repositories/gemini-structured-text.repository.impl.ts +108 -0
  37. package/src/infrastructure/repositories/gemini-text.repository.impl.ts +76 -0
  38. package/src/infrastructure/repositories/index.ts +10 -0
  39. package/src/infrastructure/utils/index.ts +6 -0
  40. package/src/presentation/hooks/index.ts +8 -0
  41. package/src/presentation/hooks/use-gemini.hook.ts +181 -0
  42. package/src/presentation/hooks/use-operation-manager.hook.ts +67 -0
  43. package/src/presentation/index.ts +10 -0
  44. package/src/presentation/providers/gemini-provider.tsx +93 -0
  45. package/src/presentation/providers/index.ts +10 -0
  46. package/dist/domain/entities/error.types.d.ts +0 -96
  47. package/dist/domain/entities/gemini.types.d.ts +0 -128
  48. package/dist/domain/entities/index.d.ts +0 -6
  49. package/dist/domain/entities/models.d.ts +0 -23
  50. package/dist/index.d.ts +0 -15
  51. package/dist/infrastructure/services/BaseService.d.ts +0 -29
  52. package/dist/infrastructure/services/ChatSession.d.ts +0 -63
  53. package/dist/infrastructure/services/GeminiClient.d.ts +0 -16
  54. package/dist/infrastructure/services/GeminiProvider.d.ts +0 -10
  55. package/dist/infrastructure/services/Streaming.d.ts +0 -7
  56. package/dist/infrastructure/services/StructuredText.d.ts +0 -6
  57. package/dist/infrastructure/services/TextGeneration.d.ts +0 -8
  58. package/dist/infrastructure/services/index.d.ts +0 -6
  59. package/dist/infrastructure/telemetry/TelemetryHooks.d.ts +0 -41
  60. package/dist/infrastructure/telemetry/index.d.ts +0 -4
  61. package/dist/infrastructure/utils/async/execute-state.util.d.ts +0 -49
  62. package/dist/infrastructure/utils/async/index.d.ts +0 -4
  63. package/dist/infrastructure/utils/content-mapper.util.d.ts +0 -45
  64. package/dist/infrastructure/utils/error-mapper.util.d.ts +0 -2
  65. package/dist/infrastructure/utils/gemini-data-transformer.util.d.ts +0 -2
  66. package/dist/infrastructure/utils/json-parser.util.d.ts +0 -9
  67. package/dist/infrastructure/utils/stream-processor.util.d.ts +0 -14
  68. package/dist/presentation/hooks/index.d.ts +0 -1
  69. package/dist/presentation/hooks/useGemini.d.ts +0 -17
  70. package/dist/presentation/hooks/useOperationManager.d.ts +0 -23
  71. package/dist/providers/ConfigBuilder.d.ts +0 -46
  72. package/dist/providers/ProviderFactory.d.ts +0 -25
  73. package/dist/providers/index.d.ts +0 -7
  74. package/src/infrastructure/services/BaseService.ts +0 -53
  75. package/src/infrastructure/services/ChatSession.ts +0 -199
  76. package/src/infrastructure/services/GeminiClient.ts +0 -112
  77. package/src/infrastructure/services/Streaming.ts +0 -56
  78. package/src/infrastructure/services/StructuredText.ts +0 -57
  79. package/src/infrastructure/services/TextGeneration.ts +0 -57
  80. package/src/infrastructure/telemetry/TelemetryHooks.ts +0 -110
  81. package/src/infrastructure/utils/async/execute-state.util.ts +0 -93
  82. package/src/infrastructure/utils/content-mapper.util.ts +0 -175
  83. package/src/infrastructure/utils/error-mapper.util.ts +0 -145
  84. package/src/infrastructure/utils/gemini-data-transformer.util.ts +0 -40
  85. package/src/infrastructure/utils/text-calculations.util.ts +0 -51
  86. package/src/presentation/hooks/useGemini.ts +0 -125
  87. package/src/presentation/hooks/useOperationManager.ts +0 -88
  88. package/src/providers/ConfigBuilder.ts +0 -112
  89. package/src/providers/ProviderFactory.ts +0 -65
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-ai-gemini-provider",
3
- "version": "3.0.41",
3
+ "version": "3.0.43",
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",
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Configuration Builder
3
+ * Fluent API for building Gemini configuration
4
+ */
5
+
6
+ import { DEFAULT_MODELS } from "../../domain/entities";
7
+ import type { GeminiConfig } from "../../domain/entities";
8
+
9
+ export interface GeminiConfigOptions {
10
+ apiKey: string;
11
+ model?: string;
12
+ timeout?: number;
13
+ strategy?: "cost" | "quality";
14
+ }
15
+
16
+ export class GeminiConfigBuilder {
17
+ private apiKey?: string;
18
+ private model: string = DEFAULT_MODELS.TEXT;
19
+ private timeout = 30000;
20
+ private strategy?: "cost" | "quality";
21
+
22
+ /**
23
+ * Set API key (required)
24
+ */
25
+ withApiKey(apiKey: string): this {
26
+ if (!apiKey || typeof apiKey !== "string" || apiKey.trim().length === 0) {
27
+ throw new Error("API key must be a non-empty string");
28
+ }
29
+ this.apiKey = apiKey.trim();
30
+ return this;
31
+ }
32
+
33
+ /**
34
+ * Set model name
35
+ */
36
+ withModel(model: string): this {
37
+ if (!model || !model.startsWith("gemini-")) {
38
+ throw new Error("Invalid model name. Must start with 'gemini-'");
39
+ }
40
+ this.model = model;
41
+ return this;
42
+ }
43
+
44
+ /**
45
+ * Set request timeout (ms)
46
+ */
47
+ withTimeout(timeout: number): this {
48
+ if (timeout <= 0 || timeout > 300000) {
49
+ throw new Error("Timeout must be between 1ms and 300000ms (5 minutes)");
50
+ }
51
+ this.timeout = timeout;
52
+ return this;
53
+ }
54
+
55
+ /**
56
+ * Set strategy and apply preset timeout
57
+ */
58
+ withStrategy(strategy: "cost" | "quality"): this {
59
+ this.strategy = strategy;
60
+
61
+ // Apply strategy-based defaults
62
+ if (strategy === "quality") {
63
+ this.timeout = 60000; // 1 minute for quality
64
+ } else {
65
+ this.timeout = 30000; // 30 seconds for cost
66
+ }
67
+
68
+ return this;
69
+ }
70
+
71
+ /**
72
+ * Build final configuration
73
+ */
74
+ build(): GeminiConfig {
75
+ if (!this.apiKey) {
76
+ throw new Error("API key is required. Call withApiKey() before build()");
77
+ }
78
+
79
+ return {
80
+ apiKey: this.apiKey,
81
+ textModel: this.model,
82
+ defaultTimeoutMs: this.timeout,
83
+ };
84
+ }
85
+
86
+ /**
87
+ * Create a new builder instance
88
+ */
89
+ static create(): GeminiConfigBuilder {
90
+ return new GeminiConfigBuilder();
91
+ }
92
+
93
+ /**
94
+ * Create builder from existing config
95
+ */
96
+ static from(config: GeminiConfig): GeminiConfigBuilder {
97
+ return new GeminiConfigBuilder()
98
+ .withApiKey(config.apiKey)
99
+ .withModel(config.textModel || DEFAULT_MODELS.TEXT)
100
+ .withTimeout(config.defaultTimeoutMs || 30000);
101
+ }
102
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Application Builders
3
+ */
4
+
5
+ export {
6
+ GeminiConfigBuilder,
7
+ type GeminiConfigOptions,
8
+ } from "./config-builder";
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Generation Request DTO
3
+ * Data transfer object for generation requests
4
+ */
5
+
6
+ import type { GeminiContent, GeminiGenerationConfig } from "../../domain/entities";
7
+
8
+ export class GenerationRequest {
9
+ constructor(
10
+ readonly model: string,
11
+ readonly contents: GeminiContent[],
12
+ readonly generationConfig?: GeminiGenerationConfig,
13
+ readonly signal?: AbortSignal
14
+ ) {}
15
+
16
+ /**
17
+ * Create a simple text generation request
18
+ */
19
+ static forText(
20
+ model: string,
21
+ prompt: string,
22
+ config?: GeminiGenerationConfig,
23
+ signal?: AbortSignal
24
+ ): GenerationRequest {
25
+ return new GenerationRequest(model, [], config, signal);
26
+ }
27
+
28
+ /**
29
+ * Create a streaming request
30
+ */
31
+ static forStream(
32
+ model: string,
33
+ prompt: string,
34
+ onChunk: (text: string) => void,
35
+ config?: GeminiGenerationConfig,
36
+ signal?: AbortSignal
37
+ ): GenerationRequest {
38
+ return new GenerationRequest(model, [], config, signal);
39
+ }
40
+
41
+ /**
42
+ * Check if request has abort signal
43
+ */
44
+ hasSignal(): boolean {
45
+ return this.signal !== undefined;
46
+ }
47
+
48
+ /**
49
+ * Check if request is aborted
50
+ */
51
+ isAborted(): boolean {
52
+ return this.signal?.aborted ?? false;
53
+ }
54
+ }
55
+
56
+ export class StructuredGenerationRequest {
57
+ constructor(
58
+ readonly model: string,
59
+ readonly prompt: string,
60
+ readonly schema: Record<string, unknown>,
61
+ readonly config?: Omit<GeminiGenerationConfig, "responseMimeType" | "responseSchema">,
62
+ readonly signal?: AbortSignal
63
+ ) {}
64
+
65
+ /**
66
+ * Get full generation config with JSON response settings
67
+ */
68
+ getConfig(): GeminiGenerationConfig {
69
+ return {
70
+ ...this.config,
71
+ responseMimeType: "application/json",
72
+ responseSchema: this.schema as any,
73
+ };
74
+ }
75
+
76
+ /**
77
+ * Check if request has abort signal
78
+ */
79
+ hasSignal(): boolean {
80
+ return this.signal !== undefined;
81
+ }
82
+
83
+ /**
84
+ * Check if request is aborted
85
+ */
86
+ isAborted(): boolean {
87
+ return this.signal?.aborted ?? false;
88
+ }
89
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Application DTOs
3
+ */
4
+
5
+ export {
6
+ GenerationRequest,
7
+ StructuredGenerationRequest,
8
+ } from "./generation-request.dto";
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Application Layer
3
+ * Use cases and orchestration
4
+ */
5
+
6
+ // DTOs
7
+ export * from "./dtos";
8
+
9
+ // Use Cases
10
+ export * from "./use-cases";
11
+
12
+ // Builders
13
+ export * from "./builders";
14
+
15
+ // Providers
16
+ export * from "./providers";
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Gemini Provider
3
+ * Main provider for dependency injection
4
+ */
5
+
6
+ import { ValidationService } from "../../domain/services/validation.service";
7
+ import { ContentMapper, ResponseMapper } from "../../infrastructure/mappers";
8
+ import {
9
+ GeminiTextRepository,
10
+ GeminiStreamingRepository,
11
+ GeminiStructuredTextRepository,
12
+ } from "../../infrastructure/repositories";
13
+ import { geminiClient } from "../../infrastructure/external/gemini-client.singleton";
14
+ import type { GeminiConfig } from "../../domain/entities";
15
+ import type {
16
+ ITextGenerationRepository,
17
+ IStreamingRepository,
18
+ IStructuredTextRepository,
19
+ } from "../../domain/repositories";
20
+
21
+ export class GeminiProviderClass {
22
+ private static instance: GeminiProviderClass | null = null;
23
+ static resetCalled = false;
24
+
25
+ readonly _validator: ValidationService;
26
+ readonly _contentMapper: ContentMapper;
27
+ readonly _responseMapper: ResponseMapper;
28
+
29
+ private readonly textRepository: ITextGenerationRepository;
30
+ private readonly streamingRepository: IStreamingRepository;
31
+ private readonly structuredTextRepository: IStructuredTextRepository;
32
+
33
+ private constructor() {
34
+ this._validator = new ValidationService();
35
+ this._contentMapper = new ContentMapper();
36
+ this._responseMapper = new ResponseMapper();
37
+
38
+ // Initialize repositories
39
+ const getModel = (name: string) => geminiClient.getModel(name);
40
+
41
+ this.textRepository = new GeminiTextRepository(
42
+ getModel,
43
+ this._validator,
44
+ this._contentMapper,
45
+ this._responseMapper
46
+ );
47
+
48
+ this.streamingRepository = new GeminiStreamingRepository(
49
+ getModel,
50
+ this._validator,
51
+ this._contentMapper
52
+ );
53
+
54
+ this.structuredTextRepository = new GeminiStructuredTextRepository(
55
+ getModel,
56
+ this._validator,
57
+ this._contentMapper,
58
+ this._responseMapper
59
+ );
60
+ }
61
+
62
+ /**
63
+ * Get singleton instance
64
+ */
65
+ static getInstance(): GeminiProviderClass {
66
+ if (!GeminiProviderClass.instance) {
67
+ GeminiProviderClass.instance = new GeminiProviderClass();
68
+ }
69
+ return GeminiProviderClass.instance;
70
+ }
71
+
72
+ /**
73
+ * Initialize with configuration
74
+ */
75
+ initialize(config: GeminiConfig): void {
76
+ geminiClient.initialize(config.apiKey);
77
+ }
78
+
79
+ /**
80
+ * Get validation service (public for use cases)
81
+ */
82
+ getValidator(): ValidationService {
83
+ return this._validator;
84
+ }
85
+
86
+ /**
87
+ * Get content mapper (public for use cases)
88
+ */
89
+ getContentMapper(): ContentMapper {
90
+ return this._contentMapper;
91
+ }
92
+
93
+ /**
94
+ * Get text generation repository
95
+ */
96
+ getTextRepository(): ITextGenerationRepository {
97
+ return this.textRepository;
98
+ }
99
+
100
+ /**
101
+ * Get streaming repository
102
+ */
103
+ getStreamingRepository(): IStreamingRepository {
104
+ return this.streamingRepository;
105
+ }
106
+
107
+ /**
108
+ * Get structured text repository
109
+ */
110
+ getStructuredTextRepository(): IStructuredTextRepository {
111
+ return this.structuredTextRepository;
112
+ }
113
+
114
+ /**
115
+ * Reset provider (for testing)
116
+ */
117
+ static reset(): void {
118
+ GeminiProviderClass.instance = null;
119
+ geminiClient.reset();
120
+ // Also expose globally for React components
121
+ if (typeof global !== 'undefined') {
122
+ (global as any).__geminiProviderReset = true;
123
+ }
124
+ }
125
+ }
126
+
127
+ /**
128
+ * Export singleton instance
129
+ */
130
+ export const geminiProvider = GeminiProviderClass.getInstance();
131
+
132
+ /**
133
+ * Type alias for cleaner API
134
+ */
135
+ export type GeminiProvider = GeminiProviderClass;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Application Providers
3
+ */
4
+
5
+ export { geminiProvider, GeminiProviderClass } from "./gemini-provider";
6
+ export type { GeminiProvider } from "./gemini-provider";
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Generate JSON Use Case
3
+ * Orchestrates structured JSON generation flow
4
+ */
5
+
6
+ import type { GeminiGenerationConfig } from "../../domain/entities";
7
+ import type { IStructuredTextRepository } from "../../domain/repositories/structured-text.repository";
8
+ import { ValidationService } from "../../domain/services/validation.service";
9
+ import { StructuredGenerationRequest } from "../dtos/generation-request.dto";
10
+
11
+ export interface GenerateJSONOptions<T> {
12
+ model: string;
13
+ prompt: string;
14
+ schema: Record<string, unknown>;
15
+ config?: Omit<GeminiGenerationConfig, "responseMimeType" | "responseSchema">;
16
+ signal?: AbortSignal;
17
+ }
18
+
19
+ export interface GenerateJSONResult<T> {
20
+ data: T;
21
+ text: string; // Pretty-printed JSON
22
+ }
23
+
24
+ export class GenerateJSONUseCase {
25
+ constructor(
26
+ private readonly repository: IStructuredTextRepository,
27
+ private readonly validator: ValidationService
28
+ ) {}
29
+
30
+ /**
31
+ * Execute structured JSON generation
32
+ */
33
+ async execute<T>(
34
+ options: GenerateJSONOptions<T>
35
+ ): Promise<GenerateJSONResult<T>> {
36
+ // Validate inputs
37
+ this.validator.validatePrompt(options.prompt);
38
+ this.validator.validateSchema(options.schema);
39
+ this.validator.validateModelName(options.model);
40
+ this.validator.validateConfig(options.config);
41
+
42
+ // Create request
43
+ const request = new StructuredGenerationRequest(
44
+ options.model,
45
+ options.prompt,
46
+ options.schema,
47
+ options.config,
48
+ options.signal
49
+ );
50
+
51
+ // Execute
52
+ const data = await this.repository.generateStructured<T>({
53
+ model: request.model,
54
+ prompt: request.prompt,
55
+ schema: request.schema,
56
+ config: request.config,
57
+ signal: request.signal,
58
+ });
59
+
60
+ return {
61
+ data,
62
+ text: JSON.stringify(data, null, 2),
63
+ };
64
+ }
65
+
66
+ /**
67
+ * Execute simple JSON generation (returns only data)
68
+ */
69
+ async executeSimple<T>(options: GenerateJSONOptions<T>): Promise<T> {
70
+ const result = await this.execute<T>(options);
71
+ return result.data;
72
+ }
73
+ }
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Generate Text Use Case
3
+ * Orchestrates text generation flow
4
+ */
5
+
6
+ import type { GeminiGenerationConfig, GeminiResponse } from "../../domain/entities";
7
+ import type { ITextGenerationRepository } from "../../domain/repositories/text-generation.repository";
8
+ import { ValidationService } from "../../domain/services/validation.service";
9
+ import { GenerationRequest } from "../dtos/generation-request.dto";
10
+ import { ContentMapper } from "../../infrastructure/mappers/content.mapper";
11
+
12
+ export interface GenerateTextOptions {
13
+ model: string;
14
+ prompt: string;
15
+ config?: GeminiGenerationConfig;
16
+ signal?: AbortSignal;
17
+ }
18
+
19
+ export interface GenerateTextResult {
20
+ text: string;
21
+ response?: GeminiResponse;
22
+ }
23
+
24
+ export class GenerateTextUseCase {
25
+ constructor(
26
+ private readonly repository: ITextGenerationRepository,
27
+ private readonly validator: ValidationService,
28
+ private readonly contentMapper: ContentMapper
29
+ ) {}
30
+
31
+ /**
32
+ * Execute text generation
33
+ */
34
+ async execute(options: GenerateTextOptions): Promise<GenerateTextResult> {
35
+ // Validate inputs
36
+ this.validator.validatePrompt(options.prompt);
37
+ this.validator.validateModelName(options.model);
38
+ this.validator.validateConfig(options.config);
39
+
40
+ // Create request
41
+ const contents = [
42
+ this.contentMapper.createTextContent(options.prompt, "user"),
43
+ ];
44
+
45
+ const request = new GenerationRequest(
46
+ options.model,
47
+ contents,
48
+ options.config,
49
+ options.signal
50
+ );
51
+
52
+ // Execute
53
+ const response = await this.repository.generate({
54
+ model: request.model,
55
+ contents: request.contents,
56
+ generationConfig: request.generationConfig,
57
+ signal: request.signal,
58
+ });
59
+
60
+ // Extract text
61
+ const text = await this.repository.generateText(
62
+ options.model,
63
+ options.prompt,
64
+ options.config,
65
+ options.signal
66
+ );
67
+
68
+ return {
69
+ text,
70
+ response,
71
+ };
72
+ }
73
+
74
+ /**
75
+ * Execute simple text generation (returns only text)
76
+ */
77
+ async executeSimple(options: GenerateTextOptions): Promise<string> {
78
+ const result = await this.execute(options);
79
+ return result.text;
80
+ }
81
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Application Use Cases
3
+ */
4
+
5
+ export {
6
+ GenerateTextUseCase,
7
+ type GenerateTextOptions,
8
+ type GenerateTextResult,
9
+ } from "./generate-text.use-case";
10
+
11
+ export {
12
+ StreamContentUseCase,
13
+ type StreamContentOptions,
14
+ } from "./stream-content.use-case";
15
+
16
+ export {
17
+ GenerateJSONUseCase,
18
+ type GenerateJSONOptions,
19
+ type GenerateJSONResult,
20
+ } from "./generate-json.use-case";
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Stream Content Use Case
3
+ * Orchestrates streaming flow
4
+ */
5
+
6
+ import type { GeminiGenerationConfig } from "../../domain/entities";
7
+ import type { IStreamingRepository } from "../../domain/repositories/streaming.repository";
8
+ import { ValidationService } from "../../domain/services/validation.service";
9
+ import { GenerationRequest } from "../dtos/generation-request.dto";
10
+ import { ContentMapper } from "../../infrastructure/mappers/content.mapper";
11
+
12
+ export interface StreamContentOptions {
13
+ model: string;
14
+ prompt: string;
15
+ onChunk: (text: string) => void;
16
+ config?: GeminiGenerationConfig;
17
+ signal?: AbortSignal;
18
+ }
19
+
20
+ export class StreamContentUseCase {
21
+ constructor(
22
+ private readonly repository: IStreamingRepository,
23
+ private readonly validator: ValidationService,
24
+ private readonly contentMapper: ContentMapper
25
+ ) {}
26
+
27
+ /**
28
+ * Execute streaming
29
+ */
30
+ async execute(options: StreamContentOptions): Promise<string> {
31
+ // Validate inputs
32
+ this.validator.validatePrompt(options.prompt);
33
+ this.validator.validateModelName(options.model);
34
+ this.validator.validateCallback(options.onChunk, "onChunk");
35
+ this.validator.validateConfig(options.config);
36
+
37
+ // Execute
38
+ return this.repository.streamText(
39
+ options.model,
40
+ options.prompt,
41
+ options.onChunk,
42
+ options.config,
43
+ options.signal
44
+ );
45
+ }
46
+ }
@@ -86,11 +86,6 @@ export class GeminiError extends Error {
86
86
  this.retryable = info.retryable;
87
87
  this.statusCode = info.statusCode;
88
88
  this.originalError = info.originalError;
89
-
90
- // Maintains proper stack trace (only available on V8)
91
- if (Error.captureStackTrace) {
92
- Error.captureStackTrace(this, GeminiError);
93
- }
94
89
  }
95
90
 
96
91
  /**
@@ -48,7 +48,9 @@ export interface GeminiContent {
48
48
  /**
49
49
  * Individual content part
50
50
  */
51
- export type GeminiPart = { text: string };
51
+ export type GeminiPart =
52
+ | { text: string }
53
+ | { inlineData: { mimeType: string; data: string } };
52
54
 
53
55
  /**
54
56
  * Response structure from Gemini API
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Domain Layer
3
+ * Core business logic and contracts
4
+ */
5
+
6
+ // Entities (re-export from existing)
7
+ export * from "./entities";
8
+
9
+ // Value Objects
10
+ export * from "./value-objects";
11
+
12
+ // Repository Interfaces
13
+ export * from "./repositories";
14
+
15
+ // Services
16
+ export { ValidationService, ValidationError } from "./services/validation.service";
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Domain Repository Interfaces
3
+ * Contracts for infrastructure implementations
4
+ */
5
+
6
+ export type {
7
+ ITextGenerationRepository,
8
+ TextGenerationRequest,
9
+ } from "./text-generation.repository";
10
+
11
+ export type {
12
+ IStreamingRepository,
13
+ StreamingRequest,
14
+ } from "./streaming.repository";
15
+
16
+ export type {
17
+ IStructuredTextRepository,
18
+ StructuredGenerationRequest,
19
+ } from "./structured-text.repository";