@umituz/react-native-ai-pruna-provider 1.0.42 → 1.0.44
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.
|
|
3
|
+
"version": "1.0.44",
|
|
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,7 +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,
|
|
25
|
+
storeRequestIdMapping, storeImmediateResultMapping,
|
|
26
|
+
getStatusUrlForRequestId, getResponseUrlForRequestId, removeRequestIdMapping,
|
|
26
27
|
} from "./request-store";
|
|
27
28
|
|
|
28
29
|
export class PrunaProvider implements IAIProvider {
|
|
@@ -86,15 +87,26 @@ export class PrunaProvider implements IAIProvider {
|
|
|
86
87
|
const apiKey = this.validateInit();
|
|
87
88
|
const prunaModel = this.validateModel(model);
|
|
88
89
|
const sessionId = generationLogCollector.startSession();
|
|
89
|
-
generationLogCollector.log(sessionId, 'pruna-provider', `submitJob()
|
|
90
|
+
generationLogCollector.log(sessionId, 'pruna-provider', `submitJob() START model: ${model}`);
|
|
90
91
|
try {
|
|
91
92
|
const submission = await queueOps.submitJob(prunaModel, input, apiKey, sessionId);
|
|
92
93
|
|
|
93
|
-
//
|
|
94
|
-
if (submission.
|
|
94
|
+
// Log response type
|
|
95
|
+
if (submission.responseUrl) {
|
|
96
|
+
generationLogCollector.log(sessionId, 'pruna-provider', `submitJob() IMMEDIATE RESULT - requestId: ${submission.requestId}, responseUrl: ${submission.responseUrl.substring(0, 80)}...`);
|
|
97
|
+
// Store requestId -> responseUrl mapping for immediate results (already complete)
|
|
98
|
+
storeImmediateResultMapping(submission.requestId, submission.responseUrl, model);
|
|
99
|
+
generationLogCollector.log(sessionId, 'pruna-provider', `submitJob() Stored immediate result mapping: ${submission.requestId}`);
|
|
100
|
+
} else if (submission.statusUrl) {
|
|
101
|
+
generationLogCollector.log(sessionId, 'pruna-provider', `submitJob() ASYNC JOB - requestId: ${submission.requestId}, statusUrl: ${submission.statusUrl.substring(0, 80)}...`);
|
|
102
|
+
// Store requestId -> statusUrl mapping for async jobs (requires polling)
|
|
95
103
|
storeRequestIdMapping(submission.requestId, submission.statusUrl, model);
|
|
104
|
+
generationLogCollector.log(sessionId, 'pruna-provider', `submitJob() Stored async job mapping: ${submission.requestId}`);
|
|
105
|
+
} else {
|
|
106
|
+
generationLogCollector.warn(sessionId, 'pruna-provider', `submitJob() WARNING - No responseUrl or statusUrl in submission`);
|
|
96
107
|
}
|
|
97
108
|
|
|
109
|
+
generationLogCollector.log(sessionId, 'pruna-provider', `submitJob() COMPLETE - returning submission with requestId: ${submission.requestId}`);
|
|
98
110
|
return submission;
|
|
99
111
|
} finally {
|
|
100
112
|
generationLogCollector.endSession(sessionId);
|
|
@@ -104,29 +116,82 @@ export class PrunaProvider implements IAIProvider {
|
|
|
104
116
|
async getJobStatus(model: string, requestId: string): Promise<JobStatus> {
|
|
105
117
|
const apiKey = this.validateInit();
|
|
106
118
|
const prunaModel = this.validateModel(model);
|
|
119
|
+
const sessionId = generationLogCollector.startSession();
|
|
120
|
+
generationLogCollector.log(sessionId, 'pruna-provider', `getJobStatus() START - model: ${model}, requestId: ${requestId}`);
|
|
107
121
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
122
|
+
try {
|
|
123
|
+
// Check if this is an immediate result (already completed)
|
|
124
|
+
const responseUrl = getResponseUrlForRequestId(requestId);
|
|
125
|
+
if (responseUrl) {
|
|
126
|
+
generationLogCollector.log(sessionId, 'pruna-provider', `getJobStatus() FOUND immediate result for ${requestId} - returning COMPLETED`);
|
|
127
|
+
generationLogCollector.endSession(sessionId);
|
|
128
|
+
// Result is already available
|
|
129
|
+
return {
|
|
130
|
+
status: "COMPLETED",
|
|
131
|
+
requestId,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Look up statusUrl from requestId mapping (async job)
|
|
136
|
+
const statusUrl = getStatusUrlForRequestId(requestId);
|
|
137
|
+
if (statusUrl) {
|
|
138
|
+
generationLogCollector.log(sessionId, 'pruna-provider', `getJobStatus() FOUND async job for ${requestId} - polling statusUrl: ${statusUrl.substring(0, 80)}...`);
|
|
139
|
+
const result = await queueOps.getJobStatus(prunaModel, statusUrl, apiKey);
|
|
140
|
+
generationLogCollector.log(sessionId, 'pruna-provider', `getJobStatus() Poll result: ${result.status}`);
|
|
141
|
+
generationLogCollector.endSession(sessionId);
|
|
142
|
+
return result;
|
|
143
|
+
}
|
|
113
144
|
|
|
114
|
-
|
|
115
|
-
|
|
145
|
+
// Fallback: assume requestId is actually a statusUrl (for direct calls with statusUrl)
|
|
146
|
+
generationLogCollector.log(sessionId, 'pruna-provider', `getJobStatus() NO mapping found - treating ${requestId} as statusUrl directly`);
|
|
147
|
+
const result = await queueOps.getJobStatus(prunaModel, requestId, apiKey);
|
|
148
|
+
generationLogCollector.log(sessionId, 'pruna-provider', `getJobStatus() Direct poll result: ${result.status}`);
|
|
149
|
+
generationLogCollector.endSession(sessionId);
|
|
150
|
+
return result;
|
|
151
|
+
} catch (error) {
|
|
152
|
+
generationLogCollector.error(sessionId, 'pruna-provider', `getJobStatus() ERROR: ${error instanceof Error ? error.message : String(error)}`);
|
|
153
|
+
generationLogCollector.endSession(sessionId);
|
|
154
|
+
throw error;
|
|
155
|
+
}
|
|
116
156
|
}
|
|
117
157
|
|
|
118
158
|
async getJobResult<T = unknown>(model: string, requestId: string): Promise<T> {
|
|
119
159
|
const apiKey = this.validateInit();
|
|
120
160
|
const prunaModel = this.validateModel(model);
|
|
161
|
+
const sessionId = generationLogCollector.startSession();
|
|
162
|
+
generationLogCollector.log(sessionId, 'pruna-provider', `getJobResult() START - model: ${model}, requestId: ${requestId}`);
|
|
121
163
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
164
|
+
try {
|
|
165
|
+
// Check if this is an immediate result (already completed)
|
|
166
|
+
const responseUrl = getResponseUrlForRequestId(requestId);
|
|
167
|
+
if (responseUrl) {
|
|
168
|
+
generationLogCollector.log(sessionId, 'pruna-provider', `getJobResult() FOUND immediate result for ${requestId} - returning url: ${responseUrl.substring(0, 80)}...`);
|
|
169
|
+
generationLogCollector.endSession(sessionId);
|
|
170
|
+
// Return the immediate result
|
|
171
|
+
return { url: responseUrl } as T;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Look up statusUrl from requestId mapping (async job)
|
|
175
|
+
const statusUrl = getStatusUrlForRequestId(requestId);
|
|
176
|
+
if (statusUrl) {
|
|
177
|
+
generationLogCollector.log(sessionId, 'pruna-provider', `getJobResult() FOUND async job for ${requestId} - fetching from statusUrl: ${statusUrl.substring(0, 80)}...`);
|
|
178
|
+
const result = await queueOps.getJobResult<T>(prunaModel, statusUrl, apiKey);
|
|
179
|
+
generationLogCollector.log(sessionId, 'pruna-provider', `getJobResult() Fetch complete`);
|
|
180
|
+
generationLogCollector.endSession(sessionId);
|
|
181
|
+
return result;
|
|
182
|
+
}
|
|
127
183
|
|
|
128
|
-
|
|
129
|
-
|
|
184
|
+
// Fallback: assume requestId is actually a statusUrl (for direct calls with statusUrl)
|
|
185
|
+
generationLogCollector.log(sessionId, 'pruna-provider', `getJobResult() NO mapping found - treating ${requestId} as statusUrl directly`);
|
|
186
|
+
const result = await queueOps.getJobResult<T>(prunaModel, requestId, apiKey);
|
|
187
|
+
generationLogCollector.log(sessionId, 'pruna-provider', `getJobResult() Direct fetch complete`);
|
|
188
|
+
generationLogCollector.endSession(sessionId);
|
|
189
|
+
return result;
|
|
190
|
+
} catch (error) {
|
|
191
|
+
generationLogCollector.error(sessionId, 'pruna-provider', `getJobResult() ERROR: ${error instanceof Error ? error.message : String(error)}`);
|
|
192
|
+
generationLogCollector.endSession(sessionId);
|
|
193
|
+
throw error;
|
|
194
|
+
}
|
|
130
195
|
}
|
|
131
196
|
|
|
132
197
|
async subscribe<T = unknown>(
|
|
@@ -16,7 +16,7 @@ const STORE_KEY = "__PRUNA_PROVIDER_REQUESTS__";
|
|
|
16
16
|
const TIMER_KEY = "__PRUNA_PROVIDER_CLEANUP_TIMER__";
|
|
17
17
|
const REQUEST_ID_KEY = "__PRUNA_PROVIDER_REQUEST_IDS__";
|
|
18
18
|
type RequestStore = Map<string, ActiveRequest>;
|
|
19
|
-
type RequestIdMap = Map<string, { statusUrl
|
|
19
|
+
type RequestIdMap = Map<string, { statusUrl?: string; responseUrl?: string; model: string }>;
|
|
20
20
|
|
|
21
21
|
const CLEANUP_INTERVAL = 60_000;
|
|
22
22
|
const MAX_REQUEST_AGE = 3_660_000; // 61 min — must exceed max allowed timeout (1 hour)
|
|
@@ -151,7 +151,11 @@ function getRequestIdMap(): RequestIdMap {
|
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
export function storeRequestIdMapping(requestId: string, statusUrl: string, model: string): void {
|
|
154
|
-
getRequestIdMap().set(requestId, { statusUrl, model });
|
|
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 });
|
|
155
159
|
}
|
|
156
160
|
|
|
157
161
|
export function getStatusUrlForRequestId(requestId: string): string | undefined {
|
|
@@ -159,6 +163,11 @@ export function getStatusUrlForRequestId(requestId: string): string | undefined
|
|
|
159
163
|
return mapping?.statusUrl;
|
|
160
164
|
}
|
|
161
165
|
|
|
166
|
+
export function getResponseUrlForRequestId(requestId: string): string | undefined {
|
|
167
|
+
const mapping = getRequestIdMap().get(requestId);
|
|
168
|
+
return mapping?.responseUrl;
|
|
169
|
+
}
|
|
170
|
+
|
|
162
171
|
export function getModelForRequestId(requestId: string): string | undefined {
|
|
163
172
|
const mapping = getRequestIdMap().get(requestId);
|
|
164
173
|
return mapping?.model;
|