@umituz/react-native-ai-generation-content 1.19.6 → 1.19.8
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 +1 -1
- package/src/features/couple-future/infrastructure/executor.ts +81 -11
- package/src/features/couple-future/presentation/hooks/coupleFutureFlow.types.ts +71 -0
- package/src/features/couple-future/presentation/hooks/useCoupleFutureFlow.ts +123 -146
- package/src/features/couple-future/presentation/hooks/useCoupleFutureGeneration.ts +61 -19
- package/src/presentation/hooks/generation/orchestrator.ts +85 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-ai-generation-content",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.8",
|
|
4
4
|
"description": "Provider-agnostic AI generation orchestration for React Native with result preview components",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "src/index.ts",
|
|
@@ -18,23 +18,51 @@ export async function executeCoupleFuture(
|
|
|
18
18
|
input: CoupleFutureInput,
|
|
19
19
|
config?: CoupleFutureConfig,
|
|
20
20
|
): Promise<CoupleFutureResult> {
|
|
21
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
22
|
+
console.log("[Executor] ========== COUPLE FUTURE START ==========");
|
|
23
|
+
console.log("[Executor] Input received:", {
|
|
24
|
+
hasPartnerA: !!input.partnerABase64,
|
|
25
|
+
partnerALength: input.partnerABase64?.length || 0,
|
|
26
|
+
hasPartnerB: !!input.partnerBBase64,
|
|
27
|
+
partnerBLength: input.partnerBBase64?.length || 0,
|
|
28
|
+
promptLength: input.prompt?.length || 0,
|
|
29
|
+
prompt: input.prompt?.slice(0, 300),
|
|
30
|
+
});
|
|
31
|
+
console.log("[Executor] Config:", {
|
|
32
|
+
hasOnProgress: !!config?.onProgress,
|
|
33
|
+
timeoutMs: config?.timeoutMs,
|
|
34
|
+
aspectRatio: config?.aspectRatio,
|
|
35
|
+
outputFormat: config?.outputFormat,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
21
39
|
const provider = providerRegistry.getActiveProvider();
|
|
22
40
|
|
|
23
41
|
if (!provider) {
|
|
42
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
43
|
+
console.log("[Executor] ❌ No AI provider configured");
|
|
44
|
+
}
|
|
24
45
|
return { success: false, error: "No AI provider configured" };
|
|
25
46
|
}
|
|
26
47
|
|
|
48
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
49
|
+
console.log("[Executor] ✅ Provider found:", provider.constructor.name);
|
|
50
|
+
}
|
|
51
|
+
|
|
27
52
|
if (!provider.isInitialized()) {
|
|
53
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
54
|
+
console.log("[Executor] ❌ AI provider not initialized");
|
|
55
|
+
}
|
|
28
56
|
return { success: false, error: "AI provider not initialized" };
|
|
29
57
|
}
|
|
30
58
|
|
|
31
|
-
const { onProgress, timeoutMs, aspectRatio, outputFormat } = config ?? {};
|
|
32
|
-
let lastStatus = "";
|
|
33
|
-
|
|
34
59
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
35
|
-
console.log("[
|
|
60
|
+
console.log("[Executor] ✅ Provider initialized");
|
|
36
61
|
}
|
|
37
62
|
|
|
63
|
+
const { onProgress, timeoutMs, aspectRatio, outputFormat } = config ?? {};
|
|
64
|
+
let lastStatus = "";
|
|
65
|
+
|
|
38
66
|
try {
|
|
39
67
|
onProgress?.(5);
|
|
40
68
|
|
|
@@ -42,7 +70,18 @@ export async function executeCoupleFuture(
|
|
|
42
70
|
.filter(Boolean)
|
|
43
71
|
.map(formatBase64);
|
|
44
72
|
|
|
73
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
74
|
+
console.log("[Executor] 🖼️ Image URLs prepared:", {
|
|
75
|
+
count: imageUrls.length,
|
|
76
|
+
url1Length: imageUrls[0]?.length || 0,
|
|
77
|
+
url2Length: imageUrls[1]?.length || 0,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
45
81
|
if (imageUrls.length < 2) {
|
|
82
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
83
|
+
console.log("[Executor] ❌ Two reference images required, got:", imageUrls.length);
|
|
84
|
+
}
|
|
46
85
|
return { success: false, error: "Two reference images required" };
|
|
47
86
|
}
|
|
48
87
|
|
|
@@ -59,7 +98,16 @@ export async function executeCoupleFuture(
|
|
|
59
98
|
};
|
|
60
99
|
|
|
61
100
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
62
|
-
console.log("[
|
|
101
|
+
console.log("[Executor] 📤 FAL AI Request:");
|
|
102
|
+
console.log("[Executor] Model:", COUPLE_FUTURE_DEFAULTS.model);
|
|
103
|
+
console.log("[Executor] Prompt:", enhancedPrompt.slice(0, 400));
|
|
104
|
+
console.log("[Executor] Aspect ratio:", modelInput.aspect_ratio);
|
|
105
|
+
console.log("[Executor] Output format:", modelInput.output_format);
|
|
106
|
+
console.log("[Executor] Timeout:", timeoutMs ?? COUPLE_FUTURE_DEFAULTS.timeoutMs);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
110
|
+
console.log("[Executor] 📡 Calling provider.subscribe()...");
|
|
63
111
|
}
|
|
64
112
|
|
|
65
113
|
const result = await provider.subscribe(COUPLE_FUTURE_DEFAULTS.model, modelInput, {
|
|
@@ -69,7 +117,10 @@ export async function executeCoupleFuture(
|
|
|
69
117
|
lastStatus = status.status;
|
|
70
118
|
|
|
71
119
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
72
|
-
console.log("[
|
|
120
|
+
console.log("[Executor] 📊 Queue status update:", {
|
|
121
|
+
status: status.status,
|
|
122
|
+
logs: status.logs?.slice(-3),
|
|
123
|
+
});
|
|
73
124
|
}
|
|
74
125
|
|
|
75
126
|
if (status.status === "IN_QUEUE") onProgress?.(20);
|
|
@@ -80,8 +131,10 @@ export async function executeCoupleFuture(
|
|
|
80
131
|
onProgress?.(90);
|
|
81
132
|
|
|
82
133
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
83
|
-
console.log("[
|
|
84
|
-
console.log("[
|
|
134
|
+
console.log("[Executor] 📥 FAL AI Response received");
|
|
135
|
+
console.log("[Executor] Raw result type:", typeof result);
|
|
136
|
+
console.log("[Executor] Raw result keys:", result ? Object.keys(result as object) : "null");
|
|
137
|
+
console.log("[Executor] Raw result:", JSON.stringify(result, null, 2).slice(0, 1000));
|
|
85
138
|
}
|
|
86
139
|
|
|
87
140
|
const rawResult = result as Record<string, unknown>;
|
|
@@ -89,21 +142,38 @@ export async function executeCoupleFuture(
|
|
|
89
142
|
const imageUrl = data?.images?.[0]?.url;
|
|
90
143
|
|
|
91
144
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
92
|
-
console.log("[
|
|
93
|
-
console.log("[
|
|
145
|
+
console.log("[Executor] 🔍 Parsed response:");
|
|
146
|
+
console.log("[Executor] Has data:", !!data);
|
|
147
|
+
console.log("[Executor] Images array length:", data?.images?.length || 0);
|
|
148
|
+
console.log("[Executor] First image URL:", imageUrl?.slice(0, 100));
|
|
94
149
|
}
|
|
95
150
|
|
|
96
151
|
onProgress?.(100);
|
|
97
152
|
|
|
98
153
|
if (!imageUrl) {
|
|
154
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
155
|
+
console.log("[Executor] ❌ No image URL in response");
|
|
156
|
+
console.log("[Executor] ========== COUPLE FUTURE END (FAILED) ==========");
|
|
157
|
+
}
|
|
99
158
|
return { success: false, error: "No image generated" };
|
|
100
159
|
}
|
|
101
160
|
|
|
161
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
162
|
+
console.log("[Executor] ✅ Generation successful!");
|
|
163
|
+
console.log("[Executor] Image URL:", imageUrl.slice(0, 100));
|
|
164
|
+
console.log("[Executor] ========== COUPLE FUTURE END (SUCCESS) ==========");
|
|
165
|
+
}
|
|
166
|
+
|
|
102
167
|
return { success: true, imageUrl };
|
|
103
168
|
} catch (error) {
|
|
104
169
|
const message = error instanceof Error ? error.message : "Generation failed";
|
|
105
170
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
106
|
-
console.error("[
|
|
171
|
+
console.error("[Executor] ❌ Exception caught:", {
|
|
172
|
+
message,
|
|
173
|
+
name: error instanceof Error ? error.name : "Unknown",
|
|
174
|
+
stack: error instanceof Error ? error.stack?.slice(0, 500) : undefined,
|
|
175
|
+
});
|
|
176
|
+
console.log("[Executor] ========== COUPLE FUTURE END (ERROR) ==========");
|
|
107
177
|
}
|
|
108
178
|
return { success: false, error: message };
|
|
109
179
|
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Couple Future Flow Types
|
|
3
|
+
* Type definitions for couple future wizard flow
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export interface CoupleFutureFlowConfig<TStep, TScenarioId> {
|
|
7
|
+
steps: {
|
|
8
|
+
SCENARIO: TStep;
|
|
9
|
+
SCENARIO_PREVIEW: TStep;
|
|
10
|
+
COUPLE_FEATURE_SELECTOR: TStep;
|
|
11
|
+
TEXT_INPUT: TStep;
|
|
12
|
+
PARTNER_A: TStep;
|
|
13
|
+
PARTNER_B: TStep;
|
|
14
|
+
GENERATING: TStep;
|
|
15
|
+
};
|
|
16
|
+
customScenarioId: TScenarioId;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface CoupleFutureFlowState<TStep, TScenarioId> {
|
|
20
|
+
step: TStep;
|
|
21
|
+
selectedScenarioId: TScenarioId | null;
|
|
22
|
+
selectedFeature: string | null;
|
|
23
|
+
partnerA: unknown;
|
|
24
|
+
partnerB: unknown;
|
|
25
|
+
partnerAName: string;
|
|
26
|
+
partnerBName: string;
|
|
27
|
+
customPrompt: string | null;
|
|
28
|
+
visualStyle: string | null;
|
|
29
|
+
selection: unknown;
|
|
30
|
+
isProcessing: boolean;
|
|
31
|
+
scenarioConfig: unknown;
|
|
32
|
+
selectedScenarioData: { requiresPhoto?: boolean } | null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface CoupleFutureFlowActions<TStep, TScenarioId, TResult> {
|
|
36
|
+
setStep: (step: TStep) => void;
|
|
37
|
+
selectScenario: (id: TScenarioId) => void;
|
|
38
|
+
setPartnerA: (image: unknown) => void;
|
|
39
|
+
setPartnerAName: (name: string) => void;
|
|
40
|
+
setPartnerB: (image: unknown) => void;
|
|
41
|
+
setPartnerBName: (name: string) => void;
|
|
42
|
+
setCustomPrompt: (prompt: string) => void;
|
|
43
|
+
setVisualStyle: (style: string) => void;
|
|
44
|
+
startGeneration: () => void;
|
|
45
|
+
generationSuccess: (result: TResult) => void;
|
|
46
|
+
generationError: (error: string) => void;
|
|
47
|
+
requireFeature: (callback: () => void) => void;
|
|
48
|
+
onNavigateToHistory: () => void;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface CoupleFutureFlowProps<TStep, TScenarioId, TResult> {
|
|
52
|
+
userId?: string;
|
|
53
|
+
config: CoupleFutureFlowConfig<TStep, TScenarioId>;
|
|
54
|
+
state: CoupleFutureFlowState<TStep, TScenarioId>;
|
|
55
|
+
actions: CoupleFutureFlowActions<TStep, TScenarioId, TResult>;
|
|
56
|
+
generationConfig: {
|
|
57
|
+
visualStyleModifiers: Record<string, string>;
|
|
58
|
+
defaultPartnerAName: string;
|
|
59
|
+
defaultPartnerBName: string;
|
|
60
|
+
};
|
|
61
|
+
alertMessages: {
|
|
62
|
+
networkError: string;
|
|
63
|
+
policyViolation: string;
|
|
64
|
+
saveFailed: string;
|
|
65
|
+
creditFailed: string;
|
|
66
|
+
unknown: string;
|
|
67
|
+
};
|
|
68
|
+
processResult: (imageUrl: string, input: unknown) => TResult;
|
|
69
|
+
buildCreation: (result: TResult, input: unknown) => unknown;
|
|
70
|
+
onCreditsExhausted: () => void;
|
|
71
|
+
}
|
|
@@ -8,73 +8,21 @@ import { InteractionManager } from "react-native";
|
|
|
8
8
|
import { useCoupleFutureGeneration } from "./useCoupleFutureGeneration";
|
|
9
9
|
import { buildGenerationInputFromConfig } from "../../infrastructure/generationUtils";
|
|
10
10
|
import type { UploadedImage } from "../../../partner-upload/domain/types";
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
step: TStep;
|
|
27
|
-
selectedScenarioId: TScenarioId | null;
|
|
28
|
-
selectedFeature: string | null;
|
|
29
|
-
partnerA: unknown;
|
|
30
|
-
partnerB: unknown;
|
|
31
|
-
partnerAName: string;
|
|
32
|
-
partnerBName: string;
|
|
33
|
-
customPrompt: string | null;
|
|
34
|
-
visualStyle: string | null;
|
|
35
|
-
selection: unknown;
|
|
36
|
-
isProcessing: boolean;
|
|
37
|
-
scenarioConfig: unknown;
|
|
38
|
-
selectedScenarioData: { requiresPhoto?: boolean } | null;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export interface CoupleFutureFlowActions<TStep, TScenarioId, TResult> {
|
|
42
|
-
setStep: (step: TStep) => void;
|
|
43
|
-
selectScenario: (id: TScenarioId) => void;
|
|
44
|
-
setPartnerA: (image: unknown) => void;
|
|
45
|
-
setPartnerAName: (name: string) => void;
|
|
46
|
-
setPartnerB: (image: unknown) => void;
|
|
47
|
-
setPartnerBName: (name: string) => void;
|
|
48
|
-
setCustomPrompt: (prompt: string) => void;
|
|
49
|
-
setVisualStyle: (style: string) => void;
|
|
50
|
-
startGeneration: () => void;
|
|
51
|
-
generationSuccess: (result: TResult) => void;
|
|
52
|
-
generationError: (error: string) => void;
|
|
53
|
-
requireFeature: (callback: () => void) => void;
|
|
54
|
-
onNavigateToHistory: () => void;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export interface CoupleFutureFlowProps<TStep, TScenarioId, TResult> {
|
|
58
|
-
userId?: string;
|
|
59
|
-
config: CoupleFutureFlowConfig<TStep, TScenarioId>;
|
|
60
|
-
state: CoupleFutureFlowState<TStep, TScenarioId>;
|
|
61
|
-
actions: CoupleFutureFlowActions<TStep, TScenarioId, TResult>;
|
|
62
|
-
generationConfig: {
|
|
63
|
-
visualStyleModifiers: Record<string, string>;
|
|
64
|
-
defaultPartnerAName: string;
|
|
65
|
-
defaultPartnerBName: string;
|
|
66
|
-
};
|
|
67
|
-
alertMessages: {
|
|
68
|
-
networkError: string;
|
|
69
|
-
policyViolation: string;
|
|
70
|
-
saveFailed: string;
|
|
71
|
-
creditFailed: string;
|
|
72
|
-
unknown: string;
|
|
73
|
-
};
|
|
74
|
-
processResult: (imageUrl: string, input: unknown) => TResult;
|
|
75
|
-
buildCreation: (result: TResult, input: unknown) => unknown;
|
|
76
|
-
onCreditsExhausted: () => void;
|
|
77
|
-
}
|
|
11
|
+
import type {
|
|
12
|
+
CoupleFutureFlowConfig,
|
|
13
|
+
CoupleFutureFlowState,
|
|
14
|
+
CoupleFutureFlowActions,
|
|
15
|
+
CoupleFutureFlowProps,
|
|
16
|
+
} from "./coupleFutureFlow.types";
|
|
17
|
+
|
|
18
|
+
declare const __DEV__: boolean;
|
|
19
|
+
|
|
20
|
+
export type {
|
|
21
|
+
CoupleFutureFlowConfig,
|
|
22
|
+
CoupleFutureFlowState,
|
|
23
|
+
CoupleFutureFlowActions,
|
|
24
|
+
CoupleFutureFlowProps,
|
|
25
|
+
};
|
|
78
26
|
|
|
79
27
|
export const useCoupleFutureFlow = <TStep, TScenarioId, TResult>(
|
|
80
28
|
props: CoupleFutureFlowProps<TStep, TScenarioId, TResult>,
|
|
@@ -83,82 +31,110 @@ export const useCoupleFutureFlow = <TStep, TScenarioId, TResult>(
|
|
|
83
31
|
const { processResult, buildCreation, onCreditsExhausted, userId } = props;
|
|
84
32
|
const hasStarted = useRef(false);
|
|
85
33
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
onCreditsExhausted,
|
|
90
|
-
onSuccess: (result) => {
|
|
91
|
-
actions.generationSuccess(result);
|
|
92
|
-
InteractionManager.runAfterInteractions(() => {
|
|
93
|
-
setTimeout(() => actions.onNavigateToHistory(), 300);
|
|
94
|
-
});
|
|
95
|
-
},
|
|
96
|
-
onError: actions.generationError,
|
|
97
|
-
processResult: processResult as never,
|
|
98
|
-
buildCreation: buildCreation as never,
|
|
99
|
-
alertMessages,
|
|
100
|
-
});
|
|
34
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
35
|
+
console.log("[CoupleFutureFlow] Hook initialized:", { userId, step: state.step });
|
|
36
|
+
}
|
|
101
37
|
|
|
102
|
-
const {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
38
|
+
const { generate, isGenerating, progress } = useCoupleFutureGeneration<TResult>({
|
|
39
|
+
userId,
|
|
40
|
+
onCreditsExhausted,
|
|
41
|
+
onSuccess: (result) => {
|
|
42
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
43
|
+
console.log("[CoupleFutureFlow] 🎉 onSuccess callback triggered");
|
|
44
|
+
}
|
|
45
|
+
actions.generationSuccess(result);
|
|
46
|
+
InteractionManager.runAfterInteractions(() => {
|
|
47
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
48
|
+
console.log("[CoupleFutureFlow] 🔄 Navigating to History in 300ms...");
|
|
49
|
+
}
|
|
50
|
+
setTimeout(() => actions.onNavigateToHistory(), 300);
|
|
51
|
+
});
|
|
52
|
+
},
|
|
53
|
+
onError: (error) => {
|
|
54
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
55
|
+
console.log("[CoupleFutureFlow] ❌ onError callback:", error);
|
|
56
|
+
}
|
|
57
|
+
actions.generationError(error);
|
|
58
|
+
},
|
|
59
|
+
processResult: processResult as never,
|
|
60
|
+
buildCreation: buildCreation as never,
|
|
61
|
+
alertMessages,
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const { step, isProcessing, selectedFeature, selectedScenarioId, selectedScenarioData } = state;
|
|
117
65
|
|
|
118
66
|
useEffect(() => {
|
|
67
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
68
|
+
console.log("[CoupleFutureFlow] useEffect triggered:", {
|
|
69
|
+
step,
|
|
70
|
+
isProcessing,
|
|
71
|
+
hasStarted: hasStarted.current,
|
|
72
|
+
targetStep: config.steps.GENERATING,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
119
76
|
if (step !== config.steps.GENERATING) {
|
|
120
77
|
hasStarted.current = false;
|
|
121
78
|
return;
|
|
122
79
|
}
|
|
123
|
-
if (!isProcessing || hasStarted.current)
|
|
80
|
+
if (!isProcessing || hasStarted.current) {
|
|
81
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
82
|
+
console.log("[CoupleFutureFlow] ⚠️ Skipping generation:", {
|
|
83
|
+
reason: !isProcessing ? "isProcessing=false" : "already started",
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
124
88
|
hasStarted.current = true;
|
|
125
89
|
|
|
90
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
91
|
+
console.log("[CoupleFutureFlow] 🚀 Building generation input...");
|
|
92
|
+
console.log("[CoupleFutureFlow] State:", {
|
|
93
|
+
hasPartnerA: !!state.partnerA,
|
|
94
|
+
hasPartnerB: !!state.partnerB,
|
|
95
|
+
partnerAName: state.partnerAName,
|
|
96
|
+
partnerBName: state.partnerBName,
|
|
97
|
+
hasScenarioConfig: !!state.scenarioConfig,
|
|
98
|
+
customPrompt: state.customPrompt?.slice(0, 100),
|
|
99
|
+
visualStyle: state.visualStyle,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
126
103
|
const input = buildGenerationInputFromConfig({
|
|
127
|
-
partnerA: partnerA as never,
|
|
128
|
-
partnerB: partnerB as never,
|
|
129
|
-
partnerAName,
|
|
130
|
-
partnerBName,
|
|
131
|
-
scenario: scenarioConfig as never,
|
|
132
|
-
customPrompt: customPrompt || undefined,
|
|
133
|
-
visualStyle: visualStyle || "",
|
|
104
|
+
partnerA: state.partnerA as never,
|
|
105
|
+
partnerB: state.partnerB as never,
|
|
106
|
+
partnerAName: state.partnerAName,
|
|
107
|
+
partnerBName: state.partnerBName,
|
|
108
|
+
scenario: state.scenarioConfig as never,
|
|
109
|
+
customPrompt: state.customPrompt || undefined,
|
|
110
|
+
visualStyle: state.visualStyle || "",
|
|
134
111
|
defaultPartnerAName: generationConfig.defaultPartnerAName,
|
|
135
112
|
defaultPartnerBName: generationConfig.defaultPartnerBName,
|
|
136
|
-
coupleFeatureSelection: selection as never,
|
|
113
|
+
coupleFeatureSelection: state.selection as never,
|
|
137
114
|
visualStyles: generationConfig.visualStyleModifiers,
|
|
138
115
|
customScenarioId: config.customScenarioId as string,
|
|
139
116
|
});
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
generationConfig.defaultPartnerBName,
|
|
156
|
-
generationConfig.visualStyleModifiers,
|
|
157
|
-
generate,
|
|
158
|
-
]);
|
|
117
|
+
|
|
118
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
119
|
+
console.log("[CoupleFutureFlow] 📦 Generation input built:", {
|
|
120
|
+
hasInput: !!input,
|
|
121
|
+
prompt: input?.prompt?.slice(0, 200),
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (input) {
|
|
126
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
127
|
+
console.log("[CoupleFutureFlow] 🚀 Calling generate()...");
|
|
128
|
+
}
|
|
129
|
+
generate(input);
|
|
130
|
+
}
|
|
131
|
+
}, [step, isProcessing, state, config, generationConfig, generate]);
|
|
159
132
|
|
|
160
133
|
const handleScenarioSelect = useCallback(
|
|
161
134
|
(id: string) => {
|
|
135
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
136
|
+
console.log("[CoupleFutureFlow] handleScenarioSelect:", id);
|
|
137
|
+
}
|
|
162
138
|
actions.selectScenario(id as TScenarioId);
|
|
163
139
|
actions.setStep(config.steps.SCENARIO_PREVIEW);
|
|
164
140
|
},
|
|
@@ -181,19 +157,13 @@ export const useCoupleFutureFlow = <TStep, TScenarioId, TResult>(
|
|
|
181
157
|
} else {
|
|
182
158
|
actions.setStep(config.steps.PARTNER_A);
|
|
183
159
|
}
|
|
184
|
-
}, [
|
|
185
|
-
actions,
|
|
186
|
-
config.steps.COUPLE_FEATURE_SELECTOR,
|
|
187
|
-
config.steps.TEXT_INPUT,
|
|
188
|
-
config.steps.PARTNER_A,
|
|
189
|
-
config.customScenarioId,
|
|
190
|
-
selectedFeature,
|
|
191
|
-
selectedScenarioId,
|
|
192
|
-
selectedScenarioData,
|
|
193
|
-
]);
|
|
160
|
+
}, [actions, config, selectedFeature, selectedScenarioId, selectedScenarioData]);
|
|
194
161
|
|
|
195
162
|
const handlePartnerAContinue = useCallback(
|
|
196
163
|
(image: UploadedImage, name: string) => {
|
|
164
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
165
|
+
console.log("[CoupleFutureFlow] handlePartnerAContinue:", { hasImage: !!image, name });
|
|
166
|
+
}
|
|
197
167
|
actions.setPartnerA(image);
|
|
198
168
|
actions.setPartnerAName(name);
|
|
199
169
|
actions.setStep(config.steps.PARTNER_B);
|
|
@@ -202,22 +172,23 @@ export const useCoupleFutureFlow = <TStep, TScenarioId, TResult>(
|
|
|
202
172
|
);
|
|
203
173
|
|
|
204
174
|
const handlePartnerABack = useCallback(() => {
|
|
205
|
-
|
|
175
|
+
const targetStep =
|
|
206
176
|
selectedScenarioId === config.customScenarioId
|
|
207
177
|
? config.steps.TEXT_INPUT
|
|
208
|
-
: config.steps.SCENARIO_PREVIEW
|
|
209
|
-
);
|
|
210
|
-
}, [
|
|
211
|
-
actions,
|
|
212
|
-
config.customScenarioId,
|
|
213
|
-
config.steps.TEXT_INPUT,
|
|
214
|
-
config.steps.SCENARIO_PREVIEW,
|
|
215
|
-
selectedScenarioId,
|
|
216
|
-
]);
|
|
178
|
+
: config.steps.SCENARIO_PREVIEW;
|
|
179
|
+
actions.setStep(targetStep);
|
|
180
|
+
}, [actions, config, selectedScenarioId]);
|
|
217
181
|
|
|
218
182
|
const handlePartnerBContinue = useCallback(
|
|
219
183
|
(image: UploadedImage, name: string) => {
|
|
184
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
185
|
+
console.log("[CoupleFutureFlow] handlePartnerBContinue:", { hasImage: !!image, name });
|
|
186
|
+
console.log("[CoupleFutureFlow] Calling requireFeature()...");
|
|
187
|
+
}
|
|
220
188
|
actions.requireFeature(() => {
|
|
189
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
190
|
+
console.log("[CoupleFutureFlow] 🔓 Feature gate passed, starting generation");
|
|
191
|
+
}
|
|
221
192
|
actions.setPartnerB(image);
|
|
222
193
|
actions.setPartnerBName(name);
|
|
223
194
|
actions.startGeneration();
|
|
@@ -233,6 +204,12 @@ export const useCoupleFutureFlow = <TStep, TScenarioId, TResult>(
|
|
|
233
204
|
|
|
234
205
|
const handleMagicPromptContinue = useCallback(
|
|
235
206
|
(prompt: string, style: string) => {
|
|
207
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
208
|
+
console.log("[CoupleFutureFlow] handleMagicPromptContinue:", {
|
|
209
|
+
promptLength: prompt.length,
|
|
210
|
+
style,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
236
213
|
actions.setCustomPrompt(prompt);
|
|
237
214
|
actions.setVisualStyle(style);
|
|
238
215
|
if (selectedScenarioId === config.customScenarioId) {
|
|
@@ -241,7 +218,7 @@ export const useCoupleFutureFlow = <TStep, TScenarioId, TResult>(
|
|
|
241
218
|
actions.startGeneration();
|
|
242
219
|
}
|
|
243
220
|
},
|
|
244
|
-
[actions, config
|
|
221
|
+
[actions, config, selectedScenarioId],
|
|
245
222
|
);
|
|
246
223
|
|
|
247
224
|
const handleMagicPromptBack = useCallback(
|
|
@@ -14,6 +14,8 @@ import type { CoupleFutureInput } from "../../domain/types";
|
|
|
14
14
|
import { createCreationsRepository } from "../../../../domains/creations/infrastructure/adapters";
|
|
15
15
|
import type { Creation } from "../../../../domains/creations/domain/entities/Creation";
|
|
16
16
|
|
|
17
|
+
declare const __DEV__: boolean;
|
|
18
|
+
|
|
17
19
|
export interface CoupleFutureConfig<TResult> {
|
|
18
20
|
userId: string | undefined;
|
|
19
21
|
processResult: (imageUrl: string, input: CoupleFutureInput) => TResult;
|
|
@@ -24,33 +26,36 @@ export interface CoupleFutureConfig<TResult> {
|
|
|
24
26
|
alertMessages: AlertMessages;
|
|
25
27
|
}
|
|
26
28
|
|
|
27
|
-
export const useCoupleFutureGeneration = <TResult>(
|
|
28
|
-
config
|
|
29
|
-
) => {
|
|
30
|
-
const {
|
|
31
|
-
userId,
|
|
32
|
-
processResult,
|
|
33
|
-
buildCreation,
|
|
34
|
-
onCreditsExhausted,
|
|
35
|
-
onSuccess,
|
|
36
|
-
onError,
|
|
37
|
-
alertMessages,
|
|
38
|
-
} = config;
|
|
29
|
+
export const useCoupleFutureGeneration = <TResult>(config: CoupleFutureConfig<TResult>) => {
|
|
30
|
+
const { userId, processResult, buildCreation, onCreditsExhausted, onSuccess, onError, alertMessages } = config;
|
|
39
31
|
|
|
40
|
-
|
|
41
|
-
(
|
|
42
|
-
|
|
43
|
-
|
|
32
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
33
|
+
console.log("[CoupleFutureGeneration] Hook initialized:", {
|
|
34
|
+
userId,
|
|
35
|
+
hasBuildCreation: !!buildCreation,
|
|
36
|
+
hasOnSuccess: !!onSuccess,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
44
39
|
|
|
45
|
-
|
|
40
|
+
const repository = useMemo(() => createCreationsRepository("creations"), []);
|
|
46
41
|
const lastInputRef = useRef<CoupleFutureInput | null>(null);
|
|
47
42
|
|
|
48
43
|
const strategy: GenerationStrategy<CoupleFutureInput, TResult> = useMemo(
|
|
49
44
|
() => ({
|
|
50
45
|
execute: async (input, onProgress) => {
|
|
51
|
-
|
|
46
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
47
|
+
console.log("[CoupleFutureGeneration] 🎯 strategy.execute() START");
|
|
48
|
+
console.log("[CoupleFutureGeneration] Input prompt:", input.prompt?.slice(0, 200));
|
|
49
|
+
console.log("[CoupleFutureGeneration] Has partnerA:", !!input.partnerABase64);
|
|
50
|
+
console.log("[CoupleFutureGeneration] Has partnerB:", !!input.partnerBBase64);
|
|
51
|
+
}
|
|
52
|
+
|
|
52
53
|
lastInputRef.current = input;
|
|
53
54
|
|
|
55
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
56
|
+
console.log("[CoupleFutureGeneration] 📡 Calling executeCoupleFuture()...");
|
|
57
|
+
}
|
|
58
|
+
|
|
54
59
|
const result = await executeCoupleFuture(
|
|
55
60
|
{
|
|
56
61
|
partnerABase64: input.partnerABase64,
|
|
@@ -60,20 +65,44 @@ export const useCoupleFutureGeneration = <TResult>(
|
|
|
60
65
|
{ onProgress },
|
|
61
66
|
);
|
|
62
67
|
|
|
68
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
69
|
+
console.log("[CoupleFutureGeneration] 📡 executeCoupleFuture() returned:", {
|
|
70
|
+
success: result.success,
|
|
71
|
+
hasImageUrl: !!result.imageUrl,
|
|
72
|
+
error: result.error,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
63
76
|
if (!result.success || !result.imageUrl) {
|
|
77
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
78
|
+
console.log("[CoupleFutureGeneration] ❌ Generation failed:", result.error);
|
|
79
|
+
}
|
|
64
80
|
throw new Error(result.error || "Generation failed");
|
|
65
81
|
}
|
|
66
82
|
|
|
83
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
84
|
+
console.log("[CoupleFutureGeneration] ✅ Processing result with processResult()");
|
|
85
|
+
}
|
|
86
|
+
|
|
67
87
|
return processResult(result.imageUrl, input);
|
|
68
88
|
},
|
|
69
89
|
getCreditCost: () => 1,
|
|
70
90
|
save: buildCreation
|
|
71
91
|
? async (result, uid) => {
|
|
92
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
93
|
+
console.log("[CoupleFutureGeneration] 💾 strategy.save() START");
|
|
94
|
+
}
|
|
72
95
|
const input = lastInputRef.current;
|
|
73
96
|
if (input) {
|
|
74
97
|
const creation = buildCreation(result, input);
|
|
75
98
|
if (creation) {
|
|
99
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
100
|
+
console.log("[CoupleFutureGeneration] 💾 Saving creation to repository...");
|
|
101
|
+
}
|
|
76
102
|
await repository.create(uid, creation);
|
|
103
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
104
|
+
console.log("[CoupleFutureGeneration] ✅ Creation saved");
|
|
105
|
+
}
|
|
77
106
|
}
|
|
78
107
|
}
|
|
79
108
|
}
|
|
@@ -84,16 +113,29 @@ export const useCoupleFutureGeneration = <TResult>(
|
|
|
84
113
|
|
|
85
114
|
const handleError = useCallback(
|
|
86
115
|
(error: { message: string }) => {
|
|
116
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
117
|
+
console.log("[CoupleFutureGeneration] ❌ handleError:", error.message);
|
|
118
|
+
}
|
|
87
119
|
onError?.(error.message);
|
|
88
120
|
},
|
|
89
121
|
[onError],
|
|
90
122
|
);
|
|
91
123
|
|
|
124
|
+
const handleSuccess = useCallback(
|
|
125
|
+
(result: unknown) => {
|
|
126
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
127
|
+
console.log("[CoupleFutureGeneration] 🎉 handleSuccess called");
|
|
128
|
+
}
|
|
129
|
+
onSuccess?.(result as TResult);
|
|
130
|
+
},
|
|
131
|
+
[onSuccess],
|
|
132
|
+
);
|
|
133
|
+
|
|
92
134
|
return useGenerationOrchestrator(strategy, {
|
|
93
135
|
userId,
|
|
94
136
|
alertMessages,
|
|
95
137
|
onCreditsExhausted,
|
|
96
|
-
onSuccess:
|
|
138
|
+
onSuccess: handleSuccess,
|
|
97
139
|
onError: handleError,
|
|
98
140
|
});
|
|
99
141
|
};
|
|
@@ -18,6 +18,8 @@ import type {
|
|
|
18
18
|
UseGenerationOrchestratorReturn,
|
|
19
19
|
} from "./types";
|
|
20
20
|
|
|
21
|
+
declare const __DEV__: boolean;
|
|
22
|
+
|
|
21
23
|
const INITIAL_STATE = {
|
|
22
24
|
status: "idle" as const,
|
|
23
25
|
isGenerating: false,
|
|
@@ -30,53 +32,109 @@ export const useGenerationOrchestrator = <TInput, TResult>(
|
|
|
30
32
|
strategy: GenerationStrategy<TInput, TResult>,
|
|
31
33
|
config: GenerationConfig,
|
|
32
34
|
): UseGenerationOrchestratorReturn<TInput, TResult> => {
|
|
33
|
-
const { userId, alertMessages, onCreditsExhausted, onSuccess, onError } =
|
|
34
|
-
|
|
35
|
+
const { userId, alertMessages, onCreditsExhausted, onSuccess, onError } = config;
|
|
36
|
+
|
|
37
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
38
|
+
console.log("[Orchestrator] Hook initialized:", { userId, hasAlertMessages: !!alertMessages });
|
|
39
|
+
}
|
|
35
40
|
|
|
36
41
|
const [state, setState] = useState<GenerationState<TResult>>(INITIAL_STATE);
|
|
37
42
|
const isGeneratingRef = useRef(false);
|
|
38
43
|
const offlineStore = useOfflineStore();
|
|
39
44
|
const { showError, showSuccess } = useAlert();
|
|
40
|
-
const { checkCredits, deductCredit } = useDeductCredit({
|
|
41
|
-
userId,
|
|
42
|
-
onCreditsExhausted,
|
|
43
|
-
});
|
|
45
|
+
const { checkCredits, deductCredit } = useDeductCredit({ userId, onCreditsExhausted });
|
|
44
46
|
|
|
45
47
|
const generate = useCallback(
|
|
46
48
|
async (input: TInput) => {
|
|
47
|
-
if (
|
|
49
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
50
|
+
console.log("[Orchestrator] 🚀 generate() called");
|
|
51
|
+
console.log("[Orchestrator] Input:", JSON.stringify(input, null, 2).slice(0, 500));
|
|
52
|
+
console.log("[Orchestrator] isGeneratingRef:", isGeneratingRef.current);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (isGeneratingRef.current) {
|
|
56
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
57
|
+
console.log("[Orchestrator] ⚠️ Already generating, skipping");
|
|
58
|
+
}
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
48
61
|
|
|
49
62
|
isGeneratingRef.current = true;
|
|
50
63
|
setState({ ...INITIAL_STATE, status: "checking", isGenerating: true });
|
|
51
64
|
|
|
65
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
66
|
+
console.log("[Orchestrator] State set to: checking, isGenerating: true");
|
|
67
|
+
}
|
|
68
|
+
|
|
52
69
|
try {
|
|
70
|
+
// Network check
|
|
53
71
|
if (!offlineStore.isOnline) {
|
|
72
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
73
|
+
console.log("[Orchestrator] ❌ Network check failed - offline");
|
|
74
|
+
}
|
|
54
75
|
throw createGenerationError("network", "No internet connection");
|
|
55
76
|
}
|
|
56
77
|
|
|
78
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
79
|
+
console.log("[Orchestrator] ✅ Network check passed");
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Credit check
|
|
57
83
|
const creditCost = strategy.getCreditCost();
|
|
84
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
85
|
+
console.log("[Orchestrator] 💳 Credit cost:", creditCost);
|
|
86
|
+
}
|
|
87
|
+
|
|
58
88
|
const hasCredits = await checkCredits(creditCost);
|
|
89
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
90
|
+
console.log("[Orchestrator] 💳 Has credits:", hasCredits);
|
|
91
|
+
}
|
|
92
|
+
|
|
59
93
|
if (!hasCredits) {
|
|
60
|
-
|
|
94
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
95
|
+
console.log("[Orchestrator] ❌ No credits, opening paywall");
|
|
96
|
+
}
|
|
61
97
|
isGeneratingRef.current = false;
|
|
62
98
|
setState(INITIAL_STATE);
|
|
63
99
|
onCreditsExhausted?.();
|
|
64
100
|
return;
|
|
65
101
|
}
|
|
66
102
|
|
|
103
|
+
// Start generation
|
|
67
104
|
setState((prev) => ({ ...prev, status: "generating", progress: 10 }));
|
|
105
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
106
|
+
console.log("[Orchestrator] 🎨 Starting strategy.execute()");
|
|
107
|
+
}
|
|
68
108
|
|
|
69
109
|
const result = await strategy.execute(input, (progress) => {
|
|
110
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
111
|
+
console.log("[Orchestrator] 📊 Progress update:", progress);
|
|
112
|
+
}
|
|
70
113
|
setState((prev) => ({ ...prev, progress }));
|
|
71
114
|
});
|
|
72
115
|
|
|
116
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
117
|
+
console.log("[Orchestrator] ✅ strategy.execute() completed");
|
|
118
|
+
console.log("[Orchestrator] Result type:", typeof result);
|
|
119
|
+
}
|
|
120
|
+
|
|
73
121
|
setState((prev) => ({ ...prev, progress: 70 }));
|
|
74
122
|
|
|
123
|
+
// Save result
|
|
75
124
|
if (strategy.save && userId) {
|
|
76
125
|
setState((prev) => ({ ...prev, status: "saving" }));
|
|
126
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
127
|
+
console.log("[Orchestrator] 💾 Saving result...");
|
|
128
|
+
}
|
|
77
129
|
try {
|
|
78
130
|
await strategy.save(result, userId);
|
|
131
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
132
|
+
console.log("[Orchestrator] ✅ Save completed");
|
|
133
|
+
}
|
|
79
134
|
} catch (saveErr) {
|
|
135
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
136
|
+
console.log("[Orchestrator] ❌ Save failed:", saveErr);
|
|
137
|
+
}
|
|
80
138
|
throw createGenerationError(
|
|
81
139
|
"save",
|
|
82
140
|
"Failed to save",
|
|
@@ -87,8 +145,13 @@ export const useGenerationOrchestrator = <TInput, TResult>(
|
|
|
87
145
|
|
|
88
146
|
setState((prev) => ({ ...prev, progress: 90 }));
|
|
89
147
|
|
|
148
|
+
// Deduct credit
|
|
149
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
150
|
+
console.log("[Orchestrator] 💳 Deducting credit:", creditCost);
|
|
151
|
+
}
|
|
90
152
|
await deductCredit(creditCost);
|
|
91
153
|
|
|
154
|
+
// Success
|
|
92
155
|
setState({
|
|
93
156
|
status: "success",
|
|
94
157
|
isGenerating: false,
|
|
@@ -97,6 +160,10 @@ export const useGenerationOrchestrator = <TInput, TResult>(
|
|
|
97
160
|
error: null,
|
|
98
161
|
});
|
|
99
162
|
|
|
163
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
164
|
+
console.log("[Orchestrator] 🎉 Generation SUCCESS");
|
|
165
|
+
}
|
|
166
|
+
|
|
100
167
|
if (alertMessages.success) {
|
|
101
168
|
void showSuccess("Success", alertMessages.success);
|
|
102
169
|
}
|
|
@@ -105,6 +172,10 @@ export const useGenerationOrchestrator = <TInput, TResult>(
|
|
|
105
172
|
} catch (err) {
|
|
106
173
|
const error = parseError(err);
|
|
107
174
|
|
|
175
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
176
|
+
console.log("[Orchestrator] ❌ Generation ERROR:", error);
|
|
177
|
+
}
|
|
178
|
+
|
|
108
179
|
setState({
|
|
109
180
|
status: "error",
|
|
110
181
|
isGenerating: false,
|
|
@@ -117,6 +188,9 @@ export const useGenerationOrchestrator = <TInput, TResult>(
|
|
|
117
188
|
onError?.(error);
|
|
118
189
|
} finally {
|
|
119
190
|
isGeneratingRef.current = false;
|
|
191
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
192
|
+
console.log("[Orchestrator] 🏁 generate() finished, isGeneratingRef reset to false");
|
|
193
|
+
}
|
|
120
194
|
}
|
|
121
195
|
},
|
|
122
196
|
[
|
|
@@ -134,6 +208,9 @@ export const useGenerationOrchestrator = <TInput, TResult>(
|
|
|
134
208
|
);
|
|
135
209
|
|
|
136
210
|
const reset = useCallback(() => {
|
|
211
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
212
|
+
console.log("[Orchestrator] 🔄 reset() called");
|
|
213
|
+
}
|
|
137
214
|
setState(INITIAL_STATE);
|
|
138
215
|
isGeneratingRef.current = false;
|
|
139
216
|
}, []);
|