@umituz/react-native-ai-pruna-provider 1.0.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/README.md ADDED
@@ -0,0 +1,447 @@
1
+ # @umituz/react-native-ai-pruna-provider
2
+
3
+ Pruna AI provider for React Native - Unified AI generation with IAIProvider interface implementation.
4
+
5
+ Supports **text-to-image**, **image-to-image**, and **image-to-video** generation via [Pruna AI](https://docs.pruna.ai).
6
+
7
+ ## Documentation Strategy
8
+
9
+ **Important:** This documentation follows a code-example-free approach for implementation details.
10
+
11
+ - **No Code Examples:** Documentation references file paths instead of showing internal code
12
+ - **Path-Based References:** Always references actual file locations
13
+ - **Maintainable:** Documentation stays valid when implementation changes
14
+
15
+ ---
16
+
17
+ ## Features
18
+
19
+ - **Text-to-Image Generation** - Generate images from text prompts (`p-image` model)
20
+ - **Image-to-Image Editing** - Transform/edit images with prompts (`p-image-edit` model)
21
+ - **Image-to-Video Conversion** - Convert static images to video with motion (`p-video` model)
22
+ - **Automatic File Upload** - Base64 images auto-uploaded to Pruna CDN for video generation
23
+ - **Async Polling** - Try-Sync with automatic fallback to async polling (~6 min max)
24
+ - **Request Deduplication** - Identical requests return same promise (no duplicate API calls)
25
+ - **Retry with Backoff** - Network/timeout/5xx errors retried (1 retry, 3s delay)
26
+ - **Session-Scoped Logging** - Each generation has isolated log session for debugging
27
+ - **Cancellation Support** - AbortController-based request cancellation
28
+ - **IAIProvider Compatible** - Plug-and-play with `@umituz/react-native-ai-generation-content`
29
+
30
+ ---
31
+
32
+ ## Supported Models
33
+
34
+ | Model | Type | Input | Output | Key Features |
35
+ |-------|------|-------|--------|-------------|
36
+ | `p-image` | Text → Image | Text prompt | Image URL | 7 aspect ratios, optional seed |
37
+ | `p-image-edit` | Image → Image | Image(s) + prompt | Image URL | Multi-image support, base64 or URL |
38
+ | `p-video` | Image → Video | Image + prompt | Video URL | 1-10s duration, 720p/1080p, draft mode |
39
+
40
+ ### Aspect Ratios (All Models)
41
+
42
+ `16:9` · `9:16` · `1:1` · `4:3` · `3:4` · `3:2` · `2:3`
43
+
44
+ ### Video Options (p-video only)
45
+
46
+ - **Duration:** 1-10 seconds (default: 5)
47
+ - **Resolution:** `720p` or `1080p` (default: 720p)
48
+ - **FPS:** 24 (fixed)
49
+ - **Draft mode:** Fast 1-second preview generation
50
+ - **Prompt upsampling:** Enabled by default
51
+
52
+ ---
53
+
54
+ ## Installation
55
+
56
+ ```bash
57
+ npm install @umituz/react-native-ai-pruna-provider
58
+ ```
59
+
60
+ **Peer Dependencies:**
61
+ - `@umituz/react-native-ai-generation-content` >= 1.70.0
62
+ - `expo` >= 54.0.0
63
+ - `react` >= 19.0.0
64
+ - `react-native` >= 0.81.4
65
+
66
+ **Note:** No external AI SDK required — uses native `fetch()` for all API communication.
67
+
68
+ ---
69
+
70
+ ## Quick Start
71
+
72
+ ### 1. Initialize Provider
73
+
74
+ **Location:** `src/init/initializePrunaProvider.ts`
75
+
76
+ **Import:**
77
+ ```typescript
78
+ import { initializePrunaProvider } from '@umituz/react-native-ai-pruna-provider';
79
+ ```
80
+
81
+ **Usage:**
82
+ Call `initializePrunaProvider()` with your Pruna API key at app startup. This initializes the provider and registers it with the provider registry.
83
+
84
+ **Alternative:** Use `createAiProviderInitModule()` from `src/init/createAiProviderInitModule.ts` for integration with app initializer patterns.
85
+
86
+ ---
87
+
88
+ ### 2. Use Provider Directly
89
+
90
+ **Location:** `src/infrastructure/services/pruna-provider.ts`
91
+
92
+ **Import:**
93
+ ```typescript
94
+ import { prunaProvider } from '@umituz/react-native-ai-pruna-provider';
95
+ ```
96
+
97
+ **Key Methods:**
98
+ - `subscribe()` - Long-running generation with polling, retry, and cancellation
99
+ - `run()` - Direct execution (no retry)
100
+ - `submitJob()` - Submit to queue, get request ID
101
+ - `getJobStatus()` - Poll job status
102
+ - `getJobResult()` - Fetch completed result
103
+ - `cancelCurrentRequest()` - Cancel active request
104
+ - `hasRunningRequest()` - Check for running requests
105
+ - `getSessionLogs()` - Get generation logs by session ID
106
+ - `endLogSession()` - End and retrieve log session
107
+
108
+ ---
109
+
110
+ ### 3. Use React Hook
111
+
112
+ **Location:** `src/presentation/hooks/use-pruna-generation.ts`
113
+
114
+ **Import:**
115
+ ```typescript
116
+ import { usePrunaGeneration } from '@umituz/react-native-ai-pruna-provider';
117
+ ```
118
+
119
+ **Returns:**
120
+ - `data` - Generation result (`{ url: string }`)
121
+ - `error` - Typed error information (`PrunaErrorInfo`)
122
+ - `isLoading` - Loading state
123
+ - `isRetryable` - Whether error can be retried
124
+ - `requestId` - Current request ID
125
+ - `isCancelling` - Cancellation in progress
126
+ - `generate()` - Start generation
127
+ - `retry()` - Retry last failed generation
128
+ - `cancel()` - Cancel current generation
129
+ - `reset()` - Reset all state
130
+
131
+ **Implementation:** See `src/presentation/hooks/use-pruna-generation.ts` for options and callbacks.
132
+
133
+ ---
134
+
135
+ ## Architecture
136
+
137
+ ```
138
+ src/
139
+ ├── domain/ # Types & interfaces
140
+ │ ├── entities/
141
+ │ │ ├── pruna.types.ts # PrunaModelId, PrunaAspectRatio, PrunaResolution, etc.
142
+ │ │ └── error.types.ts # PrunaErrorType enum, PrunaErrorInfo
143
+ │ └── types/
144
+ │ └── index.ts # IAIProvider re-export from generation-content
145
+
146
+ ├── infrastructure/ # Implementation
147
+ │ ├── services/
148
+ │ │ ├── pruna-provider.ts # Main PrunaProvider class (IAIProvider impl)
149
+ │ │ ├── pruna-provider.constants.ts # URLs, config, capabilities, defaults
150
+ │ │ ├── pruna-api-client.ts # Low-level HTTP: upload, prediction, polling
151
+ │ │ ├── pruna-input-builder.ts # Model-specific payload construction
152
+ │ │ ├── pruna-provider-subscription.ts # Subscribe/run with retry logic
153
+ │ │ ├── pruna-queue-operations.ts # submitJob, getJobStatus, getJobResult
154
+ │ │ └── request-store.ts # Promise deduplication (globalThis)
155
+ │ └── utils/
156
+ │ ├── log-collector.ts # Session-scoped generation logging
157
+ │ ├── pruna-error-handler.util.ts # Error mapping & classification
158
+ │ ├── pruna-generation-state-manager.util.ts # React state management
159
+ │ ├── type-guards/ # Type validation utilities
160
+ │ └── helpers/ # isDefined, sleep, generateUniqueId, etc.
161
+
162
+ ├── presentation/
163
+ │ └── hooks/
164
+ │ └── use-pruna-generation.ts # React hook for generation operations
165
+
166
+ ├── init/
167
+ │ ├── createAiProviderInitModule.ts # Factory for app initializer integration
168
+ │ └── initializePrunaProvider.ts # Direct synchronous initialization
169
+
170
+ ├── exports/ # Barrel exports per layer
171
+ │ ├── domain.ts
172
+ │ ├── infrastructure.ts
173
+ │ └── presentation.ts
174
+
175
+ └── index.ts # Main entry point
176
+ ```
177
+
178
+ ---
179
+
180
+ ## API Reference
181
+
182
+ ### Pruna API Integration
183
+
184
+ **Base URL:** `https://api.pruna.ai`
185
+
186
+ **Endpoints:**
187
+ - `POST /v1/predictions` - Submit generation (with `Try-Sync` header)
188
+ - `POST /v1/files` - Upload images for video generation
189
+ - `GET {poll_url}` - Poll async results
190
+
191
+ **Authentication:** `apikey` header
192
+
193
+ **Implementation:** See `src/infrastructure/services/pruna-api-client.ts`
194
+
195
+ ---
196
+
197
+ ### Model Input Building
198
+
199
+ **Location:** `src/infrastructure/services/pruna-input-builder.ts`
200
+
201
+ Each model has strict schema requirements:
202
+
203
+ **p-image (text-to-image):**
204
+ - Required: `prompt`
205
+ - Optional: `aspect_ratio`, `seed`
206
+
207
+ **p-image-edit (image-to-image):**
208
+ - Required: `prompt`, image input (`image`, `images`, `image_url`, or `image_urls`)
209
+ - Optional: `aspect_ratio`, `seed`
210
+ - Note: Images sent as raw base64 (prefix stripped automatically)
211
+
212
+ **p-video (image-to-video):**
213
+ - Required: `prompt`, image input (`image` or `image_url`)
214
+ - Optional: `duration`, `resolution`, `draft`, `aspect_ratio`
215
+ - Note: Base64 images auto-uploaded to Pruna file storage (p-video requires HTTPS URL)
216
+ - Fixed: `fps: 24`, `prompt_upsampling: true`
217
+
218
+ ---
219
+
220
+ ### Error Handling
221
+
222
+ **Location:** `src/infrastructure/utils/pruna-error-handler.util.ts`
223
+
224
+ **Error Types (`PrunaErrorType`):**
225
+ - `NETWORK` - Connection failures (retryable)
226
+ - `TIMEOUT` - Request timeout (retryable)
227
+ - `API_ERROR` - Server errors 5xx (retryable)
228
+ - `RATE_LIMIT` - Too many requests 429 (retryable)
229
+ - `VALIDATION` - Invalid input 400/422 (not retryable)
230
+ - `AUTHENTICATION` - Invalid API key 401/403 (not retryable)
231
+ - `QUOTA_EXCEEDED` - Billing issue 402 (not retryable)
232
+ - `MODEL_NOT_FOUND` - Invalid model 404 (not retryable)
233
+ - `FILE_UPLOAD` - Image upload failure (retryable)
234
+ - `POLLING_TIMEOUT` - Async polling exceeded max attempts (retryable)
235
+ - `INVALID_IMAGE` - Malformed image data (not retryable)
236
+ - `UNKNOWN` - Unclassified error (not retryable)
237
+
238
+ **Functions:**
239
+ - `mapPrunaError()` - Map raw error to `PrunaErrorInfo`
240
+ - `isPrunaErrorRetryable()` - Check if error can be retried
241
+ - `getErrorMessage()` - Extract error message string
242
+ - `formatErrorMessage()` - Format error with context
243
+
244
+ ---
245
+
246
+ ### Retry Strategy
247
+
248
+ ```
249
+ ┌──────────────────────────────────────────────────┐
250
+ │ FILE UPLOAD (Pruna /v1/files) │
251
+ │ Timeout: 30s / attempt │
252
+ │ Retries: 2 (3 total attempts) │
253
+ │ Backoff: 1s → 2s (exponential) │
254
+ │ Retries on: network, timeout │
255
+ ├──────────────────────────────────────────────────┤
256
+ │ PREDICTION (Pruna /v1/predictions) │
257
+ │ Timeout: caller-defined (default 360s) │
258
+ │ Retries: 1 (2 total attempts) │
259
+ │ Backoff: 3s (fixed) │
260
+ │ Retries on: network, timeout, server (5xx) │
261
+ │ NO retry: auth, validation, quota, cancel │
262
+ ├──────────────────────────────────────────────────┤
263
+ │ POLLING (async result polling) │
264
+ │ Interval: 3s │
265
+ │ Max attempts: 120 (~6 min) │
266
+ │ Retries on: non-ok responses (skip & continue) │
267
+ └──────────────────────────────────────────────────┘
268
+ ```
269
+
270
+ ---
271
+
272
+ ### Request Deduplication
273
+
274
+ **Location:** `src/infrastructure/services/request-store.ts`
275
+
276
+ - Same model + same input = returns existing promise (no duplicate API call)
277
+ - Uses `globalThis` storage — survives React Native hot reloads
278
+ - Automatic cleanup: stale requests removed after 5 minutes
279
+ - Deterministic key generation via recursive key sorting + hash
280
+
281
+ ---
282
+
283
+ ### Session-Scoped Logging
284
+
285
+ **Location:** `src/infrastructure/utils/log-collector.ts`
286
+
287
+ Each generation creates an isolated log session:
288
+ - Concurrent generations don't interfere
289
+ - Logs attached to result via `__providerSessionId` property
290
+ - Retrieve logs: `prunaProvider.getSessionLogs(sessionId)`
291
+ - End session: `prunaProvider.endLogSession(sessionId)`
292
+
293
+ ---
294
+
295
+ ## Type Definitions
296
+
297
+ ### Core Types
298
+
299
+ **Location:** `src/domain/entities/pruna.types.ts`
300
+
301
+ **Types:**
302
+ - `PrunaConfig` - Provider configuration
303
+ - `PrunaModelId` - Valid model IDs (`'p-video' | 'p-image' | 'p-image-edit'`)
304
+ - `PrunaModelType` - Model type classification
305
+ - `PrunaAspectRatio` - Supported aspect ratios
306
+ - `PrunaResolution` - Video resolution (`'720p' | '1080p'`)
307
+ - `PrunaJobInput` - Job input structure
308
+ - `PrunaJobResult` - Job result structure
309
+ - `PrunaQueueStatus` - Queue status structure
310
+ - `PrunaPredictionInput` - Prediction request input
311
+ - `PrunaPredictionResponse` - Raw API response
312
+ - `PrunaFileUploadResponse` - File upload response
313
+
314
+ **Import:**
315
+ ```typescript
316
+ import type {
317
+ PrunaModelId,
318
+ PrunaAspectRatio,
319
+ PrunaResolution,
320
+ PrunaQueueStatus,
321
+ } from '@umituz/react-native-ai-pruna-provider';
322
+ ```
323
+
324
+ ---
325
+
326
+ ### Error Types
327
+
328
+ **Location:** `src/domain/entities/error.types.ts`
329
+
330
+ **Types:**
331
+ - `PrunaErrorType` - Error type enumeration
332
+ - `PrunaErrorCategory` - Error category with retryable flag
333
+ - `PrunaErrorInfo` - Complete error information structure
334
+ - `PrunaErrorMessages` - Custom error message overrides
335
+
336
+ **Import:**
337
+ ```typescript
338
+ import { PrunaErrorType } from '@umituz/react-native-ai-pruna-provider';
339
+ import type { PrunaErrorInfo } from '@umituz/react-native-ai-pruna-provider';
340
+ ```
341
+
342
+ ---
343
+
344
+ ## Constants
345
+
346
+ ### Provider Constants
347
+
348
+ **Location:** `src/infrastructure/services/pruna-provider.constants.ts`
349
+
350
+ **Exports:**
351
+ - `PRUNA_BASE_URL` - API base URL
352
+ - `PRUNA_PREDICTIONS_URL` - Predictions endpoint
353
+ - `PRUNA_FILES_URL` - File upload endpoint
354
+ - `DEFAULT_PRUNA_CONFIG` - Default retry/timeout/polling configuration
355
+ - `UPLOAD_CONFIG` - File upload retry configuration
356
+ - `PRUNA_CAPABILITIES` - Provider capability flags
357
+ - `VALID_PRUNA_MODELS` - Array of valid model IDs
358
+ - `P_VIDEO_DEFAULTS` - Default p-video parameters
359
+ - `DEFAULT_ASPECT_RATIO` - Default aspect ratio (`'16:9'`)
360
+
361
+ ---
362
+
363
+ ## Utilities
364
+
365
+ ### Type Guards
366
+
367
+ **Location:** `src/infrastructure/utils/type-guards/index.ts`
368
+
369
+ **Functions:**
370
+ - `isPrunaModelId()` - Validate Pruna model ID
371
+ - `isPrunaErrorType()` - Validate error type
372
+ - `isValidApiKey()` - Validate API key
373
+ - `isValidModelId()` - Validate model ID format
374
+ - `isValidPrompt()` - Validate prompt (max 5000 chars)
375
+ - `isValidTimeout()` - Validate timeout value
376
+
377
+ ### Helper Functions
378
+
379
+ **Location:** `src/infrastructure/utils/helpers/index.ts`
380
+
381
+ **Functions:**
382
+ - `isDefined()` - Type-safe null/undefined check
383
+ - `removeNullish()` - Remove null/undefined from object
384
+ - `generateUniqueId()` - Generate unique ID with prefix
385
+ - `sleep()` - Promise-based delay
386
+
387
+ ---
388
+
389
+ ## Integration with generation-content
390
+
391
+ 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.
392
+
393
+ **Provider switching:**
394
+ ```typescript
395
+ import { providerRegistry } from '@umituz/react-native-ai-generation-content';
396
+
397
+ // Switch to Pruna
398
+ providerRegistry.setActiveProvider('pruna');
399
+
400
+ // Switch back to FAL
401
+ providerRegistry.setActiveProvider('fal');
402
+ ```
403
+
404
+ ---
405
+
406
+ ## For AI Agents
407
+
408
+ ### When Working with This Codebase
409
+
410
+ **DO:**
411
+ - Read the actual source files before writing code
412
+ - Follow existing patterns in the codebase
413
+ - Use types from `src/domain/`
414
+ - Respect the architecture (domain/infrastructure/presentation)
415
+ - Maintain type safety
416
+
417
+ **DON'T:**
418
+ - Write code without reading existing implementations
419
+ - Make assumptions about code structure
420
+ - Skip type definitions
421
+ - Create parallel implementations
422
+
423
+ ### Implementation Patterns
424
+
425
+ **For New Features:**
426
+ 1. Define types in `src/domain/entities/` or `src/domain/types/`
427
+ 2. Implement in appropriate layer (infrastructure for services, presentation for hooks)
428
+ 3. Export from `src/exports/` barrel files
429
+ 4. Re-export from `src/index.ts`
430
+
431
+ **For Modifications:**
432
+ 1. Read the complete file first
433
+ 2. Understand dependencies and the call chain
434
+ 3. Make changes while maintaining existing patterns
435
+ 4. Test type safety with `npm run typecheck`
436
+
437
+ ---
438
+
439
+ ## Support
440
+
441
+ **Documentation:** See individual source files for inline documentation
442
+
443
+ **Issues:** Report issues at https://github.com/umituz/react-native-ai-pruna-provider/issues
444
+
445
+ **Author:** Umit UZ <umit@umituz.com>
446
+
447
+ **License:** MIT
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@umituz/react-native-ai-pruna-provider",
3
+ "version": "1.0.0",
4
+ "description": "Pruna AI provider for React Native - implements IAIProvider interface for unified AI generation",
5
+ "main": "./src/index.ts",
6
+ "types": "./src/index.ts",
7
+ "sideEffects": false,
8
+ "exports": {
9
+ ".": "./src/index.ts",
10
+ "./package.json": "./package.json"
11
+ },
12
+ "scripts": {
13
+ "typecheck": "tsc --noEmit --project tsconfig.typecheck.json",
14
+ "lint": "eslint src --ext .ts,.tsx --max-warnings 0",
15
+ "lint:fix": "eslint src --ext .ts,.tsx --fix"
16
+ },
17
+ "keywords": [
18
+ "react-native",
19
+ "pruna-ai",
20
+ "ai",
21
+ "ai-provider",
22
+ "text-to-image",
23
+ "image-to-video",
24
+ "image-to-image",
25
+ "ai-generation",
26
+ "provider-agnostic"
27
+ ],
28
+ "author": "Umit UZ <umit@umituz.com>",
29
+ "license": "MIT",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "https://github.com/umituz/react-native-ai-pruna-provider"
33
+ },
34
+ "peerDependencies": {
35
+ "@umituz/react-native-ai-generation-content": ">=1.70.0",
36
+ "expo": ">=54.0.0",
37
+ "react": ">=19.0.0",
38
+ "react-native": ">=0.81.4"
39
+ },
40
+ "devDependencies": {
41
+ "@types/react": "~19.1.0",
42
+ "@typescript-eslint/eslint-plugin": "^7.0.0",
43
+ "@typescript-eslint/parser": "^7.0.0",
44
+ "@umituz/react-native-ai-generation-content": "^1.83.17",
45
+ "eslint": "^8.57.0",
46
+ "react": "19.1.0",
47
+ "react-native": "0.81.4",
48
+ "typescript": "^5.3.0"
49
+ },
50
+ "publishConfig": {
51
+ "access": "public"
52
+ },
53
+ "files": [
54
+ "src",
55
+ "README.md",
56
+ "LICENSE"
57
+ ]
58
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Pruna Error Types
3
+ * Error handling type definitions
4
+ */
5
+
6
+ export enum PrunaErrorType {
7
+ NETWORK = "network",
8
+ TIMEOUT = "timeout",
9
+ API_ERROR = "api_error",
10
+ VALIDATION = "validation",
11
+ CONTENT_POLICY = "content_policy",
12
+ RATE_LIMIT = "rate_limit",
13
+ AUTHENTICATION = "authentication",
14
+ QUOTA_EXCEEDED = "quota_exceeded",
15
+ MODEL_NOT_FOUND = "model_not_found",
16
+ FILE_UPLOAD = "file_upload",
17
+ POLLING_TIMEOUT = "polling_timeout",
18
+ INVALID_IMAGE = "invalid_image",
19
+ UNKNOWN = "unknown",
20
+ }
21
+
22
+ export interface PrunaErrorCategory {
23
+ readonly type: PrunaErrorType;
24
+ readonly messageKey: string;
25
+ readonly retryable: boolean;
26
+ }
27
+
28
+ export interface PrunaErrorInfo {
29
+ readonly type: PrunaErrorType;
30
+ readonly messageKey: string;
31
+ readonly retryable: boolean;
32
+ readonly originalError: string;
33
+ readonly originalErrorName?: string;
34
+ readonly stack?: string;
35
+ readonly statusCode?: number;
36
+ }
37
+
38
+ export interface PrunaErrorMessages {
39
+ network?: string;
40
+ timeout?: string;
41
+ api_error?: string;
42
+ validation?: string;
43
+ content_policy?: string;
44
+ rate_limit?: string;
45
+ authentication?: string;
46
+ quota_exceeded?: string;
47
+ model_not_found?: string;
48
+ file_upload?: string;
49
+ polling_timeout?: string;
50
+ invalid_image?: string;
51
+ unknown?: string;
52
+ }
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Pruna AI Types
3
+ * Core type definitions for Pruna AI integration
4
+ *
5
+ * Models (from docs.pruna.ai):
6
+ * p-video: image-to-video — requires image (file URL), prompt, duration, resolution, fps, draft, aspect_ratio
7
+ * p-image: text-to-image — requires prompt; optional aspect_ratio, seed
8
+ * p-image-edit: image-to-image — requires images[] (base64 or URL), prompt; optional aspect_ratio, seed
9
+ */
10
+
11
+ export interface PrunaConfig {
12
+ readonly apiKey: string;
13
+ readonly baseUrl?: string;
14
+ readonly maxRetries?: number;
15
+ readonly baseDelay?: number;
16
+ readonly maxDelay?: number;
17
+ readonly defaultTimeoutMs?: number;
18
+ }
19
+
20
+ export type PrunaModelId = 'p-video' | 'p-image' | 'p-image-edit';
21
+
22
+ export type PrunaModelType =
23
+ | "text-to-image"
24
+ | "image-to-video"
25
+ | "image-to-image";
26
+
27
+ export type PrunaAspectRatio = '16:9' | '9:16' | '1:1' | '4:3' | '3:4' | '3:2' | '2:3';
28
+
29
+ export type PrunaResolution = '720p' | '1080p';
30
+
31
+ export interface PrunaModel {
32
+ readonly id: PrunaModelId;
33
+ readonly name: string;
34
+ readonly description?: string;
35
+ readonly type: PrunaModelType;
36
+ readonly pricing?: PrunaModelPricing;
37
+ readonly enabled: boolean;
38
+ }
39
+
40
+ export interface PrunaModelPricing {
41
+ readonly baseCost: number;
42
+ readonly perSecondCost?: number;
43
+ readonly resolutionMultiplier?: Record<PrunaResolution, number>;
44
+ }
45
+
46
+ export interface PrunaJobInput {
47
+ readonly [key: string]: unknown;
48
+ }
49
+
50
+ export interface PrunaJobResult<T = unknown> {
51
+ readonly requestId: string;
52
+ readonly data: T;
53
+ }
54
+
55
+ export interface PrunaLogEntry {
56
+ readonly message: string;
57
+ readonly timestamp?: string;
58
+ readonly level?: "info" | "warn" | "error";
59
+ }
60
+
61
+ export type PrunaJobStatusType = "IN_QUEUE" | "IN_PROGRESS" | "COMPLETED" | "FAILED";
62
+
63
+ export interface PrunaQueueStatus {
64
+ readonly status: PrunaJobStatusType;
65
+ readonly requestId: string;
66
+ readonly logs?: readonly PrunaLogEntry[];
67
+ }
68
+
69
+ export interface PrunaSubscribeOptions {
70
+ readonly onQueueUpdate?: (update: PrunaQueueStatus) => void;
71
+ readonly timeoutMs?: number;
72
+ }
73
+
74
+ /**
75
+ * Pruna API prediction request input
76
+ */
77
+ export interface PrunaPredictionInput {
78
+ readonly prompt: string;
79
+ readonly aspect_ratio?: PrunaAspectRatio;
80
+ readonly image?: string;
81
+ readonly images?: readonly string[];
82
+ readonly duration?: number;
83
+ readonly resolution?: PrunaResolution;
84
+ readonly fps?: number;
85
+ readonly draft?: boolean;
86
+ readonly prompt_upsampling?: boolean;
87
+ readonly seed?: number;
88
+ }
89
+
90
+ /**
91
+ * Pruna API prediction response (raw)
92
+ */
93
+ export interface PrunaPredictionResponse {
94
+ readonly generation_url?: string;
95
+ readonly output?: { readonly url: string } | string | readonly string[];
96
+ readonly data?: string;
97
+ readonly video_url?: string;
98
+ readonly get_url?: string;
99
+ readonly status_url?: string;
100
+ readonly status?: 'succeeded' | 'completed' | 'failed';
101
+ readonly error?: string;
102
+ }
103
+
104
+ /**
105
+ * Pruna API file upload response
106
+ */
107
+ export interface PrunaFileUploadResponse {
108
+ readonly id?: string;
109
+ readonly urls?: {
110
+ readonly get: string;
111
+ };
112
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Domain Types Index
3
+ */
4
+
5
+ // Provider Types (imported from core package)
6
+ export type {
7
+ ImageFeatureType,
8
+ VideoFeatureType,
9
+ AIProviderConfig,
10
+ AIJobStatusType,
11
+ AILogEntry,
12
+ JobSubmission,
13
+ JobStatus,
14
+ ProviderProgressInfo,
15
+ SubscribeOptions,
16
+ RunOptions,
17
+ ProviderCapabilities,
18
+ ImageFeatureInputData,
19
+ VideoFeatureInputData,
20
+ IAIProvider,
21
+ } from "@umituz/react-native-ai-generation-content/core";