@umituz/react-native-ai-generation-content 1.0.6 → 1.2.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.
- package/package.json +1 -1
- package/src/infrastructure/services/generation-orchestrator.service.ts +77 -2
- package/src/infrastructure/services/provider-registry.service.ts +24 -1
- package/src/infrastructure/utils/error-classifier.util.ts +36 -14
- package/src/infrastructure/utils/result-validator.util.ts +15 -1
package/package.json
CHANGED
|
@@ -30,6 +30,13 @@ class GenerationOrchestratorService {
|
|
|
30
30
|
private config: OrchestratorConfig = {};
|
|
31
31
|
|
|
32
32
|
configure(config: OrchestratorConfig): void {
|
|
33
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
34
|
+
// eslint-disable-next-line no-console
|
|
35
|
+
console.log("[Orchestrator] configure() called", {
|
|
36
|
+
hasPollingConfig: !!config.polling,
|
|
37
|
+
hasStatusUpdate: !!config.onStatusUpdate,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
33
40
|
this.config = { ...this.config, ...config };
|
|
34
41
|
}
|
|
35
42
|
|
|
@@ -40,6 +47,15 @@ class GenerationOrchestratorService {
|
|
|
40
47
|
const progressTracker = createProgressTracker();
|
|
41
48
|
const startTime = Date.now();
|
|
42
49
|
|
|
50
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
51
|
+
// eslint-disable-next-line no-console
|
|
52
|
+
console.log("[Orchestrator] Generate started:", {
|
|
53
|
+
model: request.model,
|
|
54
|
+
capability: request.capability,
|
|
55
|
+
provider: provider.providerId,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
43
59
|
const updateProgress = (
|
|
44
60
|
stage: GenerationProgress["stage"],
|
|
45
61
|
subProgress = 0,
|
|
@@ -60,7 +76,10 @@ class GenerationOrchestratorService {
|
|
|
60
76
|
|
|
61
77
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
62
78
|
// eslint-disable-next-line no-console
|
|
63
|
-
console.log("[Orchestrator] Job submitted:",
|
|
79
|
+
console.log("[Orchestrator] Job submitted:", {
|
|
80
|
+
requestId: submission.requestId,
|
|
81
|
+
provider: provider.providerId,
|
|
82
|
+
});
|
|
64
83
|
}
|
|
65
84
|
|
|
66
85
|
updateProgress("generating");
|
|
@@ -74,6 +93,17 @@ class GenerationOrchestratorService {
|
|
|
74
93
|
|
|
75
94
|
updateProgress("completed");
|
|
76
95
|
|
|
96
|
+
const duration = Date.now() - startTime;
|
|
97
|
+
|
|
98
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
99
|
+
// eslint-disable-next-line no-console
|
|
100
|
+
console.log("[Orchestrator] Generate completed:", {
|
|
101
|
+
requestId: submission.requestId,
|
|
102
|
+
duration: `${duration}ms`,
|
|
103
|
+
success: true,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
77
107
|
return {
|
|
78
108
|
success: true,
|
|
79
109
|
data: result,
|
|
@@ -84,7 +114,7 @@ class GenerationOrchestratorService {
|
|
|
84
114
|
capability: request.capability,
|
|
85
115
|
startTime,
|
|
86
116
|
endTime: Date.now(),
|
|
87
|
-
duration
|
|
117
|
+
duration,
|
|
88
118
|
},
|
|
89
119
|
};
|
|
90
120
|
} catch (error) {
|
|
@@ -116,6 +146,15 @@ class GenerationOrchestratorService {
|
|
|
116
146
|
requestId: string,
|
|
117
147
|
onProgress?: (progress: GenerationProgress) => void,
|
|
118
148
|
): Promise<T> {
|
|
149
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
150
|
+
// eslint-disable-next-line no-console
|
|
151
|
+
console.log("[Orchestrator] pollForResult() started", {
|
|
152
|
+
provider: provider.providerId,
|
|
153
|
+
model,
|
|
154
|
+
requestId,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
119
158
|
const config = {
|
|
120
159
|
...DEFAULT_POLLING_CONFIG,
|
|
121
160
|
...this.config.polling,
|
|
@@ -126,6 +165,14 @@ class GenerationOrchestratorService {
|
|
|
126
165
|
for (let attempt = 0; attempt < config.maxAttempts; attempt++) {
|
|
127
166
|
await createPollingDelay(attempt, config);
|
|
128
167
|
|
|
168
|
+
if (typeof __DEV__ !== "undefined" && __DEV__ && attempt % 5 === 0) {
|
|
169
|
+
// eslint-disable-next-line no-console
|
|
170
|
+
console.log("[Orchestrator] pollForResult() attempt", {
|
|
171
|
+
attempt,
|
|
172
|
+
maxAttempts: config.maxAttempts,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
129
176
|
try {
|
|
130
177
|
const status = await provider.getJobStatus(model, requestId);
|
|
131
178
|
|
|
@@ -134,6 +181,13 @@ class GenerationOrchestratorService {
|
|
|
134
181
|
this.updateProgressFromStatus(status, attempt, config, onProgress);
|
|
135
182
|
|
|
136
183
|
if (status.status === "COMPLETED") {
|
|
184
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
185
|
+
// eslint-disable-next-line no-console
|
|
186
|
+
console.log("[Orchestrator] pollForResult() job COMPLETED", {
|
|
187
|
+
requestId,
|
|
188
|
+
attempt,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
137
191
|
return provider.getJobResult<T>(model, requestId);
|
|
138
192
|
}
|
|
139
193
|
|
|
@@ -191,20 +245,41 @@ class GenerationOrchestratorService {
|
|
|
191
245
|
}
|
|
192
246
|
|
|
193
247
|
private getProvider(): IAIProvider {
|
|
248
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
249
|
+
// eslint-disable-next-line no-console
|
|
250
|
+
console.log("[Orchestrator] getProvider() called");
|
|
251
|
+
}
|
|
252
|
+
|
|
194
253
|
const provider = providerRegistry.getActiveProvider();
|
|
195
254
|
|
|
196
255
|
if (!provider) {
|
|
256
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
257
|
+
// eslint-disable-next-line no-console
|
|
258
|
+
console.error("[Orchestrator] No active provider found!");
|
|
259
|
+
}
|
|
197
260
|
throw new Error(
|
|
198
261
|
"No active AI provider. Register and set a provider first.",
|
|
199
262
|
);
|
|
200
263
|
}
|
|
201
264
|
|
|
202
265
|
if (!provider.isInitialized()) {
|
|
266
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
267
|
+
// eslint-disable-next-line no-console
|
|
268
|
+
console.error("[Orchestrator] Provider not initialized:", provider.providerId);
|
|
269
|
+
}
|
|
203
270
|
throw new Error(
|
|
204
271
|
`Provider ${provider.providerId} is not initialized.`,
|
|
205
272
|
);
|
|
206
273
|
}
|
|
207
274
|
|
|
275
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
276
|
+
// eslint-disable-next-line no-console
|
|
277
|
+
console.log("[Orchestrator] getProvider() returning:", {
|
|
278
|
+
providerId: provider.providerId,
|
|
279
|
+
isInitialized: provider.isInitialized(),
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
|
|
208
283
|
return provider;
|
|
209
284
|
}
|
|
210
285
|
}
|
|
@@ -52,10 +52,33 @@ class ProviderRegistry {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
getActiveProvider(): IAIProvider | null {
|
|
55
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
56
|
+
// eslint-disable-next-line no-console
|
|
57
|
+
console.log("[ProviderRegistry] getActiveProvider() called", {
|
|
58
|
+
activeProviderId: this.activeProviderId,
|
|
59
|
+
registeredProviders: Array.from(this.providers.keys()),
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
55
63
|
if (!this.activeProviderId) {
|
|
64
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
65
|
+
// eslint-disable-next-line no-console
|
|
66
|
+
console.warn("[ProviderRegistry] No active provider set!");
|
|
67
|
+
}
|
|
56
68
|
return null;
|
|
57
69
|
}
|
|
58
|
-
|
|
70
|
+
|
|
71
|
+
const provider = this.providers.get(this.activeProviderId) ?? null;
|
|
72
|
+
|
|
73
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
74
|
+
// eslint-disable-next-line no-console
|
|
75
|
+
console.log("[ProviderRegistry] getActiveProvider() returning", {
|
|
76
|
+
providerId: provider?.providerId,
|
|
77
|
+
isInitialized: provider?.isInitialized(),
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return provider;
|
|
59
82
|
}
|
|
60
83
|
|
|
61
84
|
getProvider(providerId: string): IAIProvider | null {
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
import { AIErrorType, type AIErrorInfo } from "../../domain/entities";
|
|
7
7
|
|
|
8
|
+
declare const __DEV__: boolean;
|
|
9
|
+
|
|
8
10
|
const NETWORK_ERROR_PATTERNS = [
|
|
9
11
|
"network",
|
|
10
12
|
"timeout",
|
|
@@ -60,18 +62,38 @@ function getStatusCode(error: unknown): number | undefined {
|
|
|
60
62
|
return undefined;
|
|
61
63
|
}
|
|
62
64
|
|
|
65
|
+
function logClassification(info: AIErrorInfo): AIErrorInfo {
|
|
66
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
67
|
+
// eslint-disable-next-line no-console
|
|
68
|
+
console.log("[ErrorClassifier] Classified as:", {
|
|
69
|
+
type: info.type,
|
|
70
|
+
messageKey: info.messageKey,
|
|
71
|
+
retryable: info.retryable,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return info;
|
|
75
|
+
}
|
|
76
|
+
|
|
63
77
|
export function classifyError(error: unknown): AIErrorInfo {
|
|
64
78
|
const message = error instanceof Error ? error.message : String(error);
|
|
65
79
|
const statusCode = getStatusCode(error);
|
|
66
80
|
|
|
81
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
82
|
+
// eslint-disable-next-line no-console
|
|
83
|
+
console.log("[ErrorClassifier] Classifying error:", {
|
|
84
|
+
message: message.slice(0, 100),
|
|
85
|
+
statusCode,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
67
89
|
if (statusCode === 429 || matchesPatterns(message, RATE_LIMIT_PATTERNS)) {
|
|
68
|
-
return {
|
|
90
|
+
return logClassification({
|
|
69
91
|
type: AIErrorType.RATE_LIMIT,
|
|
70
92
|
messageKey: "error.rateLimit",
|
|
71
93
|
retryable: true,
|
|
72
94
|
originalError: error,
|
|
73
95
|
statusCode,
|
|
74
|
-
};
|
|
96
|
+
});
|
|
75
97
|
}
|
|
76
98
|
|
|
77
99
|
if (
|
|
@@ -79,65 +101,65 @@ export function classifyError(error: unknown): AIErrorInfo {
|
|
|
79
101
|
statusCode === 403 ||
|
|
80
102
|
matchesPatterns(message, AUTH_ERROR_PATTERNS)
|
|
81
103
|
) {
|
|
82
|
-
return {
|
|
104
|
+
return logClassification({
|
|
83
105
|
type: AIErrorType.AUTHENTICATION,
|
|
84
106
|
messageKey: "error.authentication",
|
|
85
107
|
retryable: false,
|
|
86
108
|
originalError: error,
|
|
87
109
|
statusCode,
|
|
88
|
-
};
|
|
110
|
+
});
|
|
89
111
|
}
|
|
90
112
|
|
|
91
113
|
if (matchesPatterns(message, CONTENT_POLICY_PATTERNS)) {
|
|
92
|
-
return {
|
|
114
|
+
return logClassification({
|
|
93
115
|
type: AIErrorType.CONTENT_POLICY,
|
|
94
116
|
messageKey: "error.contentPolicy",
|
|
95
117
|
retryable: false,
|
|
96
118
|
originalError: error,
|
|
97
119
|
statusCode,
|
|
98
|
-
};
|
|
120
|
+
});
|
|
99
121
|
}
|
|
100
122
|
|
|
101
123
|
if (matchesPatterns(message, NETWORK_ERROR_PATTERNS)) {
|
|
102
|
-
return {
|
|
124
|
+
return logClassification({
|
|
103
125
|
type: AIErrorType.NETWORK,
|
|
104
126
|
messageKey: "error.network",
|
|
105
127
|
retryable: true,
|
|
106
128
|
originalError: error,
|
|
107
129
|
statusCode,
|
|
108
|
-
};
|
|
130
|
+
});
|
|
109
131
|
}
|
|
110
132
|
|
|
111
133
|
if (
|
|
112
134
|
(statusCode && statusCode >= 500) ||
|
|
113
135
|
matchesPatterns(message, SERVER_ERROR_PATTERNS)
|
|
114
136
|
) {
|
|
115
|
-
return {
|
|
137
|
+
return logClassification({
|
|
116
138
|
type: AIErrorType.SERVER,
|
|
117
139
|
messageKey: "error.server",
|
|
118
140
|
retryable: true,
|
|
119
141
|
originalError: error,
|
|
120
142
|
statusCode,
|
|
121
|
-
};
|
|
143
|
+
});
|
|
122
144
|
}
|
|
123
145
|
|
|
124
146
|
if (message.toLowerCase().includes("timeout")) {
|
|
125
|
-
return {
|
|
147
|
+
return logClassification({
|
|
126
148
|
type: AIErrorType.TIMEOUT,
|
|
127
149
|
messageKey: "error.timeout",
|
|
128
150
|
retryable: true,
|
|
129
151
|
originalError: error,
|
|
130
152
|
statusCode,
|
|
131
|
-
};
|
|
153
|
+
});
|
|
132
154
|
}
|
|
133
155
|
|
|
134
|
-
return {
|
|
156
|
+
return logClassification({
|
|
135
157
|
type: AIErrorType.UNKNOWN,
|
|
136
158
|
messageKey: "error.unknown",
|
|
137
159
|
retryable: false,
|
|
138
160
|
originalError: error,
|
|
139
161
|
statusCode,
|
|
140
|
-
};
|
|
162
|
+
});
|
|
141
163
|
}
|
|
142
164
|
|
|
143
165
|
export function isTransientError(error: unknown): boolean {
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* Validates AI generation job results
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
declare const __DEV__: boolean;
|
|
7
|
+
|
|
6
8
|
export interface ResultValidation {
|
|
7
9
|
isValid: boolean;
|
|
8
10
|
hasError: boolean;
|
|
@@ -98,12 +100,24 @@ export function validateResult(
|
|
|
98
100
|
const hasError =
|
|
99
101
|
hasInternalServerError || (isEmpty && !hasOutput && !allowEmpty);
|
|
100
102
|
|
|
101
|
-
|
|
103
|
+
const validation: ResultValidation = {
|
|
102
104
|
isValid: !hasError && (hasOutput || allowEmpty),
|
|
103
105
|
hasError,
|
|
104
106
|
errorMessage: hasError && errorValue ? String(errorValue) : undefined,
|
|
105
107
|
hasOutput,
|
|
106
108
|
};
|
|
109
|
+
|
|
110
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
111
|
+
// eslint-disable-next-line no-console
|
|
112
|
+
console.log("[ResultValidator] Validation result:", {
|
|
113
|
+
isValid: validation.isValid,
|
|
114
|
+
hasOutput: validation.hasOutput,
|
|
115
|
+
hasError: validation.hasError,
|
|
116
|
+
checkedFields: outputFields.join(", "),
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return validation;
|
|
107
121
|
}
|
|
108
122
|
|
|
109
123
|
/**
|