Package Exports
- @umituz/react-native-ai-pruna-provider
- @umituz/react-native-ai-pruna-provider/package.json
Readme
@umituz/react-native-ai-pruna-provider
Pruna AI provider for React Native - Unified AI generation with IAIProvider interface implementation.
Supports text-to-image, image-to-image, and image-to-video generation via Pruna AI.
Documentation Strategy
Important: This documentation follows a code-example-free approach for implementation details.
- No Code Examples: Documentation references file paths instead of showing internal code
- Path-Based References: Always references actual file locations
- Maintainable: Documentation stays valid when implementation changes
Features
- Text-to-Image Generation - Generate images from text prompts (
p-imagemodel) - Image-to-Image Editing - Transform/edit images with prompts (
p-image-editmodel) - Image-to-Video Conversion - Convert static images to video with motion (
p-videomodel) - Automatic File Upload - Base64 images auto-uploaded to Pruna CDN for video generation
- Async Polling - Try-Sync with automatic fallback to async polling (~6 min max)
- Request Deduplication - Identical requests return same promise (no duplicate API calls)
- Retry with Backoff - Network/timeout/5xx errors retried (1 retry, 3s delay)
- Session-Scoped Logging - Each generation has isolated log session for debugging
- Cancellation Support - AbortController-based request cancellation
- IAIProvider Compatible - Plug-and-play with
@umituz/react-native-ai-generation-content
Supported Models
| Model | Type | Input | Output | Key Features |
|---|---|---|---|---|
p-image |
Text → Image | Text prompt | Image URL | 7 aspect ratios, optional seed |
p-image-edit |
Image → Image | Image(s) + prompt | Image URL | Multi-image support, base64 or URL |
p-video |
Image → Video | Image + prompt | Video URL | 1-10s duration, 720p/1080p, draft mode |
Aspect Ratios (All Models)
16:9 · 9:16 · 1:1 · 4:3 · 3:4 · 3:2 · 2:3
Video Options (p-video only)
- Duration: 1-10 seconds (default: 5)
- Resolution:
720por1080p(default: 720p) - FPS: 24 (fixed)
- Draft mode: Fast 1-second preview generation
- Prompt upsampling: Enabled by default
Installation
npm install @umituz/react-native-ai-pruna-providerPeer Dependencies:
@umituz/react-native-ai-generation-content>= 1.70.0expo>= 54.0.0react>= 19.0.0react-native>= 0.81.4
Note: No external AI SDK required — uses native fetch() for all API communication.
Quick Start
1. Initialize Provider
Location: src/init/initializePrunaProvider.ts
Import:
import { initializePrunaProvider } from '@umituz/react-native-ai-pruna-provider';Usage:
Call initializePrunaProvider() with your Pruna API key at app startup. This initializes the provider and registers it with the provider registry.
Alternative: Use createAiProviderInitModule() from src/init/createAiProviderInitModule.ts for integration with app initializer patterns.
2. Use Provider Directly
Location: src/infrastructure/services/pruna-provider.ts
Import:
import { prunaProvider } from '@umituz/react-native-ai-pruna-provider';Key Methods:
subscribe()- Long-running generation with polling, retry, and cancellationrun()- Direct execution (no retry)submitJob()- Submit to queue, get request IDgetJobStatus()- Poll job statusgetJobResult()- Fetch completed resultcancelCurrentRequest()- Cancel active requesthasRunningRequest()- Check for running requestsgetSessionLogs()- Get generation logs by session IDendLogSession()- End and retrieve log session
3. Use React Hook
Location: src/presentation/hooks/use-pruna-generation.ts
Import:
import { usePrunaGeneration } from '@umituz/react-native-ai-pruna-provider';Returns:
data- Generation result ({ url: string })error- Typed error information (PrunaErrorInfo)isLoading- Loading stateisRetryable- Whether error can be retriedrequestId- Current request IDisCancelling- Cancellation in progressgenerate()- Start generationretry()- Retry last failed generationcancel()- Cancel current generationreset()- Reset all state
Implementation: See src/presentation/hooks/use-pruna-generation.ts for options and callbacks.
Architecture
src/
├── domain/ # Types & interfaces
│ ├── entities/
│ │ ├── pruna.types.ts # PrunaModelId, PrunaAspectRatio, PrunaResolution, etc.
│ │ └── error.types.ts # PrunaErrorType enum, PrunaErrorInfo
│ └── types/
│ └── index.ts # IAIProvider re-export from generation-content
│
├── infrastructure/ # Implementation
│ ├── services/
│ │ ├── pruna-provider.ts # Main PrunaProvider class (IAIProvider impl)
│ │ ├── pruna-provider.constants.ts # URLs, config, capabilities, defaults
│ │ ├── pruna-api-client.ts # Low-level HTTP: upload, prediction, polling
│ │ ├── pruna-input-builder.ts # Model-specific payload construction
│ │ ├── pruna-provider-subscription.ts # Subscribe/run with retry logic
│ │ ├── pruna-queue-operations.ts # submitJob, getJobStatus, getJobResult
│ │ └── request-store.ts # Promise deduplication (globalThis)
│ └── utils/
│ ├── log-collector.ts # Session-scoped generation logging
│ ├── pruna-error-handler.util.ts # Error mapping & classification
│ ├── pruna-generation-state-manager.util.ts # React state management
│ ├── type-guards/ # Type validation utilities
│ └── helpers/ # isDefined, sleep, generateUniqueId, etc.
│
├── presentation/
│ └── hooks/
│ └── use-pruna-generation.ts # React hook for generation operations
│
├── init/
│ ├── createAiProviderInitModule.ts # Factory for app initializer integration
│ └── initializePrunaProvider.ts # Direct synchronous initialization
│
├── exports/ # Barrel exports per layer
│ ├── domain.ts
│ ├── infrastructure.ts
│ └── presentation.ts
│
└── index.ts # Main entry pointAPI Reference
Pruna API Integration
Base URL: https://api.pruna.ai
Endpoints:
POST /v1/predictions- Submit generation (withTry-Syncheader)POST /v1/files- Upload images for video generationGET {poll_url}- Poll async results
Authentication: apikey header
Implementation: See src/infrastructure/services/pruna-api-client.ts
Model Input Building
Location: src/infrastructure/services/pruna-input-builder.ts
Each model has strict schema requirements:
p-image (text-to-image):
- Required:
prompt - Optional:
aspect_ratio,seed
p-image-edit (image-to-image):
- Required:
prompt, image input (image,images,image_url, orimage_urls) - Optional:
aspect_ratio,seed - Note: Images sent as raw base64 (prefix stripped automatically)
p-video (image-to-video):
- Required:
prompt, image input (imageorimage_url) - Optional:
duration,resolution,draft,aspect_ratio - Note: Base64 images auto-uploaded to Pruna file storage (p-video requires HTTPS URL)
- Fixed:
fps: 24,prompt_upsampling: true
Error Handling
Location: src/infrastructure/utils/pruna-error-handler.util.ts
Error Types (PrunaErrorType):
NETWORK- Connection failures (retryable)TIMEOUT- Request timeout (retryable)API_ERROR- Server errors 5xx (retryable)RATE_LIMIT- Too many requests 429 (retryable)VALIDATION- Invalid input 400/422 (not retryable)AUTHENTICATION- Invalid API key 401/403 (not retryable)QUOTA_EXCEEDED- Billing issue 402 (not retryable)MODEL_NOT_FOUND- Invalid model 404 (not retryable)FILE_UPLOAD- Image upload failure (retryable)POLLING_TIMEOUT- Async polling exceeded max attempts (retryable)INVALID_IMAGE- Malformed image data (not retryable)UNKNOWN- Unclassified error (not retryable)
Functions:
mapPrunaError()- Map raw error toPrunaErrorInfoisPrunaErrorRetryable()- Check if error can be retriedgetErrorMessage()- Extract error message stringformatErrorMessage()- Format error with context
Retry Strategy
┌──────────────────────────────────────────────────┐
│ FILE UPLOAD (Pruna /v1/files) │
│ Timeout: 30s / attempt │
│ Retries: 2 (3 total attempts) │
│ Backoff: 1s → 2s (exponential) │
│ Retries on: network, timeout │
├──────────────────────────────────────────────────┤
│ PREDICTION (Pruna /v1/predictions) │
│ Timeout: caller-defined (default 360s) │
│ Retries: 1 (2 total attempts) │
│ Backoff: 3s (fixed) │
│ Retries on: network, timeout, server (5xx) │
│ NO retry: auth, validation, quota, cancel │
├──────────────────────────────────────────────────┤
│ POLLING (async result polling) │
│ Interval: 3s │
│ Max attempts: 120 (~6 min) │
│ Retries on: non-ok responses (skip & continue) │
└──────────────────────────────────────────────────┘Request Deduplication
Location: src/infrastructure/services/request-store.ts
- Same model + same input = returns existing promise (no duplicate API call)
- Uses
globalThisstorage — survives React Native hot reloads - Automatic cleanup: stale requests removed after 5 minutes
- Deterministic key generation via recursive key sorting + hash
Session-Scoped Logging
Location: src/infrastructure/utils/log-collector.ts
Each generation creates an isolated log session:
- Concurrent generations don't interfere
- Logs attached to result via
__providerSessionIdproperty - Retrieve logs:
prunaProvider.getSessionLogs(sessionId) - End session:
prunaProvider.endLogSession(sessionId)
Type Definitions
Core Types
Location: src/domain/entities/pruna.types.ts
Types:
PrunaConfig- Provider configurationPrunaModelId- Valid model IDs ('p-video' | 'p-image' | 'p-image-edit')PrunaModelType- Model type classificationPrunaAspectRatio- Supported aspect ratiosPrunaResolution- Video resolution ('720p' | '1080p')PrunaJobInput- Job input structurePrunaJobResult- Job result structurePrunaQueueStatus- Queue status structurePrunaPredictionInput- Prediction request inputPrunaPredictionResponse- Raw API responsePrunaFileUploadResponse- File upload response
Import:
import type {
PrunaModelId,
PrunaAspectRatio,
PrunaResolution,
PrunaQueueStatus,
} from '@umituz/react-native-ai-pruna-provider';Error Types
Location: src/domain/entities/error.types.ts
Types:
PrunaErrorType- Error type enumerationPrunaErrorCategory- Error category with retryable flagPrunaErrorInfo- Complete error information structurePrunaErrorMessages- Custom error message overrides
Import:
import { PrunaErrorType } from '@umituz/react-native-ai-pruna-provider';
import type { PrunaErrorInfo } from '@umituz/react-native-ai-pruna-provider';Constants
Provider Constants
Location: src/infrastructure/services/pruna-provider.constants.ts
Exports:
PRUNA_BASE_URL- API base URLPRUNA_PREDICTIONS_URL- Predictions endpointPRUNA_FILES_URL- File upload endpointDEFAULT_PRUNA_CONFIG- Default retry/timeout/polling configurationUPLOAD_CONFIG- File upload retry configurationPRUNA_CAPABILITIES- Provider capability flagsVALID_PRUNA_MODELS- Array of valid model IDsP_VIDEO_DEFAULTS- Default p-video parametersDEFAULT_ASPECT_RATIO- Default aspect ratio ('16:9')
Utilities
Type Guards
Location: src/infrastructure/utils/type-guards/index.ts
Functions:
isPrunaModelId()- Validate Pruna model IDisPrunaErrorType()- Validate error typeisValidApiKey()- Validate API keyisValidModelId()- Validate model ID formatisValidPrompt()- Validate prompt (max 5000 chars)isValidTimeout()- Validate timeout value
Helper Functions
Location: src/infrastructure/utils/helpers/index.ts
Functions:
isDefined()- Type-safe null/undefined checkremoveNullish()- Remove null/undefined from objectgenerateUniqueId()- Generate unique ID with prefixsleep()- Promise-based delay
Integration with generation-content
This provider implements the IAIProvider interface from @umituz/react-native-ai-generation-content/core. Once initialized, it registers with the providerRegistry and can be used as the active provider for all generation operations.
Provider switching:
import { providerRegistry } from '@umituz/react-native-ai-generation-content';
// Switch to Pruna
providerRegistry.setActiveProvider('pruna');
// Switch back to FAL
providerRegistry.setActiveProvider('fal');For AI Agents
When Working with This Codebase
DO:
- Read the actual source files before writing code
- Follow existing patterns in the codebase
- Use types from
src/domain/ - Respect the architecture (domain/infrastructure/presentation)
- Maintain type safety
DON'T:
- Write code without reading existing implementations
- Make assumptions about code structure
- Skip type definitions
- Create parallel implementations
Implementation Patterns
For New Features:
- Define types in
src/domain/entities/orsrc/domain/types/ - Implement in appropriate layer (infrastructure for services, presentation for hooks)
- Export from
src/exports/barrel files - Re-export from
src/index.ts
For Modifications:
- Read the complete file first
- Understand dependencies and the call chain
- Make changes while maintaining existing patterns
- Test type safety with
npm run typecheck
Support
Documentation: See individual source files for inline documentation
Issues: Report issues at https://github.com/umituz/react-native-ai-pruna-provider/issues
Author: Umit UZ umit@umituz.com
License: MIT