@umituz/react-native-ai-generation-content 1.17.122 → 1.17.124

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-generation-content",
3
- "version": "1.17.122",
3
+ "version": "1.17.124",
4
4
  "description": "Provider-agnostic AI generation orchestration for React Native",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -49,6 +49,8 @@ export interface ProviderCapabilities {
49
49
  imageToVideo: boolean;
50
50
  /** Supports text-to-voice generation */
51
51
  textToVoice: boolean;
52
+ /** Supports text-to-text (LLM) generation */
53
+ textToText: boolean;
52
54
  }
53
55
 
54
56
  export interface JobSubmission {
@@ -89,6 +89,6 @@ export function mapDocumentToCreation(
89
89
  isShared: data.isShared ?? false,
90
90
  isFavorite: data.isFavorite ?? false,
91
91
  status: data.status as CreationStatus | undefined,
92
- output: data.output,
92
+ output: data.output ?? undefined,
93
93
  };
94
94
  }
@@ -1 +1,2 @@
1
1
  export * from "./presentation/screens";
2
+ export * from "./infrastructure/services/MemeGenerationService";
@@ -0,0 +1,82 @@
1
+ import { providerRegistry } from "../../../../infrastructure/services/provider.registry";
2
+
3
+ export interface MemeGenerationParams {
4
+ prompt: string;
5
+ styleId?: string;
6
+ }
7
+
8
+ export class MemeGenerationService {
9
+ /**
10
+ * Enhance a simple user prompt into a rich image generation prompt
11
+ */
12
+ async enhancePrompt(prompt: string, modelId?: string): Promise<string> {
13
+ try {
14
+ const provider = providerRegistry.getActiveProvider();
15
+ if (!provider) {
16
+ throw new Error("AI provider not available");
17
+ }
18
+
19
+ const systemPrompt = `You are an AI art director. Take the user's simple meme idea and transform it into a visually rich, detailed, and funny image generation prompt. Your response should be only the new prompt, no explanations. Idea: "${prompt}"`;
20
+
21
+ // Use provided modelId or try to find a default text-to-text model
22
+ const model = modelId || "fal-ai/llama-3-8cl-instruct";
23
+
24
+ const result = await provider.run<{ text?: string, data?: { text: string } }>(
25
+ model,
26
+ { prompt: systemPrompt }
27
+ );
28
+
29
+ // Handle different provider response formats
30
+ const text = result.text || result.data?.text || prompt;
31
+ return text;
32
+ } catch (error) {
33
+ if (__DEV__) {
34
+ // eslint-disable-next-line no-console
35
+ console.error("[MemeGenerationService] Enhance prompt error:", error);
36
+ }
37
+ return prompt;
38
+ }
39
+ }
40
+
41
+ /**
42
+ * Generate a meme image
43
+ */
44
+ async generateMeme(prompt: string, modelId?: string): Promise<string> {
45
+ try {
46
+ const provider = providerRegistry.getActiveProvider();
47
+ if (!provider) {
48
+ throw new Error("AI provider not available");
49
+ }
50
+
51
+ const enhancedPrompt = await this.enhancePrompt(prompt, modelId);
52
+ const finalPrompt = `High-quality, funny meme: ${enhancedPrompt}. Cinematic, vibrant, clean subject, NO TEXT in image.`;
53
+
54
+ const model = modelId || "fal-ai/flux/schnell";
55
+
56
+ // For Fal, we usually use subscribe or run
57
+ // provider.run should be enough for quick models like flux/schnell
58
+ const result = await provider.run<{ images: { url: string }[] }>(
59
+ model,
60
+ {
61
+ prompt: finalPrompt,
62
+ image_size: "square",
63
+ num_inference_steps: 4
64
+ }
65
+ );
66
+
67
+ if (result.images && result.images.length > 0) {
68
+ return result.images[0].url;
69
+ }
70
+
71
+ throw new Error("No image generated");
72
+ } catch (error) {
73
+ if (__DEV__) {
74
+ // eslint-disable-next-line no-console
75
+ console.error("[MemeGenerationService] Generate meme error:", error);
76
+ }
77
+ throw error;
78
+ }
79
+ }
80
+ }
81
+
82
+ export const memeGenerationService = new MemeGenerationService();
package/src/index.ts CHANGED
@@ -321,6 +321,7 @@ export {
321
321
  // Headers
322
322
  FeatureHeader,
323
323
  AIGenScreenHeader,
324
+ CreditBadge,
324
325
 
325
326
  // Photo Upload
326
327
  PhotoUploadCard,
@@ -380,6 +381,7 @@ export type {
380
381
  FeatureHeaderProps,
381
382
  AIGenScreenHeaderProps,
382
383
  NavigationButtonType,
384
+ CreditBadgeProps,
383
385
 
384
386
  // Photo Upload
385
387
  PhotoUploadCardProps,
@@ -0,0 +1,58 @@
1
+ import React from "react";
2
+ import { View, StyleSheet } from "react-native";
3
+ import {
4
+ AtomicText,
5
+ AtomicIcon,
6
+ useAppDesignTokens,
7
+ } from "@umituz/react-native-design-system";
8
+
9
+ export interface CreditBadgeProps {
10
+ readonly credits: number;
11
+ readonly iconName?: string;
12
+ readonly compact?: boolean;
13
+ }
14
+
15
+ export const CreditBadge: React.FC<CreditBadgeProps> = ({
16
+ credits,
17
+ iconName = "flash",
18
+ compact = false,
19
+ }) => {
20
+ const tokens = useAppDesignTokens();
21
+
22
+ return (
23
+ <View
24
+ style={[
25
+ styles.container,
26
+ compact && styles.compact,
27
+ { backgroundColor: tokens.colors.surface },
28
+ ]}
29
+ >
30
+ <AtomicIcon name={iconName} size="sm" color="warning" />
31
+ <AtomicText
32
+ type={compact ? "labelSmall" : "labelMedium"}
33
+ style={[styles.text, { color: tokens.colors.textPrimary }]}
34
+ >
35
+ {credits}
36
+ </AtomicText>
37
+ </View>
38
+ );
39
+ };
40
+
41
+ const styles = StyleSheet.create({
42
+ container: {
43
+ flexDirection: "row",
44
+ alignItems: "center",
45
+ paddingHorizontal: 10,
46
+ paddingVertical: 6,
47
+ borderRadius: 16,
48
+ gap: 4,
49
+ },
50
+ compact: {
51
+ paddingHorizontal: 8,
52
+ paddingVertical: 4,
53
+ borderRadius: 12,
54
+ },
55
+ text: {
56
+ fontWeight: "600",
57
+ },
58
+ });
@@ -1,2 +1,3 @@
1
1
  export * from "./FeatureHeader";
2
2
  export * from "./AIGenScreenHeader";
3
+ export * from "./CreditBadge";