@aj-archipelago/cortex 1.1.2 → 1.1.4-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.
Files changed (64) hide show
  1. package/.eslintignore +3 -3
  2. package/README.md +16 -3
  3. package/config.js +32 -8
  4. package/{helper_apps/CortexFileHandler → helper-apps/cortex-file-handler}/Dockerfile +1 -1
  5. package/{helper_apps/CortexFileHandler → helper-apps/cortex-file-handler}/fileChunker.js +1 -0
  6. package/{helper_apps/CortexFileHandler → helper-apps/cortex-file-handler}/package-lock.json +25 -216
  7. package/{helper_apps/CortexFileHandler → helper-apps/cortex-file-handler}/package.json +2 -2
  8. package/helper-apps/cortex-whisper-wrapper/.dockerignore +27 -0
  9. package/helper-apps/cortex-whisper-wrapper/Dockerfile +32 -0
  10. package/helper-apps/cortex-whisper-wrapper/app.py +104 -0
  11. package/helper-apps/cortex-whisper-wrapper/docker-compose.debug.yml +12 -0
  12. package/helper-apps/cortex-whisper-wrapper/docker-compose.yml +10 -0
  13. package/helper-apps/cortex-whisper-wrapper/models/.gitkeep +0 -0
  14. package/helper-apps/cortex-whisper-wrapper/requirements.txt +5 -0
  15. package/lib/cortexRequest.js +117 -0
  16. package/lib/pathwayTools.js +2 -1
  17. package/lib/redisSubscription.js +44 -28
  18. package/lib/requestExecutor.js +360 -0
  19. package/lib/requestMonitor.js +131 -28
  20. package/package.json +2 -1
  21. package/pathways/summary.js +3 -3
  22. package/server/graphql.js +4 -4
  23. package/server/{pathwayPrompter.js → modelExecutor.js} +24 -21
  24. package/server/pathwayResolver.js +25 -20
  25. package/server/plugins/azureCognitivePlugin.js +25 -20
  26. package/server/plugins/azureTranslatePlugin.js +6 -10
  27. package/server/plugins/cohereGeneratePlugin.js +5 -12
  28. package/server/plugins/cohereSummarizePlugin.js +5 -12
  29. package/server/plugins/localModelPlugin.js +3 -3
  30. package/server/plugins/modelPlugin.js +18 -12
  31. package/server/plugins/openAiChatExtensionPlugin.js +5 -5
  32. package/server/plugins/openAiChatPlugin.js +8 -10
  33. package/server/plugins/openAiCompletionPlugin.js +9 -12
  34. package/server/plugins/openAiDallE3Plugin.js +14 -31
  35. package/server/plugins/openAiEmbeddingsPlugin.js +6 -9
  36. package/server/plugins/openAiImagePlugin.js +19 -15
  37. package/server/plugins/openAiWhisperPlugin.js +167 -99
  38. package/server/plugins/palmChatPlugin.js +9 -10
  39. package/server/plugins/palmCodeCompletionPlugin.js +2 -2
  40. package/server/plugins/palmCompletionPlugin.js +11 -12
  41. package/server/resolver.js +2 -2
  42. package/server/rest.js +4 -5
  43. package/server/subscriptions.js +2 -0
  44. package/tests/config.test.js +1 -1
  45. package/tests/mocks.js +5 -0
  46. package/tests/modelPlugin.test.js +3 -10
  47. package/tests/openAiChatPlugin.test.js +9 -8
  48. package/tests/openai_api.test.js +3 -3
  49. package/tests/palmChatPlugin.test.js +1 -1
  50. package/tests/palmCompletionPlugin.test.js +1 -1
  51. package/tests/pathwayResolver.test.js +2 -1
  52. package/tests/requestMonitor.test.js +94 -0
  53. package/tests/{requestDurationEstimator.test.js → requestMonitorDurationEstimator.test.js} +21 -17
  54. package/tests/truncateMessages.test.js +1 -1
  55. package/lib/request.js +0 -260
  56. package/lib/requestDurationEstimator.js +0 -90
  57. /package/{helper_apps/CortexFileHandler → helper-apps/cortex-file-handler}/blobHandler.js +0 -0
  58. /package/{helper_apps/CortexFileHandler → helper-apps/cortex-file-handler}/docHelper.js +0 -0
  59. /package/{helper_apps/CortexFileHandler → helper-apps/cortex-file-handler}/function.json +0 -0
  60. /package/{helper_apps/CortexFileHandler → helper-apps/cortex-file-handler}/helper.js +0 -0
  61. /package/{helper_apps/CortexFileHandler → helper-apps/cortex-file-handler}/index.js +0 -0
  62. /package/{helper_apps/CortexFileHandler → helper-apps/cortex-file-handler}/localFileHandler.js +0 -0
  63. /package/{helper_apps/CortexFileHandler → helper-apps/cortex-file-handler}/redis.js +0 -0
  64. /package/{helper_apps/CortexFileHandler → helper-apps/cortex-file-handler}/start.js +0 -0
@@ -1,4 +1,6 @@
1
- // PathwayPrompter.js
1
+ // ModelExecutor.js
2
+ import CortexRequest from '../lib/cortexRequest.js';
3
+
2
4
  import OpenAIChatPlugin from './plugins/openAiChatPlugin.js';
3
5
  import OpenAICompletionPlugin from './plugins/openAiCompletionPlugin.js';
4
6
  import AzureTranslatePlugin from './plugins/azureTranslatePlugin.js';
@@ -16,59 +18,59 @@ import OpenAIImagePlugin from './plugins/openAiImagePlugin.js';
16
18
  import OpenAIDallE3Plugin from './plugins/openAiDallE3Plugin.js';
17
19
  import OpenAIVisionPlugin from './plugins/openAiVisionPlugin.js';
18
20
 
19
- class PathwayPrompter {
20
- constructor(config, pathway, modelName, model) {
21
+ class ModelExecutor {
22
+ constructor(pathway, model) {
21
23
 
22
24
  let plugin;
23
25
 
24
26
  switch (model.type) {
25
27
  case 'OPENAI-CHAT':
26
- plugin = new OpenAIChatPlugin(config, pathway, modelName, model);
28
+ plugin = new OpenAIChatPlugin(pathway, model);
27
29
  break;
28
30
  case 'OPENAI-DALLE2':
29
- plugin = new OpenAIImagePlugin(config, pathway, modelName, model);
31
+ plugin = new OpenAIImagePlugin(pathway, model);
30
32
  break;
31
33
  case 'OPENAI-DALLE3':
32
- plugin = new OpenAIDallE3Plugin(config, pathway, modelName, model);
34
+ plugin = new OpenAIDallE3Plugin(pathway, model);
33
35
  break;
34
36
  case 'OPENAI-CHAT-EXTENSION':
35
- plugin = new OpenAIChatExtensionPlugin(config, pathway, modelName, model);
37
+ plugin = new OpenAIChatExtensionPlugin(pathway, model);
36
38
  break;
37
39
  case 'AZURE-TRANSLATE':
38
- plugin = new AzureTranslatePlugin(config, pathway, modelName, model);
40
+ plugin = new AzureTranslatePlugin(pathway, model);
39
41
  break;
40
42
  case 'AZURE-COGNITIVE':
41
- plugin = new AzureCognitivePlugin(config, pathway, modelName, model);
43
+ plugin = new AzureCognitivePlugin(pathway, model);
42
44
  break;
43
45
  case 'OPENAI-EMBEDDINGS':
44
- plugin = new OpenAiEmbeddingsPlugin(config, pathway, modelName, model);
46
+ plugin = new OpenAiEmbeddingsPlugin(pathway, model);
45
47
  break;
46
48
  case 'OPENAI-COMPLETION':
47
- plugin = new OpenAICompletionPlugin(config, pathway, modelName, model);
49
+ plugin = new OpenAICompletionPlugin(pathway, model);
48
50
  break;
49
51
  case 'OPENAI-WHISPER':
50
- plugin = new OpenAIWhisperPlugin(config, pathway, modelName, model);
52
+ plugin = new OpenAIWhisperPlugin(pathway, model);
51
53
  break;
52
54
  case 'LOCAL-CPP-MODEL':
53
- plugin = new LocalModelPlugin(config, pathway, modelName, model);
55
+ plugin = new LocalModelPlugin(pathway, model);
54
56
  break;
55
57
  case 'PALM-CHAT':
56
- plugin = new PalmChatPlugin(config, pathway, modelName, model);
58
+ plugin = new PalmChatPlugin(pathway, model);
57
59
  break;
58
60
  case 'PALM-COMPLETION':
59
- plugin = new PalmCompletionPlugin(config, pathway, modelName, model);
61
+ plugin = new PalmCompletionPlugin(pathway, model);
60
62
  break;
61
63
  case 'PALM-CODE-COMPLETION':
62
- plugin = new PalmCodeCompletionPlugin(config, pathway, modelName, model);
64
+ plugin = new PalmCodeCompletionPlugin(pathway, model);
63
65
  break;
64
66
  case 'COHERE-GENERATE':
65
- plugin = new CohereGeneratePlugin(config, pathway, modelName, model);
67
+ plugin = new CohereGeneratePlugin(pathway, model);
66
68
  break;
67
69
  case 'COHERE-SUMMARIZE':
68
- plugin = new CohereSummarizePlugin(config, pathway, modelName, model);
70
+ plugin = new CohereSummarizePlugin(pathway, model);
69
71
  break;
70
72
  case 'OPENAI-VISION':
71
- plugin = new OpenAIVisionPlugin(config, pathway, modelName, model);
73
+ plugin = new OpenAIVisionPlugin(pathway, model);
72
74
  break;
73
75
  default:
74
76
  throw new Error(`Unsupported model type: ${model.type}`);
@@ -78,10 +80,11 @@ class PathwayPrompter {
78
80
  }
79
81
 
80
82
  async execute(text, parameters, prompt, pathwayResolver) {
81
- return await this.plugin.execute(text, parameters, prompt, pathwayResolver);
83
+ const cortexRequest = new CortexRequest({ pathwayResolver });
84
+ return await this.plugin.execute(text, parameters, prompt, cortexRequest);
82
85
  }
83
86
  }
84
87
 
85
88
  export {
86
- PathwayPrompter
89
+ ModelExecutor
87
90
  };
@@ -1,4 +1,5 @@
1
- import { PathwayPrompter } from './pathwayPrompter.js';
1
+ import { ModelExecutor } from './modelExecutor.js';
2
+ import { modelEndpoints } from '../lib/requestExecutor.js';
2
3
  // eslint-disable-next-line import/no-extraneous-dependencies
3
4
  import { v4 as uuidv4 } from 'uuid';
4
5
  import { encode } from 'gpt-3-encoder';
@@ -14,7 +15,9 @@ import logger from '../lib/logger.js';
14
15
  const modelTypesExcludedFromProgressUpdates = ['OPENAI-DALLE2', 'OPENAI-DALLE3'];
15
16
 
16
17
  class PathwayResolver {
17
- constructor({ config, pathway, args }) {
18
+ // Optional endpoints override parameter is for testing purposes
19
+ constructor({ config, pathway, args, endpoints }) {
20
+ this.endpoints = endpoints || modelEndpoints;
18
21
  this.config = config;
19
22
  this.pathway = pathway;
20
23
  this.args = args;
@@ -28,8 +31,8 @@ class PathwayResolver {
28
31
  args?.model,
29
32
  pathway.inputParameters?.model,
30
33
  config.get('defaultModelName')
31
- ].find(modelName => modelName && Object.prototype.hasOwnProperty.call(config.get('models'), modelName));
32
- this.model = config.get('models')[this.modelName];
34
+ ].find(modelName => modelName && Object.prototype.hasOwnProperty.call(this.endpoints, modelName));
35
+ this.model = this.endpoints[this.modelName];
33
36
 
34
37
  if (!this.model) {
35
38
  throw new Error(`Model ${this.modelName} not found in config`);
@@ -47,7 +50,7 @@ class PathwayResolver {
47
50
 
48
51
  this.previousResult = '';
49
52
  this.prompts = [];
50
- this.pathwayPrompter = new PathwayPrompter(this.config, this.pathway, this.modelName, this.model);
53
+ this.modelExecutor = new ModelExecutor(this.pathway, this.model);
51
54
 
52
55
  Object.defineProperty(this, 'pathwayPrompt', {
53
56
  get() {
@@ -70,7 +73,7 @@ class PathwayResolver {
70
73
  // the graphql subscription to send progress updates to the client. Most of
71
74
  // the time the client will be an external client, but it could also be the
72
75
  // Cortex REST api code.
73
- async asyncResolve(args, useRedis = true) {
76
+ async asyncResolve(args) {
74
77
  const MAX_RETRY_COUNT = 3;
75
78
  let attempt = 0;
76
79
  let streamErrorOccurred = false;
@@ -88,7 +91,7 @@ class PathwayResolver {
88
91
  requestId: this.requestId,
89
92
  progress: completedCount / totalCount,
90
93
  data: JSON.stringify(responseData),
91
- }, useRedis);
94
+ });
92
95
  }
93
96
  } else {
94
97
  try {
@@ -140,7 +143,7 @@ class PathwayResolver {
140
143
 
141
144
  try {
142
145
  //logger.info(`Publishing stream message to requestId ${this.requestId}: ${message}`);
143
- publishRequestProgress(requestProgress, useRedis);
146
+ publishRequestProgress(requestProgress);
144
147
  } catch (error) {
145
148
  logger.error(`Could not publish the stream message: "${messageBuffer}", ${error}`);
146
149
  }
@@ -255,7 +258,7 @@ class PathwayResolver {
255
258
  }
256
259
 
257
260
  truncate(str, n) {
258
- if (this.pathwayPrompter.plugin.promptParameters.truncateFromFront) {
261
+ if (this.modelExecutor.plugin.promptParameters.truncateFromFront) {
259
262
  return getFirstNToken(str, n);
260
263
  }
261
264
  return getLastNToken(str, n);
@@ -263,7 +266,7 @@ class PathwayResolver {
263
266
 
264
267
  async summarizeIfEnabled({ text, ...parameters }) {
265
268
  if (this.pathway.useInputSummarization) {
266
- return await callPathway(this.config, 'summary', { ...this.args, ...parameters, targetLength: 0});
269
+ return await callPathway('summary', { ...this.args, ...parameters, targetLength: 0});
267
270
  }
268
271
  return text;
269
272
  }
@@ -271,15 +274,15 @@ class PathwayResolver {
271
274
  // Calculate the maximum token length for a chunk
272
275
  getChunkMaxTokenLength() {
273
276
  // find the longest prompt
274
- const maxPromptTokenLength = Math.max(...this.prompts.map((promptData) => this.pathwayPrompter.plugin.getCompiledPrompt('', this.args, promptData).tokenLength));
277
+ const maxPromptTokenLength = Math.max(...this.prompts.map((promptData) => this.modelExecutor.plugin.getCompiledPrompt('', this.args, promptData).tokenLength));
275
278
 
276
279
  // find out if any prompts use both text input and previous result
277
280
  const hasBothProperties = this.prompts.some(prompt => prompt.usesTextInput && prompt.usesPreviousResult);
278
281
 
279
282
  // the token ratio is the ratio of the total prompt to the result text - both have to be included
280
283
  // in computing the max token length
281
- const promptRatio = this.pathwayPrompter.plugin.getPromptTokenRatio();
282
- let chunkMaxTokenLength = promptRatio * this.pathwayPrompter.plugin.getModelMaxTokenLength() - maxPromptTokenLength - 1;
284
+ const promptRatio = this.modelExecutor.plugin.getPromptTokenRatio();
285
+ let chunkMaxTokenLength = promptRatio * this.modelExecutor.plugin.getModelMaxTokenLength() - maxPromptTokenLength - 1;
283
286
 
284
287
  // if we have to deal with prompts that have both text input
285
288
  // and previous result, we need to split the maxChunkToken in half
@@ -386,20 +389,22 @@ class PathwayResolver {
386
389
 
387
390
  // If this text is empty, skip applying the prompt as it will likely be a nonsensical result
388
391
  if (!/^\s*$/.test(text) || parameters?.file || parameters?.inputVector || this?.modelName.includes('cognitive')) {
389
- result = await this.pathwayPrompter.execute(text, { ...parameters, ...this.savedContext }, prompt, this);
392
+ result = await this.modelExecutor.execute(text, { ...parameters, ...this.savedContext }, prompt, this);
390
393
  } else {
391
394
  result = text;
392
395
  }
393
396
 
394
397
  requestState[this.requestId].completedCount++;
395
398
 
396
- const { completedCount, totalCount } = requestState[this.requestId];
399
+ if (parameters.async) {
400
+ const { completedCount, totalCount } = requestState[this.requestId];
397
401
 
398
- if (completedCount < totalCount) {
399
- await publishRequestProgress({
400
- requestId: this.requestId,
401
- progress: completedCount / totalCount,
402
- });
402
+ if (completedCount < totalCount) {
403
+ await publishRequestProgress({
404
+ requestId: this.requestId,
405
+ progress: completedCount / totalCount,
406
+ });
407
+ }
403
408
  }
404
409
 
405
410
  if (prompt.saveResultTo) {
@@ -4,7 +4,7 @@ import ModelPlugin from './modelPlugin.js';
4
4
  import { v4 as uuidv4 } from 'uuid';
5
5
  import path from 'path';
6
6
  import { config } from '../../config.js';
7
- import { axios } from '../../lib/request.js';
7
+ import { axios } from '../../lib/requestExecutor.js';
8
8
  import logger from '../../lib/logger.js';
9
9
 
10
10
  const API_URL = config.get('whisperMediaApiUrl');
@@ -14,8 +14,8 @@ const TOP = 1000;
14
14
  let DIRECT_FILE_EXTENSIONS = [".txt", ".json", ".csv", ".md", ".xml", ".js", ".html", ".css"];
15
15
 
16
16
  class AzureCognitivePlugin extends ModelPlugin {
17
- constructor(config, pathway, modelName, model) {
18
- super(config, pathway, modelName, model);
17
+ constructor(pathway, model) {
18
+ super(pathway, model);
19
19
  }
20
20
 
21
21
  async getInputVector (text) {
@@ -23,14 +23,14 @@ class AzureCognitivePlugin extends ModelPlugin {
23
23
  if(!text || !text.trim()){
24
24
  return;
25
25
  }
26
- return JSON.parse(await callPathway(this.config, 'embeddings', { text }))[0];
26
+ return JSON.parse(await callPathway('embeddings', { text }))[0];
27
27
  }catch(err){
28
28
  logger.error(`Error in calculating input vector for text: ${text}, error: ${err}`);
29
29
  }
30
30
  }
31
31
 
32
32
  // Set up parameters specific to the Azure Cognitive API
33
- async getRequestParameters(text, parameters, prompt, mode, indexName, savedContextId, {headers, requestId, pathway, _url}) {
33
+ async getRequestParameters(text, parameters, prompt, mode, indexName, savedContextId, cortexRequest) {
34
34
  const combinedParameters = { ...this.promptParameters, ...parameters };
35
35
  const { modelPromptText } = this.getCompiledPrompt(text, combinedParameters, prompt);
36
36
  const { inputVector, calculateInputVector, privateData, filter, docId } = combinedParameters;
@@ -44,13 +44,15 @@ class AzureCognitivePlugin extends ModelPlugin {
44
44
  searchQuery += ` AND docId:'${docId}'`;
45
45
  }
46
46
 
47
- const docsToDelete = JSON.parse(await this.executeRequest(searchUrl,
48
- { search: searchQuery,
49
- "searchMode": "all",
50
- "queryType": "full",
51
- select: 'id', top: TOP
52
- },
53
- {}, headers, prompt, requestId, pathway));
47
+ cortexRequest.url = searchUrl;
48
+ cortexRequest.data =
49
+ { search: searchQuery,
50
+ "searchMode": "all",
51
+ "queryType": "full",
52
+ select: 'id', top: TOP
53
+ };
54
+
55
+ const docsToDelete = JSON.parse(await this.executeRequest(cortexRequest));
54
56
 
55
57
  const value = docsToDelete.value.map(({id}) => ({
56
58
  id,
@@ -144,13 +146,13 @@ class AzureCognitivePlugin extends ModelPlugin {
144
146
  }
145
147
 
146
148
  // Execute the request to the Azure Cognitive API
147
- async execute(text, parameters, prompt, pathwayResolver) {
148
- const { requestId, pathway, savedContextId, savedContext } = pathwayResolver;
149
+ async execute(text, parameters, prompt, cortexRequest) {
150
+ const { requestId, savedContextId, savedContext } = cortexRequest.pathwayResolver;
149
151
  const mode = this.promptParameters.mode || 'search';
150
152
  let url = this.ensureMode(this.requestUrl(text), mode == 'delete' ? 'index' : mode);
151
153
  const indexName = parameters.indexName || 'indexcortex';
152
154
  url = this.ensureIndex(url, indexName);
153
- const headers = this.model.headers;
155
+ const headers = cortexRequest.headers;
154
156
 
155
157
  const { file } = parameters;
156
158
  if(file){
@@ -175,15 +177,14 @@ class AzureCognitivePlugin extends ModelPlugin {
175
177
  throw Error(`No data can be extracted out of file!`);
176
178
  }
177
179
 
178
- //return await this.execute(data, {...parameters, file:null}, prompt, pathwayResolver);
179
- return await callPathway(this.config, 'cognitive_insert', {...parameters, file:null, text:data });
180
+ return await callPathway('cognitive_insert', {...parameters, file:null, text:data });
180
181
  }
181
182
 
182
183
  if (mode === 'index' && (!text || !text.trim()) ){
183
184
  return; // nothing to index
184
185
  }
185
186
 
186
- const { data, params } = await this.getRequestParameters(text, parameters, prompt, mode, indexName, savedContextId, {headers, requestId, pathway, url});
187
+ const { data, params } = await this.getRequestParameters(text, parameters, prompt, mode, indexName, savedContextId, cortexRequest);
187
188
 
188
189
  // update contextid last used
189
190
  savedContext["lastUsed"] = new Date().toISOString();
@@ -193,11 +194,15 @@ class AzureCognitivePlugin extends ModelPlugin {
193
194
  }
194
195
 
195
196
  // execute the request
196
- const result = await this.executeRequest(url, data || {}, params || {}, headers || {}, prompt, requestId, pathway);
197
+ cortexRequest.url = url;
198
+ cortexRequest.data = data;
199
+ cortexRequest.params = params;
200
+ cortexRequest.headers = headers;
201
+ const result = await this.executeRequest(cortexRequest);
197
202
 
198
203
  // if still has more to delete
199
204
  if (mode === 'delete' && data?.value?.length == TOP) {
200
- return await this.execute(text, parameters, prompt, pathwayResolver);
205
+ return await this.execute(text, parameters, prompt, cortexRequest);
201
206
  }
202
207
 
203
208
  return result;
@@ -3,8 +3,8 @@ import ModelPlugin from './modelPlugin.js';
3
3
  import logger from '../../lib/logger.js';
4
4
 
5
5
  class AzureTranslatePlugin extends ModelPlugin {
6
- constructor(config, pathway, modelName, model) {
7
- super(config, pathway, modelName, model);
6
+ constructor(pathway, model) {
7
+ super(pathway, model);
8
8
  }
9
9
 
10
10
  // Set up parameters specific to the Azure Translate API
@@ -25,17 +25,13 @@ class AzureTranslatePlugin extends ModelPlugin {
25
25
  }
26
26
 
27
27
  // Execute the request to the Azure Translate API
28
- async execute(text, parameters, prompt, pathwayResolver) {
28
+ async execute(text, parameters, prompt, cortexRequest) {
29
29
  const requestParameters = this.getRequestParameters(text, parameters, prompt);
30
- const { requestId, pathway} = pathwayResolver;
31
30
 
32
- const url = this.requestUrl(text);
31
+ cortexRequest.data = requestParameters.data;
32
+ cortexRequest.params = requestParameters.params;
33
33
 
34
- const data = requestParameters.data;
35
- const params = requestParameters.params;
36
- const headers = this.model.headers || {};
37
-
38
- return this.executeRequest(url, data, params, headers, prompt, requestId, pathway);
34
+ return this.executeRequest(cortexRequest);
39
35
  }
40
36
 
41
37
  // Parse the response from the Azure Translate API
@@ -2,8 +2,8 @@
2
2
  import ModelPlugin from './modelPlugin.js';
3
3
 
4
4
  class CohereGeneratePlugin extends ModelPlugin {
5
- constructor(config, pathway, modelName, model) {
6
- super(config, pathway, modelName, model);
5
+ constructor(pathway, model) {
6
+ super(pathway, model);
7
7
  }
8
8
 
9
9
  // Set up parameters specific to the Cohere API
@@ -33,17 +33,10 @@ class CohereGeneratePlugin extends ModelPlugin {
33
33
  }
34
34
 
35
35
  // Execute the request to the Cohere API
36
- async execute(text, parameters, prompt, pathwayResolver) {
37
- const url = this.requestUrl();
36
+ async execute(text, parameters, prompt, cortexRequest) {
38
37
  const requestParameters = this.getRequestParameters(text, parameters, prompt);
39
- const { requestId, pathway} = pathwayResolver;
40
-
41
- const data = { ...(this.model.params || {}), ...requestParameters };
42
- const params = {};
43
- const headers = {
44
- ...this.model.headers || {}
45
- };
46
- return this.executeRequest(url, data, params, headers, prompt, requestId, pathway);
38
+ cortexRequest.data = { ...cortexRequest.data, ...requestParameters };
39
+ return this.executeRequest(cortexRequest);
47
40
  }
48
41
 
49
42
  // Parse the response from the Cohere API
@@ -2,8 +2,8 @@
2
2
  import ModelPlugin from './modelPlugin.js';
3
3
 
4
4
  class CohereSummarizePlugin extends ModelPlugin {
5
- constructor(config, pathway, modelName, model) {
6
- super(config, pathway, modelName, model);
5
+ constructor(pathway, model) {
6
+ super(pathway, model);
7
7
  }
8
8
 
9
9
  // Set up parameters specific to the Cohere Summarize API
@@ -23,17 +23,10 @@ class CohereSummarizePlugin extends ModelPlugin {
23
23
  }
24
24
 
25
25
  // Execute the request to the Cohere Summarize API
26
- async execute(text, parameters, prompt, pathwayResolver) {
27
- const url = this.requestUrl();
26
+ async execute(text, parameters, prompt, cortexRequest) {
28
27
  const requestParameters = this.getRequestParameters(text, parameters, prompt);
29
- const { requestId, pathway} = pathwayResolver;
30
-
31
- const data = { ...(this.model.params || {}), ...requestParameters };
32
- const params = {};
33
- const headers = {
34
- ...this.model.headers || {}
35
- };
36
- return this.executeRequest(url, data, params, headers, prompt, requestId, pathway);
28
+ cortexRequest.data = { ...cortexRequest.data, ...requestParameters };
29
+ return this.executeRequest(cortexRequest);
37
30
  }
38
31
 
39
32
  // Parse the response from the Cohere Summarize API
@@ -5,8 +5,8 @@ import { encode } from 'gpt-3-encoder';
5
5
  import logger from '../../lib/logger.js';
6
6
 
7
7
  class LocalModelPlugin extends ModelPlugin {
8
- constructor(config, pathway, modelName, model) {
9
- super(config, pathway, modelName, model);
8
+ constructor(pathway, model) {
9
+ super(pathway, model);
10
10
  }
11
11
 
12
12
  // if the input starts with a chatML response, just return that
@@ -47,7 +47,7 @@ class LocalModelPlugin extends ModelPlugin {
47
47
  };
48
48
  }
49
49
 
50
- async execute(text, parameters, prompt, _pathwayResolver) {
50
+ async execute(text, parameters, prompt, _cortexRequest) {
51
51
  const requestParameters = this.getRequestParameters(text, parameters, prompt);
52
52
  const { executablePath, args } = this.model;
53
53
  args.push("--prompt", requestParameters.prompt);
@@ -1,18 +1,18 @@
1
1
  // ModelPlugin.js
2
2
  import HandleBars from '../../lib/handleBars.js';
3
-
4
- import { request } from '../../lib/request.js';
3
+ import { executeRequest } from '../../lib/requestExecutor.js';
5
4
  import { encode } from 'gpt-3-encoder';
6
5
  import { getFirstNToken } from '../chunker.js';
7
6
  import logger, { obscureUrlParams } from '../../lib/logger.js';
7
+ import { config } from '../../config.js';
8
8
 
9
9
  const DEFAULT_MAX_TOKENS = 4096;
10
10
  const DEFAULT_MAX_RETURN_TOKENS = 256;
11
11
  const DEFAULT_PROMPT_TOKEN_RATIO = 0.5;
12
12
 
13
13
  class ModelPlugin {
14
- constructor(config, pathway, modelName, model) {
15
- this.modelName = modelName;
14
+ constructor(pathway, model) {
15
+ this.modelName = model.name;
16
16
  this.model = model;
17
17
  this.config = config;
18
18
  this.environmentVariables = config.getEnv();
@@ -33,7 +33,6 @@ class ModelPlugin {
33
33
 
34
34
  this.requestCount = 0;
35
35
  this.lastRequestStartTime = new Date();
36
- this.shouldCache = config.get('enableCache') && (pathway.enableCache || pathway.temperature == 0);
37
36
  }
38
37
 
39
38
  truncateMessagesToTargetLength(messages, targetTokenLength) {
@@ -220,14 +219,14 @@ class ModelPlugin {
220
219
  parseResponse(data) { return data; }
221
220
 
222
221
  // Default simple logging
223
- logRequestStart(url, _data) {
222
+ logRequestStart() {
224
223
  this.requestCount++;
225
224
  this.lastRequestStartTime = new Date();
226
225
  const logMessage = `>>> [${this.requestId}: ${this.pathwayName}.${this.requestCount}] request`;
227
226
  const header = '>'.repeat(logMessage.length);
228
227
  logger.info(`${header}`);
229
228
  logger.info(`${logMessage}`);
230
- logger.info(`>>> Making API request to ${obscureUrlParams(url)}`);
229
+ logger.info(`>>> Making API request to ${obscureUrlParams(this.url)}`);
231
230
  }
232
231
 
233
232
  logAIRequestFinished() {
@@ -257,15 +256,22 @@ class ModelPlugin {
257
256
  prompt && prompt.debugInfo && (prompt.debugInfo += `\n${JSON.stringify(data)}`);
258
257
  }
259
258
 
260
- async executeRequest(url, data, params, headers, prompt, requestId, pathway) {
259
+ async executeRequest(cortexRequest) {
261
260
  try {
262
- this.aiRequestStartTime = new Date();
261
+ const { url, data, pathway, requestId, prompt } = cortexRequest;
262
+ this.url = url;
263
263
  this.requestId = requestId;
264
- this.logRequestStart(url, data);
265
- const responseData = await request({ url, data, params, headers, cache: this.shouldCache }, this.modelName, this.requestId, pathway);
264
+ this.pathwayName = pathway.name;
265
+ this.pathwayPrompt = pathway.prompt;
266
+
267
+ cortexRequest.cache = config.get('enableCache') && (pathway.enableCache || pathway.temperature == 0);
268
+ this.logRequestStart();
269
+
270
+ const responseData = await executeRequest(cortexRequest);
266
271
 
267
272
  if (responseData.error) {
268
- throw new Error(`An error was returned from the server: ${JSON.stringify(responseData.error)}`);
273
+ logger.error(`An error was returned from the server: ${JSON.stringify(responseData.error)}`);
274
+ throw responseData;
269
275
  }
270
276
 
271
277
  this.logRequestData(data, responseData, prompt);
@@ -2,8 +2,8 @@
2
2
  import OpenAIChatPlugin from './openAiChatPlugin.js';
3
3
 
4
4
  class OpenAIChatExtensionPlugin extends OpenAIChatPlugin {
5
- constructor(config, pathway, modelName, model) {
6
- super(config, pathway, modelName, model);
5
+ constructor(pathway, model) {
6
+ super(pathway, model);
7
7
  this.tool = '';
8
8
  }
9
9
 
@@ -47,9 +47,9 @@ class OpenAIChatExtensionPlugin extends OpenAIChatPlugin {
47
47
  return reqParams;
48
48
  }
49
49
 
50
- async execute(text, parameters, prompt, pathwayResolver) {
51
- const result = await super.execute(text, parameters, prompt, pathwayResolver);
52
- pathwayResolver.tool = this.tool; // add tool info back
50
+ async execute(text, parameters, prompt, cortexRequest) {
51
+ const result = await super.execute(text, parameters, prompt, cortexRequest);
52
+ cortexRequest.pathwayResolver.tool = this.tool; // add tool info back
53
53
  return result;
54
54
  }
55
55
 
@@ -4,8 +4,8 @@ import { encode } from 'gpt-3-encoder';
4
4
  import logger from '../../lib/logger.js';
5
5
 
6
6
  class OpenAIChatPlugin extends ModelPlugin {
7
- constructor(config, pathway, modelName, model) {
8
- super(config, pathway, modelName, model);
7
+ constructor(pathway, model) {
8
+ super(pathway, model);
9
9
  }
10
10
 
11
11
  // convert to OpenAI messages array format if necessary
@@ -76,16 +76,14 @@ class OpenAIChatPlugin extends ModelPlugin {
76
76
  return requestParameters;
77
77
  }
78
78
 
79
- // Execute the request to the OpenAI Chat API
80
- async execute(text, parameters, prompt, pathwayResolver) {
81
- const url = this.requestUrl(text);
79
+ // Assemble and execute the request to the OpenAI Chat API
80
+ async execute(text, parameters, prompt, cortexRequest) {
82
81
  const requestParameters = this.getRequestParameters(text, parameters, prompt);
83
- const { requestId, pathway} = pathwayResolver;
84
82
 
85
- const data = { ...(this.model.params || {}), ...requestParameters };
86
- const params = {}; // query params
87
- const headers = this.model.headers || {};
88
- return this.executeRequest(url, data, params, headers, prompt, requestId, pathway);
83
+ cortexRequest.data = { ...(cortexRequest.data || {}), ...requestParameters };
84
+ cortexRequest.params = {}; // query params
85
+
86
+ return this.executeRequest(cortexRequest);
89
87
  }
90
88
 
91
89
  // Parse the response from the OpenAI Chat API
@@ -16,8 +16,8 @@ const truncatePromptIfNecessary = (text, textTokenCount, modelMaxTokenCount, tar
16
16
  }
17
17
 
18
18
  class OpenAICompletionPlugin extends ModelPlugin {
19
- constructor(config, pathway, modelName, model) {
20
- super(config, pathway, modelName, model);
19
+ constructor(pathway, model) {
20
+ super(pathway, model);
21
21
  }
22
22
 
23
23
  // Set up parameters specific to the OpenAI Completion API
@@ -76,16 +76,13 @@ class OpenAICompletionPlugin extends ModelPlugin {
76
76
  }
77
77
 
78
78
  // Execute the request to the OpenAI Completion API
79
- async execute(text, parameters, prompt, pathwayResolver) {
80
- const url = this.requestUrl(text);
81
- const requestParameters = this.getRequestParameters(text, parameters, prompt, pathwayResolver);
82
- const { requestId, pathway} = pathwayResolver;
83
-
84
- const data = { ...(this.model.params || {}), ...requestParameters };
85
- const params = {};
86
- const headers = this.model.headers || {};
87
-
88
- return this.executeRequest(url, data, params, headers, prompt, requestId, pathway);
79
+ async execute(text, parameters, prompt, cortexRequest) {
80
+ const requestParameters = this.getRequestParameters(text, parameters, prompt, cortexRequest.pathwayResolver);
81
+
82
+ cortexRequest.data = { ...(cortexRequest.data || {}), ...requestParameters };
83
+ cortexRequest.params = {};
84
+
85
+ return this.executeRequest(cortexRequest);
89
86
  }
90
87
 
91
88
  // Parse the response from the OpenAI Completion API