@aj-archipelago/cortex 1.1.14 → 1.1.16

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.
@@ -1,8 +1,9 @@
1
1
  import { selectEndpoint } from './requestExecutor.js';
2
2
 
3
3
  class CortexRequest {
4
- constructor( { url, data, params, headers, cache, model, pathwayResolver, selectedEndpoint, stream } = {}) {
4
+ constructor( { url, urlSuffix, data, params, headers, cache, model, pathwayResolver, selectedEndpoint, stream } = {}) {
5
5
  this._url = url || '';
6
+ this._urlSuffix = urlSuffix || '';
6
7
  this._data = data || {};
7
8
  this._params = params || {};
8
9
  this._headers = headers || {};
@@ -35,13 +36,22 @@ class CortexRequest {
35
36
 
36
37
  // url getter and setter
37
38
  get url() {
38
- return this._url;
39
+ return this._url + this._urlSuffix;
39
40
  }
40
41
 
41
42
  set url(value) {
42
43
  this._url = value;
43
44
  }
44
45
 
46
+ // urlSuffix getter and setter
47
+ get urlSuffix() {
48
+ return this._urlSuffix;
49
+ }
50
+
51
+ set urlSuffix(value) {
52
+ this._urlSuffix = value;
53
+ }
54
+
45
55
  // method getter and setter
46
56
  get method() {
47
57
  return this._method;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aj-archipelago/cortex",
3
- "version": "1.1.14",
3
+ "version": "1.1.16",
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": {
@@ -30,5 +30,7 @@ export default {
30
30
  executePathway: undefined,
31
31
  // Set the temperature to 0 to favor more deterministic output when generating entity extraction.
32
32
  temperature: 0.9,
33
+ // Require a valid JSON response from the model
34
+ json: false,
33
35
  };
34
36
 
package/server/parser.js CHANGED
@@ -49,6 +49,28 @@ const isNumberedList = (data) => {
49
49
  return numberedListPattern.test(data.trim());
50
50
  }
51
51
 
52
+ function parseJson(str) {
53
+ try {
54
+ const start = Math.min(
55
+ str.indexOf('{') !== -1 ? str.indexOf('{') : Infinity,
56
+ str.indexOf('[') !== -1 ? str.indexOf('[') : Infinity
57
+ );
58
+
59
+ const end = Math.max(
60
+ str.lastIndexOf('}') !== -1 ? str.lastIndexOf('}') + 1 : 0,
61
+ str.lastIndexOf(']') !== -1 ? str.lastIndexOf(']') + 1 : 0
62
+ );
63
+
64
+ const jsonStr = str.slice(start, end);
65
+ // eslint-disable-next-line no-unused-vars
66
+ const json = JSON.parse(jsonStr);
67
+ return jsonStr;
68
+ } catch (error) {
69
+ logger.warn(`Pathway requires JSON format result. Failed to parse JSON: ${error.message}`);
70
+ return null;
71
+ }
72
+ }
73
+
52
74
  export {
53
75
  regexParser,
54
76
  parseNumberedList,
@@ -56,4 +78,5 @@ export {
56
78
  parseCommaSeparatedList,
57
79
  isCommaSeparatedList,
58
80
  isNumberedList,
81
+ parseJson
59
82
  };
@@ -211,8 +211,19 @@ class PathwayResolver {
211
211
  // Save the context before processing the request
212
212
  const savedContextStr = JSON.stringify(this.savedContext);
213
213
 
214
- // Process the request
215
- const data = await this.processRequest(args);
214
+ const MAX_RETRIES = 3;
215
+ let data = null;
216
+
217
+ for (let retries = 0; retries < MAX_RETRIES; retries++) {
218
+ data = await this.processRequest(args);
219
+ data = this.responseParser.parse(data);
220
+
221
+ if (data !== null && data !== undefined) {
222
+ break;
223
+ }
224
+
225
+ logger.warn(`Bad pathway result - retrying pathway. Attempt ${retries + 1} of ${MAX_RETRIES}`);
226
+ }
216
227
 
217
228
  // Update saved context if it has changed, generating a new contextId if necessary
218
229
  if (savedContextStr !== JSON.stringify(this.savedContext)) {
@@ -220,8 +231,7 @@ class PathwayResolver {
220
231
  setv && setv(this.savedContextId, this.savedContext);
221
232
  }
222
233
 
223
- // Return the result
224
- return this.responseParser.parse(data);
234
+ return data;
225
235
  }
226
236
 
227
237
  // Add a warning and log it
@@ -1,4 +1,4 @@
1
- import { parseNumberedList, parseNumberedObjectList, parseCommaSeparatedList, isCommaSeparatedList, isNumberedList } from './parser.js';
1
+ import { parseNumberedList, parseNumberedObjectList, parseCommaSeparatedList, isCommaSeparatedList, isNumberedList, parseJson } from './parser.js';
2
2
 
3
3
  class PathwayResponseParser {
4
4
  constructor(pathway) {
@@ -22,6 +22,10 @@ class PathwayResponseParser {
22
22
  return [data];
23
23
  }
24
24
 
25
+ if (this.pathway.json) {
26
+ return parseJson(data);
27
+ }
28
+
25
29
  return data;
26
30
  }
27
31
  }
@@ -79,7 +79,7 @@ class Claude3VertexPlugin extends OpenAIVisionPlugin {
79
79
  cortexRequest.data = { ...(cortexRequest.data || {}), ...requestParameters };
80
80
  cortexRequest.params = {}; // query params
81
81
  cortexRequest.stream = stream;
82
- cortexRequest.url = cortexRequest.stream ? `${cortexRequest.url}:streamRawPredict` : `${cortexRequest.url}:rawPredict`;
82
+ cortexRequest.urlSuffix = cortexRequest.stream ? ':streamRawPredict' : ':rawPredict';
83
83
 
84
84
  const gcpAuthTokenHelper = this.config.get('gcpAuthTokenHelper');
85
85
  const authToken = await gcpAuthTokenHelper.getAccessToken();
@@ -335,7 +335,7 @@ try {
335
335
 
336
336
  totalCount = mediaChunks.length + 1; // total number of chunks that will be processed
337
337
 
338
- const batchSize = 2;
338
+ const batchSize = 4;
339
339
  sendProgress();
340
340
 
341
341
  for (let i = 0; i < uris.length; i += batchSize) {