@umituz/react-native-ai-pruna-provider 1.0.41 → 1.0.43

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-pruna-provider",
3
- "version": "1.0.41",
3
+ "version": "1.0.43",
4
4
  "description": "Pruna AI provider for React Native - implements IAIProvider interface for unified AI generation",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -22,6 +22,8 @@ import type { LogEntry } from "../utils/log-collector";
22
22
  import {
23
23
  createRequestKey, getExistingRequest, storeRequest,
24
24
  removeRequest, cancelRequest, cancelAllRequests, hasActiveRequests,
25
+ storeRequestIdMapping, storeImmediateResultMapping,
26
+ getStatusUrlForRequestId, getResponseUrlForRequestId, removeRequestIdMapping,
25
27
  } from "./request-store";
26
28
 
27
29
  export class PrunaProvider implements IAIProvider {
@@ -87,7 +89,19 @@ export class PrunaProvider implements IAIProvider {
87
89
  const sessionId = generationLogCollector.startSession();
88
90
  generationLogCollector.log(sessionId, 'pruna-provider', `submitJob() for model: ${model}`);
89
91
  try {
90
- return await queueOps.submitJob(prunaModel, input, apiKey, sessionId);
92
+ const submission = await queueOps.submitJob(prunaModel, input, apiKey, sessionId);
93
+
94
+ // Store requestId -> statusUrl mapping for async jobs (requires polling)
95
+ if (submission.statusUrl) {
96
+ storeRequestIdMapping(submission.requestId, submission.statusUrl, model);
97
+ }
98
+
99
+ // Store requestId -> responseUrl mapping for immediate results (already complete)
100
+ if (submission.responseUrl) {
101
+ storeImmediateResultMapping(submission.requestId, submission.responseUrl, model);
102
+ }
103
+
104
+ return submission;
91
105
  } finally {
92
106
  generationLogCollector.endSession(sessionId);
93
107
  }
@@ -96,12 +110,45 @@ export class PrunaProvider implements IAIProvider {
96
110
  async getJobStatus(model: string, requestId: string): Promise<JobStatus> {
97
111
  const apiKey = this.validateInit();
98
112
  const prunaModel = this.validateModel(model);
113
+
114
+ // Check if this is an immediate result (already completed)
115
+ const responseUrl = getResponseUrlForRequestId(requestId);
116
+ if (responseUrl) {
117
+ // Result is already available
118
+ return {
119
+ status: "COMPLETED",
120
+ requestId,
121
+ };
122
+ }
123
+
124
+ // Look up statusUrl from requestId mapping (async job)
125
+ const statusUrl = getStatusUrlForRequestId(requestId);
126
+ if (statusUrl) {
127
+ return queueOps.getJobStatus(prunaModel, statusUrl, apiKey);
128
+ }
129
+
130
+ // Fallback: assume requestId is actually a statusUrl (for direct calls with statusUrl)
99
131
  return queueOps.getJobStatus(prunaModel, requestId, apiKey);
100
132
  }
101
133
 
102
134
  async getJobResult<T = unknown>(model: string, requestId: string): Promise<T> {
103
135
  const apiKey = this.validateInit();
104
136
  const prunaModel = this.validateModel(model);
137
+
138
+ // Check if this is an immediate result (already completed)
139
+ const responseUrl = getResponseUrlForRequestId(requestId);
140
+ if (responseUrl) {
141
+ // Return the immediate result
142
+ return { url: responseUrl } as T;
143
+ }
144
+
145
+ // Look up statusUrl from requestId mapping (async job)
146
+ const statusUrl = getStatusUrlForRequestId(requestId);
147
+ if (statusUrl) {
148
+ return queueOps.getJobResult<T>(prunaModel, statusUrl, apiKey);
149
+ }
150
+
151
+ // Fallback: assume requestId is actually a statusUrl (for direct calls with statusUrl)
105
152
  return queueOps.getJobResult<T>(prunaModel, requestId, apiKey);
106
153
  }
107
154
 
@@ -14,7 +14,9 @@ export interface ActiveRequest<T = unknown> {
14
14
 
15
15
  const STORE_KEY = "__PRUNA_PROVIDER_REQUESTS__";
16
16
  const TIMER_KEY = "__PRUNA_PROVIDER_CLEANUP_TIMER__";
17
+ const REQUEST_ID_KEY = "__PRUNA_PROVIDER_REQUEST_IDS__";
17
18
  type RequestStore = Map<string, ActiveRequest>;
19
+ type RequestIdMap = Map<string, { statusUrl?: string; responseUrl?: string; model: string }>;
18
20
 
19
21
  const CLEANUP_INTERVAL = 60_000;
20
22
  const MAX_REQUEST_AGE = 3_660_000; // 61 min — must exceed max allowed timeout (1 hour)
@@ -138,6 +140,43 @@ export function stopAutomaticCleanup(): void {
138
140
  stopCleanupTimer();
139
141
  }
140
142
 
143
+ // ─── Request ID to StatusUrl Mapping ───────────────────────────────────────
144
+
145
+ function getRequestIdMap(): RequestIdMap {
146
+ const globalObj = globalThis as Record<string, unknown>;
147
+ if (!globalObj[REQUEST_ID_KEY]) {
148
+ globalObj[REQUEST_ID_KEY] = new Map();
149
+ }
150
+ return globalObj[REQUEST_ID_KEY] as RequestIdMap;
151
+ }
152
+
153
+ export function storeRequestIdMapping(requestId: string, statusUrl: string, model: string): void {
154
+ getRequestIdMap().set(requestId, { statusUrl, model, responseUrl: undefined });
155
+ }
156
+
157
+ export function storeImmediateResultMapping(requestId: string, responseUrl: string, model: string): void {
158
+ getRequestIdMap().set(requestId, { statusUrl: undefined, model, responseUrl });
159
+ }
160
+
161
+ export function getStatusUrlForRequestId(requestId: string): string | undefined {
162
+ const mapping = getRequestIdMap().get(requestId);
163
+ return mapping?.statusUrl;
164
+ }
165
+
166
+ export function getResponseUrlForRequestId(requestId: string): string | undefined {
167
+ const mapping = getRequestIdMap().get(requestId);
168
+ return mapping?.responseUrl;
169
+ }
170
+
171
+ export function getModelForRequestId(requestId: string): string | undefined {
172
+ const mapping = getRequestIdMap().get(requestId);
173
+ return mapping?.model;
174
+ }
175
+
176
+ export function removeRequestIdMapping(requestId: string): void {
177
+ getRequestIdMap().delete(requestId);
178
+ }
179
+
141
180
  // Clear any leftover timer on module load (hot reload safety)
142
181
  if (typeof globalThis !== "undefined") {
143
182
  const existingTimer = getCleanupTimer();