@umituz/react-native-ai-generation-content 1.17.309 → 1.18.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.
Files changed (25) hide show
  1. package/package.json +1 -1
  2. package/src/features/anime-selfie/domain/types/anime-selfie.types.ts +1 -0
  3. package/src/features/anime-selfie/presentation/hooks/useAnimeSelfieFeature.ts +31 -126
  4. package/src/features/hd-touch-up/domain/types/hd-touch-up.types.ts +1 -0
  5. package/src/features/hd-touch-up/presentation/hooks/useHDTouchUpFeature.ts +25 -105
  6. package/src/features/image-to-image/presentation/hooks/useDualImageFeature.ts +111 -75
  7. package/src/features/image-to-image/presentation/hooks/useImageWithPromptFeature.ts +115 -84
  8. package/src/features/image-to-image/presentation/hooks/useSingleImageFeature.ts +93 -69
  9. package/src/features/photo-restoration/domain/types/photo-restore.types.ts +1 -0
  10. package/src/features/photo-restoration/presentation/hooks/usePhotoRestoreFeature.ts +25 -121
  11. package/src/features/remove-object/presentation/hooks/useRemoveObjectFeature.ts +125 -79
  12. package/src/features/shared/dual-image-video/presentation/hooks/useDualImageVideoFeature.ts +106 -64
  13. package/src/index.ts +6 -4
  14. package/src/presentation/hooks/generation/index.ts +19 -0
  15. package/src/presentation/hooks/generation/useImageGeneration.ts +157 -0
  16. package/src/presentation/hooks/generation/useVideoGeneration.ts +107 -0
  17. package/src/presentation/hooks/index.ts +8 -12
  18. package/src/presentation/hooks/base/index.ts +0 -9
  19. package/src/presentation/hooks/base/types.ts +0 -47
  20. package/src/presentation/hooks/base/use-dual-image-feature.ts +0 -170
  21. package/src/presentation/hooks/base/use-image-with-prompt-feature.ts +0 -167
  22. package/src/presentation/hooks/base/use-single-image-feature.ts +0 -154
  23. package/src/presentation/hooks/base/utils/feature-state.factory.ts +0 -133
  24. package/src/presentation/hooks/generation-callbacks.types.ts +0 -42
  25. package/src/presentation/hooks/useGenerationCallbacksBuilder.ts +0 -126
@@ -1,13 +1,18 @@
1
1
  /**
2
2
  * useRemoveObjectFeature Hook
3
3
  * Manages remove object feature state and actions
4
+ * Uses centralized orchestrator for credit/error handling
4
5
  */
5
6
 
6
- import { useState, useCallback, useRef } from "react";
7
+ import { useState, useCallback, useRef, useMemo } from "react";
7
8
  import { generateUUID } from "@umituz/react-native-design-system";
8
9
  import { executeImageFeature } from "../../../../infrastructure/services";
10
+ import {
11
+ useGenerationOrchestrator,
12
+ type GenerationStrategy,
13
+ type AlertMessages,
14
+ } from "../../../../presentation/hooks/generation";
9
15
  import type {
10
- RemoveObjectFeatureState,
11
16
  RemoveObjectFeatureConfig,
12
17
  RemoveObjectResult,
13
18
  } from "../../domain/types";
@@ -20,7 +25,23 @@ export interface UseRemoveObjectFeatureProps {
20
25
  onBeforeProcess?: () => Promise<boolean>;
21
26
  }
22
27
 
23
- export interface UseRemoveObjectFeatureReturn extends RemoveObjectFeatureState {
28
+ export interface UseRemoveObjectFeatureOptions {
29
+ /** Alert messages for error handling */
30
+ alertMessages?: AlertMessages;
31
+ /** User ID for credit operations */
32
+ userId?: string;
33
+ /** Callback when credits are exhausted */
34
+ onCreditsExhausted?: () => void;
35
+ }
36
+
37
+ export interface UseRemoveObjectFeatureReturn {
38
+ imageUri: string | null;
39
+ maskUri: string | null;
40
+ prompt: string;
41
+ processedUrl: string | null;
42
+ isProcessing: boolean;
43
+ progress: number;
44
+ error: string | null;
24
45
  selectImage: () => Promise<void>;
25
46
  selectMask: () => Promise<void>;
26
47
  setPrompt: (prompt: string) => void;
@@ -29,33 +50,85 @@ export interface UseRemoveObjectFeatureReturn extends RemoveObjectFeatureState {
29
50
  reset: () => void;
30
51
  }
31
52
 
32
- const initialState: RemoveObjectFeatureState = {
33
- imageUri: null,
34
- maskUri: null,
35
- prompt: "",
36
- processedUrl: null,
37
- isProcessing: false,
38
- progress: 0,
39
- error: null,
53
+ const DEFAULT_ALERT_MESSAGES: AlertMessages = {
54
+ networkError: "No internet connection. Please check your network.",
55
+ policyViolation: "Content not allowed. Please try a different image.",
56
+ saveFailed: "Failed to save result. Please try again.",
57
+ creditFailed: "Credit operation failed. Please try again.",
58
+ unknown: "An error occurred. Please try again.",
40
59
  };
41
60
 
61
+ interface RemoveObjectInput {
62
+ imageBase64: string;
63
+ maskBase64?: string;
64
+ prompt?: string;
65
+ }
66
+
42
67
  export function useRemoveObjectFeature(
43
68
  props: UseRemoveObjectFeatureProps,
69
+ options?: UseRemoveObjectFeatureOptions,
44
70
  ): UseRemoveObjectFeatureReturn {
45
71
  const { config, onSelectImage, onSelectMask, onSaveImage, onBeforeProcess } = props;
46
- const [state, setState] = useState<RemoveObjectFeatureState>(initialState);
72
+
73
+ // UI state (separate from orchestrator state)
74
+ const [imageUri, setImageUri] = useState<string | null>(null);
75
+ const [maskUri, setMaskUri] = useState<string | null>(null);
76
+ const [prompt, setPromptState] = useState("");
77
+ const [imageError, setImageError] = useState<string | null>(null);
47
78
  const creationIdRef = useRef<string | null>(null);
48
79
 
80
+ // Create strategy for orchestrator
81
+ const strategy: GenerationStrategy<RemoveObjectInput, string> = useMemo(
82
+ () => ({
83
+ execute: async (input, onProgress) => {
84
+ const result = await executeImageFeature(
85
+ "remove-object",
86
+ {
87
+ imageBase64: input.imageBase64,
88
+ targetImageBase64: input.maskBase64,
89
+ prompt: input.prompt,
90
+ },
91
+ { extractResult: config.extractResult, onProgress },
92
+ );
93
+
94
+ if (!result.success || !result.imageUrl) {
95
+ throw new Error(result.error || "Processing failed");
96
+ }
97
+
98
+ // Notify completion with creationId
99
+ const creationId = creationIdRef.current;
100
+ if (creationId) {
101
+ config.onProcessingComplete?.({ ...result, creationId } as RemoveObjectResult & { creationId?: string });
102
+ }
103
+
104
+ return result.imageUrl;
105
+ },
106
+ getCreditCost: () => config.creditCost || 1,
107
+ }),
108
+ [config],
109
+ );
110
+
111
+ // Use orchestrator for generation
112
+ const orchestrator = useGenerationOrchestrator(strategy, {
113
+ userId: options?.userId,
114
+ alertMessages: options?.alertMessages || DEFAULT_ALERT_MESSAGES,
115
+ onCreditsExhausted: options?.onCreditsExhausted,
116
+ onError: (error) => {
117
+ config.onError?.(error.message, creationIdRef.current ?? undefined);
118
+ },
119
+ });
120
+
49
121
  const selectImage = useCallback(async () => {
50
122
  try {
51
123
  const uri = await onSelectImage();
52
124
  if (uri) {
53
- setState((prev) => ({ ...prev, imageUri: uri, error: null }));
125
+ setImageUri(uri);
126
+ setImageError(null);
54
127
  config.onImageSelect?.(uri);
55
128
  }
56
129
  } catch (error) {
57
130
  const message = error instanceof Error ? error.message : String(error);
58
- setState((prev) => ({ ...prev, error: message }));
131
+ setImageError(message);
59
132
  }
60
133
  }, [onSelectImage, config]);
61
134
 
@@ -65,25 +138,23 @@ export function useRemoveObjectFeature(
65
138
  try {
66
139
  const uri = await onSelectMask();
67
140
  if (uri) {
68
- setState((prev) => ({ ...prev, maskUri: uri, error: null }));
141
+ setMaskUri(uri);
142
+ setImageError(null);
69
143
  config.onMaskSelect?.(uri);
70
144
  }
71
145
  } catch (error) {
72
146
  const message = error instanceof Error ? error.message : String(error);
73
- setState((prev) => ({ ...prev, error: message }));
147
+ setImageError(message);
74
148
  }
75
149
  }, [onSelectMask, config]);
76
150
 
77
- const setPrompt = useCallback((prompt: string) => {
78
- setState((prev) => ({ ...prev, prompt }));
79
- }, []);
80
-
81
- const handleProgress = useCallback((progress: number) => {
82
- setState((prev) => ({ ...prev, progress }));
151
+ const setPrompt = useCallback((newPrompt: string) => {
152
+ setPromptState(newPrompt);
153
+ setImageError(null);
83
154
  }, []);
84
155
 
85
156
  const process = useCallback(async () => {
86
- if (!state.imageUri) return;
157
+ if (!imageUri) return;
87
158
 
88
159
  if (onBeforeProcess) {
89
160
  const canProceed = await onBeforeProcess();
@@ -93,78 +164,53 @@ export function useRemoveObjectFeature(
93
164
  const creationId = generateUUID();
94
165
  creationIdRef.current = creationId;
95
166
 
96
- setState((prev) => ({
97
- ...prev,
98
- isProcessing: true,
99
- progress: 0,
100
- error: null,
101
- }));
102
-
103
- config.onProcessingStart?.({ creationId, imageUri: state.imageUri });
167
+ config.onProcessingStart?.({ creationId, imageUri });
104
168
 
105
169
  try {
106
- const imageBase64 = await config.prepareImage(state.imageUri);
107
- const maskBase64 = state.maskUri
108
- ? await config.prepareImage(state.maskUri)
170
+ const imageBase64 = await config.prepareImage(imageUri);
171
+ const maskBase64 = maskUri
172
+ ? await config.prepareImage(maskUri)
109
173
  : undefined;
110
174
 
111
- const result = await executeImageFeature(
112
- "remove-object",
113
- {
114
- imageBase64,
115
- targetImageBase64: maskBase64,
116
- prompt: state.prompt || undefined,
117
- },
118
- { extractResult: config.extractResult, onProgress: handleProgress },
119
- );
120
-
121
- if (result.success && result.imageUrl) {
122
- setState((prev) => ({
123
- ...prev,
124
- isProcessing: false,
125
- processedUrl: result.imageUrl!,
126
- progress: 100,
127
- }));
128
- config.onProcessingComplete?.({ ...result, creationId } as RemoveObjectResult & { creationId?: string });
129
- } else {
130
- const errorMessage = result.error || "Processing failed";
131
- setState((prev) => ({
132
- ...prev,
133
- isProcessing: false,
134
- error: errorMessage,
135
- progress: 0,
136
- }));
137
- config.onError?.(errorMessage, creationId);
138
- }
175
+ await orchestrator.generate({
176
+ imageBase64,
177
+ maskBase64,
178
+ prompt: prompt || undefined,
179
+ });
139
180
  } catch (error) {
140
- const message = error instanceof Error ? error.message : String(error);
141
- setState((prev) => ({
142
- ...prev,
143
- isProcessing: false,
144
- error: message,
145
- progress: 0,
146
- }));
147
- config.onError?.(message, creationIdRef.current ?? undefined);
181
+ // Error already handled by orchestrator
148
182
  }
149
- }, [state.imageUri, state.maskUri, state.prompt, config, handleProgress, onBeforeProcess]);
183
+ }, [imageUri, maskUri, prompt, config, onBeforeProcess, orchestrator]);
150
184
 
151
185
  const save = useCallback(async () => {
152
- if (!state.processedUrl) return;
186
+ if (!orchestrator.result) return;
153
187
 
154
188
  try {
155
- await onSaveImage(state.processedUrl);
189
+ await onSaveImage(orchestrator.result);
156
190
  } catch (error) {
157
191
  const message = error instanceof Error ? error.message : String(error);
158
- setState((prev) => ({ ...prev, error: message }));
192
+ setImageError(message);
159
193
  }
160
- }, [state.processedUrl, onSaveImage]);
194
+ }, [orchestrator.result, onSaveImage]);
161
195
 
162
196
  const reset = useCallback(() => {
163
- setState(initialState);
164
- }, []);
165
-
197
+ setImageUri(null);
198
+ setMaskUri(null);
199
+ setPromptState("");
200
+ setImageError(null);
201
+ creationIdRef.current = null;
202
+ orchestrator.reset();
203
+ }, [orchestrator]);
204
+
205
+ // Combine states for backward compatibility
166
206
  return {
167
- ...state,
207
+ imageUri,
208
+ maskUri,
209
+ prompt,
210
+ processedUrl: orchestrator.result,
211
+ isProcessing: orchestrator.isGenerating,
212
+ progress: orchestrator.progress,
213
+ error: orchestrator.error?.message || imageError,
168
214
  selectImage,
169
215
  selectMask,
170
216
  setPrompt,
@@ -2,43 +2,104 @@
2
2
  * useDualImageVideoFeature Hook
3
3
  * Base hook for video features that take two images (ai-hug, ai-kiss, etc.)
4
4
  * DRY: Consolidates common logic from useAIHugFeature and useAIKissFeature
5
+ * Uses centralized orchestrator for credit/error handling
5
6
  */
6
7
 
7
- import { useState, useCallback, useRef } from "react";
8
+ import { useState, useCallback, useRef, useMemo } from "react";
8
9
  import { executeVideoFeature } from "../../../../../infrastructure/services";
9
10
  import { generateCreationId } from "../../../../../domains/creations/domain/utils";
11
+ import {
12
+ useGenerationOrchestrator,
13
+ type GenerationStrategy,
14
+ type AlertMessages,
15
+ } from "../../../../../presentation/hooks/generation";
10
16
  import type {
11
- DualImageVideoFeatureState,
12
17
  UseDualImageVideoFeatureProps,
13
18
  UseDualImageVideoFeatureReturn,
14
19
  } from "../../domain/types/dual-image-video.types";
15
20
 
16
- const initialState: DualImageVideoFeatureState = {
17
- sourceImageUri: null,
18
- targetImageUri: null,
19
- processedVideoUrl: null,
20
- isProcessing: false,
21
- progress: 0,
22
- error: null,
21
+ export interface DualImageVideoFeatureOptions {
22
+ /** Alert messages for error handling */
23
+ alertMessages?: AlertMessages;
24
+ /** User ID for credit operations */
25
+ userId?: string;
26
+ /** Callback when credits are exhausted */
27
+ onCreditsExhausted?: () => void;
28
+ }
29
+
30
+ const DEFAULT_ALERT_MESSAGES: AlertMessages = {
31
+ networkError: "No internet connection. Please check your network.",
32
+ policyViolation: "Content not allowed. Please try different images.",
33
+ saveFailed: "Failed to save result. Please try again.",
34
+ creditFailed: "Credit operation failed. Please try again.",
35
+ unknown: "An error occurred. Please try again.",
23
36
  };
24
37
 
38
+ interface DualImageVideoInput {
39
+ sourceImageBase64: string;
40
+ targetImageBase64: string;
41
+ }
42
+
25
43
  export function useDualImageVideoFeature(
26
44
  props: UseDualImageVideoFeatureProps,
45
+ options?: DualImageVideoFeatureOptions,
27
46
  ): UseDualImageVideoFeatureReturn {
28
47
  const { featureType, config, onSelectSourceImage, onSelectTargetImage, onSaveVideo, onBeforeProcess } = props;
29
- const [state, setState] = useState<DualImageVideoFeatureState>(initialState);
48
+
49
+ // Image selection state (separate from orchestrator state)
50
+ const [sourceImageUri, setSourceImageUri] = useState<string | null>(null);
51
+ const [targetImageUri, setTargetImageUri] = useState<string | null>(null);
52
+ const [imageError, setImageError] = useState<string | null>(null);
30
53
  const currentCreationIdRef = useRef<string | null>(null);
31
54
 
55
+ // Create strategy for orchestrator
56
+ const strategy: GenerationStrategy<DualImageVideoInput, string> = useMemo(
57
+ () => ({
58
+ execute: async (input, onProgress) => {
59
+ const result = await executeVideoFeature(
60
+ featureType,
61
+ { sourceImageBase64: input.sourceImageBase64, targetImageBase64: input.targetImageBase64 },
62
+ { extractResult: config.extractResult, onProgress },
63
+ );
64
+
65
+ if (!result.success || !result.videoUrl) {
66
+ throw new Error(result.error || "Processing failed");
67
+ }
68
+
69
+ // Notify completion with creationId
70
+ const creationId = currentCreationIdRef.current;
71
+ if (creationId) {
72
+ config.onProcessingComplete?.({ success: true, videoUrl: result.videoUrl, creationId });
73
+ }
74
+
75
+ return result.videoUrl;
76
+ },
77
+ getCreditCost: () => config.creditCost || 1,
78
+ }),
79
+ [featureType, config],
80
+ );
81
+
82
+ // Use orchestrator for generation
83
+ const orchestrator = useGenerationOrchestrator(strategy, {
84
+ userId: options?.userId,
85
+ alertMessages: options?.alertMessages || DEFAULT_ALERT_MESSAGES,
86
+ onCreditsExhausted: options?.onCreditsExhausted,
87
+ onError: (error) => {
88
+ config.onError?.(error.message, currentCreationIdRef.current ?? undefined);
89
+ },
90
+ });
91
+
32
92
  const selectSourceImage = useCallback(async () => {
33
93
  try {
34
94
  const uri = await onSelectSourceImage();
35
95
  if (uri) {
36
- setState((prev) => ({ ...prev, sourceImageUri: uri, error: null }));
96
+ setSourceImageUri(uri);
97
+ setImageError(null);
37
98
  config.onSourceImageSelect?.(uri);
38
99
  }
39
100
  } catch (error) {
40
101
  const message = error instanceof Error ? error.message : String(error);
41
- setState((prev) => ({ ...prev, error: message }));
102
+ setImageError(message);
42
103
  }
43
104
  }, [onSelectSourceImage, config]);
44
105
 
@@ -46,21 +107,18 @@ export function useDualImageVideoFeature(
46
107
  try {
47
108
  const uri = await onSelectTargetImage();
48
109
  if (uri) {
49
- setState((prev) => ({ ...prev, targetImageUri: uri, error: null }));
110
+ setTargetImageUri(uri);
111
+ setImageError(null);
50
112
  config.onTargetImageSelect?.(uri);
51
113
  }
52
114
  } catch (error) {
53
115
  const message = error instanceof Error ? error.message : String(error);
54
- setState((prev) => ({ ...prev, error: message }));
116
+ setImageError(message);
55
117
  }
56
118
  }, [onSelectTargetImage, config]);
57
119
 
58
- const handleProgress = useCallback((progress: number) => {
59
- setState((prev) => ({ ...prev, progress }));
60
- }, []);
61
-
62
120
  const process = useCallback(async () => {
63
- if (!state.sourceImageUri || !state.targetImageUri) return;
121
+ if (!sourceImageUri || !targetImageUri) return;
64
122
 
65
123
  if (onBeforeProcess) {
66
124
  const canProceed = await onBeforeProcess();
@@ -71,69 +129,53 @@ export function useDualImageVideoFeature(
71
129
  const creationId = generateCreationId();
72
130
  currentCreationIdRef.current = creationId;
73
131
 
74
- setState((prev) => ({
75
- ...prev,
76
- isProcessing: true,
77
- progress: 0,
78
- error: null,
79
- }));
80
-
81
132
  // Notify start with creationId for Firestore creation
82
133
  config.onProcessingStart?.({
83
134
  creationId,
84
135
  featureType,
85
- sourceImageUri: state.sourceImageUri,
86
- targetImageUri: state.targetImageUri,
136
+ sourceImageUri,
137
+ targetImageUri,
87
138
  });
88
139
 
89
- const sourceImageBase64 = await config.prepareImage(state.sourceImageUri);
90
- const targetImageBase64 = await config.prepareImage(state.targetImageUri);
140
+ try {
141
+ const [sourceImageBase64, targetImageBase64] = await Promise.all([
142
+ config.prepareImage(sourceImageUri),
143
+ config.prepareImage(targetImageUri),
144
+ ]);
91
145
 
92
- const result = await executeVideoFeature(
93
- featureType,
94
- { sourceImageBase64, targetImageBase64 },
95
- { extractResult: config.extractResult, onProgress: handleProgress },
96
- );
97
-
98
- if (result.success && result.videoUrl) {
99
- setState((prev) => ({
100
- ...prev,
101
- isProcessing: false,
102
- processedVideoUrl: result.videoUrl!,
103
- progress: 100,
104
- }));
105
- // Notify completion with creationId and videoUrl for Firestore update
106
- config.onProcessingComplete?.({ success: true, videoUrl: result.videoUrl, creationId });
107
- } else {
108
- const errorMessage = result.error || "Processing failed";
109
- setState((prev) => ({
110
- ...prev,
111
- isProcessing: false,
112
- error: errorMessage,
113
- progress: 0,
114
- }));
115
- // Notify error with creationId for Firestore update to "failed"
116
- config.onError?.(errorMessage, creationId);
146
+ await orchestrator.generate({ sourceImageBase64, targetImageBase64 });
147
+ } catch (error) {
148
+ // Error already handled by orchestrator
117
149
  }
118
- }, [state.sourceImageUri, state.targetImageUri, featureType, config, handleProgress, onBeforeProcess]);
150
+ }, [sourceImageUri, targetImageUri, featureType, config, onBeforeProcess, orchestrator]);
119
151
 
120
152
  const save = useCallback(async () => {
121
- if (!state.processedVideoUrl) return;
153
+ if (!orchestrator.result) return;
122
154
 
123
155
  try {
124
- await onSaveVideo(state.processedVideoUrl);
156
+ await onSaveVideo(orchestrator.result);
125
157
  } catch (error) {
126
158
  const message = error instanceof Error ? error.message : String(error);
127
- setState((prev) => ({ ...prev, error: message }));
159
+ setImageError(message);
128
160
  }
129
- }, [state.processedVideoUrl, onSaveVideo]);
161
+ }, [orchestrator.result, onSaveVideo]);
130
162
 
131
163
  const reset = useCallback(() => {
132
- setState(initialState);
133
- }, []);
134
-
164
+ setSourceImageUri(null);
165
+ setTargetImageUri(null);
166
+ setImageError(null);
167
+ currentCreationIdRef.current = null;
168
+ orchestrator.reset();
169
+ }, [orchestrator]);
170
+
171
+ // Combine states for backward compatibility
135
172
  return {
136
- ...state,
173
+ sourceImageUri,
174
+ targetImageUri,
175
+ processedVideoUrl: orchestrator.result,
176
+ isProcessing: orchestrator.isGenerating,
177
+ progress: orchestrator.progress,
178
+ error: orchestrator.error?.message || imageError,
137
179
  selectSourceImage,
138
180
  selectTargetImage,
139
181
  process,
package/src/index.ts CHANGED
@@ -68,18 +68,20 @@ export type { ModerationResult, ModerationConfig, SynchronousGenerationInput, Sy
68
68
 
69
69
  export {
70
70
  useGeneration, usePendingJobs, useBackgroundGeneration,
71
- useGenerationFlow, useGenerationCallbacksBuilder, useAIFeatureCallbacks,
72
- useGenerationOrchestrator, createGenerationError, getAlertMessage, parseError,
71
+ useGenerationFlow, useAIFeatureCallbacks,
72
+ useGenerationOrchestrator, useImageGeneration, useVideoGeneration,
73
+ createGenerationError, getAlertMessage, parseError,
73
74
  } from "./presentation/hooks";
74
75
 
75
76
  export type {
76
77
  UseGenerationOptions, UseGenerationReturn, UsePendingJobsOptions, UsePendingJobsReturn,
77
78
  UseBackgroundGenerationOptions, UseBackgroundGenerationReturn, DirectExecutionResult,
78
- UseGenerationFlowOptions, UseGenerationFlowReturn, CreditType, GenerationExecutionResult,
79
- GenerationCallbacksConfig, GenerationCallbacks, UseGenerationCallbacksBuilderOptions,
79
+ UseGenerationFlowOptions, UseGenerationFlowReturn,
80
80
  AIFeatureCallbacksConfig, AIFeatureCallbacks, AIFeatureGenerationResult,
81
81
  GenerationStrategy, GenerationConfig, GenerationState, OrchestratorStatus,
82
82
  GenerationError, GenerationErrorType, AlertMessages, UseGenerationOrchestratorReturn,
83
+ SingleImageInput, DualImageInput, ImageGenerationInput, ImageGenerationConfig,
84
+ DualImageVideoInput, VideoGenerationConfig,
83
85
  } from "./presentation/hooks";
84
86
 
85
87
  export {
@@ -3,8 +3,14 @@
3
3
  * Feature-agnostic AI generation orchestration
4
4
  */
5
5
 
6
+ // Core orchestrator
6
7
  export { useGenerationOrchestrator } from "./orchestrator";
7
8
 
9
+ // Generic feature hooks
10
+ export { useImageGeneration } from "./useImageGeneration";
11
+ export { useVideoGeneration } from "./useVideoGeneration";
12
+
13
+ // Types
8
14
  export type {
9
15
  GenerationStrategy,
10
16
  GenerationConfig,
@@ -16,6 +22,19 @@ export type {
16
22
  UseGenerationOrchestratorReturn,
17
23
  } from "./types";
18
24
 
25
+ export type {
26
+ SingleImageInput,
27
+ DualImageInput,
28
+ ImageGenerationInput,
29
+ ImageGenerationConfig,
30
+ } from "./useImageGeneration";
31
+
32
+ export type {
33
+ DualImageVideoInput,
34
+ VideoGenerationConfig,
35
+ } from "./useVideoGeneration";
36
+
37
+ // Error utilities
19
38
  export {
20
39
  createGenerationError,
21
40
  getAlertMessage,