@umituz/react-native-ai-fal-provider 1.0.46 → 1.0.48
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-ai-fal-provider",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.48",
|
|
4
4
|
"description": "FAL AI provider for React Native - implements IAIProvider interface for unified AI generation",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
package/src/index.ts
CHANGED
|
@@ -25,7 +25,7 @@ export type { FeatureModelConfig } from "./domain/constants/feature-models.const
|
|
|
25
25
|
|
|
26
26
|
export {
|
|
27
27
|
FalProvider, falProvider, falModelsService,
|
|
28
|
-
getImageFeatureModel, getVideoFeatureModel,
|
|
28
|
+
getImageFeatureModel, getVideoFeatureModel, NSFWContentError,
|
|
29
29
|
} from "./infrastructure/services";
|
|
30
30
|
export type { ModelFetcher } from "./infrastructure/services";
|
|
31
31
|
|
|
@@ -20,6 +20,7 @@ import type {
|
|
|
20
20
|
import type { FalQueueStatus } from "../../domain/entities/fal.types";
|
|
21
21
|
import { DEFAULT_FAL_CONFIG, FAL_CAPABILITIES } from "./fal-provider.constants";
|
|
22
22
|
import { mapFalStatusToJobStatus } from "./fal-status-mapper";
|
|
23
|
+
import { NSFWContentError } from "./nsfw-content-error";
|
|
23
24
|
import { FAL_IMAGE_FEATURE_MODELS, FAL_VIDEO_FEATURE_MODELS } from "../../domain/constants/feature-models.constants";
|
|
24
25
|
import {
|
|
25
26
|
buildSingleImageInput,
|
|
@@ -119,17 +120,22 @@ export class FalProvider implements IAIProvider {
|
|
|
119
120
|
console.log("[FalProvider] Subscribe started:", { model, timeoutMs });
|
|
120
121
|
}
|
|
121
122
|
|
|
123
|
+
let lastStatus = "";
|
|
124
|
+
|
|
122
125
|
try {
|
|
123
126
|
const result = await Promise.race([
|
|
124
127
|
fal.subscribe(model, {
|
|
125
128
|
input,
|
|
126
|
-
logs:
|
|
129
|
+
logs: false,
|
|
127
130
|
pollInterval: DEFAULT_FAL_CONFIG.pollInterval,
|
|
128
131
|
onQueueUpdate: (update: { status: string; logs?: unknown[] }) => {
|
|
129
|
-
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
130
|
-
console.log("[FalProvider] Queue update:", JSON.stringify(update));
|
|
131
|
-
}
|
|
132
132
|
const jobStatus = mapFalStatusToJobStatus(update as unknown as FalQueueStatus);
|
|
133
|
+
if (jobStatus.status !== lastStatus) {
|
|
134
|
+
lastStatus = jobStatus.status;
|
|
135
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
136
|
+
console.log("[FalProvider] Status:", jobStatus.status);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
133
139
|
options?.onQueueUpdate?.(jobStatus);
|
|
134
140
|
},
|
|
135
141
|
}),
|
|
@@ -142,6 +148,8 @@ export class FalProvider implements IAIProvider {
|
|
|
142
148
|
console.log("[FalProvider] Subscribe completed:", { model });
|
|
143
149
|
}
|
|
144
150
|
|
|
151
|
+
this.checkForNSFWContent(result as Record<string, unknown>);
|
|
152
|
+
|
|
145
153
|
options?.onResult?.(result as T);
|
|
146
154
|
return result as T;
|
|
147
155
|
} finally {
|
|
@@ -163,19 +171,29 @@ export class FalProvider implements IAIProvider {
|
|
|
163
171
|
console.log("[FalProvider] run() raw result:", JSON.stringify(result, null, 2));
|
|
164
172
|
console.log("[FalProvider] run() result type:", typeof result);
|
|
165
173
|
console.log("[FalProvider] run() result keys:", result ? Object.keys(result as object) : "null");
|
|
166
|
-
const r = result as Record<string, unknown>;
|
|
167
|
-
if (r?.data) {
|
|
168
|
-
console.log("[FalProvider] run() has data property, data keys:", Object.keys(r.data as object));
|
|
169
|
-
}
|
|
170
|
-
if (r?.images) {
|
|
171
|
-
console.log("[FalProvider] run() has images property, images:", JSON.stringify(r.images));
|
|
172
|
-
}
|
|
173
174
|
}
|
|
174
175
|
|
|
176
|
+
this.checkForNSFWContent(result as Record<string, unknown>);
|
|
177
|
+
|
|
175
178
|
options?.onProgress?.({ progress: 100, status: "COMPLETED" });
|
|
176
179
|
return result as T;
|
|
177
180
|
}
|
|
178
181
|
|
|
182
|
+
private checkForNSFWContent(result: Record<string, unknown>): void {
|
|
183
|
+
const nsfwConcepts = result?.has_nsfw_concepts as boolean[] | undefined;
|
|
184
|
+
|
|
185
|
+
if (nsfwConcepts && Array.isArray(nsfwConcepts)) {
|
|
186
|
+
const hasNSFW = nsfwConcepts.some((value) => value === true);
|
|
187
|
+
|
|
188
|
+
if (hasNSFW) {
|
|
189
|
+
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
190
|
+
console.log("[FalProvider] NSFW content detected, rejecting result");
|
|
191
|
+
}
|
|
192
|
+
throw new NSFWContentError();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
179
197
|
reset(): void {
|
|
180
198
|
this.apiKey = null;
|
|
181
199
|
this.config = null;
|
|
@@ -7,6 +7,7 @@ import type { ImageFeatureType, VideoFeatureType } from "@umituz/react-native-ai
|
|
|
7
7
|
|
|
8
8
|
export { FalProvider, falProvider } from "./fal-provider";
|
|
9
9
|
export { falModelsService, type FalModelConfig, type ModelFetcher } from "./fal-models.service";
|
|
10
|
+
export { NSFWContentError } from "./nsfw-content-error";
|
|
10
11
|
|
|
11
12
|
export function getImageFeatureModel(feature: ImageFeatureType): string {
|
|
12
13
|
return FAL_IMAGE_FEATURE_MODELS[feature];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NSFW Content Error
|
|
3
|
+
* Thrown when AI provider detects NSFW content in generated output
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { FalErrorType } from "../../domain/entities/error.types";
|
|
7
|
+
|
|
8
|
+
export class NSFWContentError extends Error {
|
|
9
|
+
public readonly type = FalErrorType.CONTENT_POLICY;
|
|
10
|
+
public readonly retryable = false;
|
|
11
|
+
public readonly messageKey = "error.nsfw_content_detected";
|
|
12
|
+
|
|
13
|
+
constructor(message?: string) {
|
|
14
|
+
super(
|
|
15
|
+
message ||
|
|
16
|
+
"The generated content was flagged as inappropriate. Please try a different prompt."
|
|
17
|
+
);
|
|
18
|
+
this.name = "NSFWContentError";
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
getUserMessage(): string {
|
|
22
|
+
return this.message;
|
|
23
|
+
}
|
|
24
|
+
}
|