@aj-archipelago/cortex 1.1.11 → 1.1.12

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": "@aj-archipelago/cortex",
3
- "version": "1.1.11",
3
+ "version": "1.1.12",
4
4
  "description": "Cortex is a GraphQL API for AI. It provides a simple, extensible interface for using AI services from OpenAI, Azure and others.",
5
5
  "private": false,
6
6
  "repository": {
@@ -223,7 +223,24 @@ class OpenAIWhisperPlugin extends ModelPlugin {
223
223
  cortexRequest.url = WHISPER_TS_API_URL;
224
224
  cortexRequest.data = tsparams;
225
225
 
226
- const res = await this.executeRequest(cortexRequest);
226
+ const MAX_RETRIES = 3;
227
+ let attempt = 0;
228
+ let res = null;
229
+ while(attempt < MAX_RETRIES){
230
+ sendProgress(true, true);
231
+ try {
232
+ res = await this.executeRequest(cortexRequest);
233
+ if(res.statusCode && res.statusCode >= 400){
234
+ throw new Error(res.message || 'An error occurred.');
235
+ }
236
+ break;
237
+ }
238
+ catch(err){
239
+ logger.warn(`Error calling timestamped API: ${err}. Retrying ${attempt+1} of ${MAX_RETRIES}...`);
240
+ attempt++;
241
+ }
242
+ }
243
+
227
244
  if (res.statusCode && res.statusCode >= 400) {
228
245
  throw new Error(res.message || 'An error occurred.');
229
246
  }
@@ -241,18 +258,23 @@ class OpenAIWhisperPlugin extends ModelPlugin {
241
258
  let completedCount = 0;
242
259
  let partialCount = 0;
243
260
  const { requestId } = pathwayResolver;
261
+ let partialRatio = 0;
262
+
263
+ const sendProgress = (partial=false, resetCount=false) => {
264
+ partialCount = resetCount ? 0 : partialCount;
244
265
 
245
- const MAXPARTIALCOUNT = 60;
246
- const sendProgress = (partial=false) => {
247
266
  if(partial){
248
- partialCount = Math.min(partialCount + 1, MAXPARTIALCOUNT-1);
249
- }else {
267
+ partialCount++;
268
+ const increment = 0.02 / Math.log2(partialCount + 1); // logarithmic diminishing increment
269
+ partialRatio = Math.min(partialRatio + increment, 0.99); // limit to 0.99
270
+ }else{
250
271
  partialCount = 0;
272
+ partialRatio = 0;
251
273
  completedCount++;
252
274
  }
253
- if (completedCount >= totalCount) return;
275
+ if(completedCount >= totalCount) return;
254
276
 
255
- const progress = (partialCount / MAXPARTIALCOUNT + completedCount) / totalCount;
277
+ const progress = (completedCount + partialRatio) / totalCount;
256
278
  logger.info(`Progress for ${requestId}: ${progress}`);
257
279
 
258
280
  publishRequestProgress({
@@ -262,57 +284,64 @@ class OpenAIWhisperPlugin extends ModelPlugin {
262
284
  });
263
285
  }
264
286
 
265
- async function processURI(uri) {
266
- let result = null;
267
- let _promise = null;
268
- let errorOccurred = false;
269
-
270
- const useTS = WHISPER_TS_API_URL && (wordTimestamped || highlightWords);
271
-
272
- if (useTS) {
273
- _promise = processTS;
274
- } else {
275
- _promise = processChunk;
276
- }
277
-
278
- _promise(uri).then((ts) => {
279
- result = ts;
280
- }).catch((err) => {
281
- logger.error(`Error occurred while processing URI: ${err}`);
282
- errorOccurred = err;
283
- });
284
-
285
- while(result === null && !errorOccurred) {
286
- sendProgress(true);
287
- await new Promise(r => setTimeout(r, 3000));
288
- }
287
+ async function processURI(uri) {
288
+ let result = null;
289
+ let _promise = null;
290
+ let errorOccurred = false;
289
291
 
290
- if(errorOccurred) {
291
- throw errorOccurred;
292
- }
293
-
294
- return result;
295
- }
292
+ const intervalId = setInterval(() => sendProgress(true), 3000);
296
293
 
297
- try {
298
- const uris = await this.getMediaChunks(file, requestId); // array of remote file uris
299
- if (!uris || !uris.length) {
300
- throw new Error(`Error in getting chunks from media helper for file ${file}`);
301
- }
302
- totalCount = uris.length + 1; // total number of chunks that will be processed
294
+ const useTS = WHISPER_TS_API_URL && (wordTimestamped || highlightWords);
303
295
 
304
- // sequential process of chunks
305
- for (const uri of uris) {
306
- sendProgress();
307
- const ts = await processURI(uri);
308
- result.push(ts);
309
- }
296
+ if (useTS) {
297
+ _promise = processTS;
298
+ } else {
299
+ _promise = processChunk;
300
+ }
310
301
 
311
- } catch (error) {
312
- const errMsg = `Transcribe error: ${error?.response?.data || error?.message || error}`;
313
- logger.error(errMsg);
314
- return errMsg;
302
+ await _promise(uri).then((ts) => {
303
+ result = ts;
304
+ }).catch((err) => {
305
+ errorOccurred = err;
306
+ }).finally(() => {
307
+ clearInterval(intervalId);
308
+ sendProgress();
309
+ });
310
+
311
+ if(errorOccurred) {
312
+ throw errorOccurred;
313
+ }
314
+
315
+ return result;
316
+ }
317
+
318
+ try {
319
+ const uris = await this.getMediaChunks(file, requestId);
320
+
321
+ if (!uris || !uris.length) {
322
+ throw new Error(`Error in getting chunks from media helper for file ${file}`);
323
+ }
324
+
325
+ totalCount = uris.length + 1; // total number of chunks that will be processed
326
+
327
+ const batchSize = 2;
328
+ sendProgress();
329
+
330
+ for (let i = 0; i < uris.length; i += batchSize) {
331
+ const currentBatchURIs = uris.slice(i, i + batchSize);
332
+ const promisesToProcess = currentBatchURIs.map(uri => processURI(uri));
333
+ const results = await Promise.all(promisesToProcess);
334
+
335
+ for(const res of results) {
336
+ result.push(res);
315
337
  }
338
+ }
339
+
340
+ } catch (error) {
341
+ const errMsg = `Transcribe error: ${error?.response?.data || error?.message || error}`;
342
+ logger.error(errMsg);
343
+ return errMsg;
344
+ }
316
345
  finally {
317
346
  try {
318
347
  for (const chunk of chunks) {