@aj-archipelago/cortex 1.1.6 → 1.1.7

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/config.js CHANGED
@@ -146,6 +146,16 @@ var config = convict({
146
146
  "maxTokenLength": 128000,
147
147
  "supportsStreaming": true
148
148
  },
149
+ "azure-bing": {
150
+ "type": "AZURE-BING",
151
+ "url": "https://api.bing.microsoft.com/v7.0/search",
152
+ "headers": {
153
+ "Ocp-Apim-Subscription-Key": "{{AZURE_BING_KEY}}",
154
+ "Content-Type": "application/json"
155
+ },
156
+ "requestsPerSecond": 10,
157
+ "maxTokenLength": 200000
158
+ },
149
159
  },
150
160
  env: 'CORTEX_MODELS'
151
161
  },
@@ -11,6 +11,7 @@ class CortexRequest {
11
11
  this._pathwayResolver = pathwayResolver || {};
12
12
  this._selectedEndpoint = selectedEndpoint || {};
13
13
  this._stream = stream || false;
14
+ this._method = 'POST';
14
15
 
15
16
  if (this._pathwayResolver) {
16
17
  this._model = this._pathwayResolver.model;
@@ -41,6 +42,15 @@ class CortexRequest {
41
42
  this._url = value;
42
43
  }
43
44
 
45
+ // method getter and setter
46
+ get method() {
47
+ return this._method;
48
+ }
49
+
50
+ set method(value) {
51
+ this._method = value;
52
+ }
53
+
44
54
  // data getter and setter
45
55
  get data() {
46
56
  return this._data;
@@ -183,11 +183,15 @@ setInterval(() => {
183
183
  }
184
184
  }, 30000); // Log rates every 30 seconds
185
185
 
186
- const postWithMonitor = async (endpoint, url, data, axiosConfigObj) => {
186
+ const requestWithMonitor = async (endpoint, url, data, axiosConfigObj) => {
187
187
  const callId = endpoint?.monitor?.startCall();
188
188
  let response;
189
189
  try {
190
- response = await cortexAxios.post(url, data, axiosConfigObj);
190
+ if (axiosConfigObj?.method == 'GET'){
191
+ response = await cortexAxios.get(url, axiosConfigObj);
192
+ } else {
193
+ response = await cortexAxios.post(url, data, axiosConfigObj);
194
+ }
191
195
  } catch (error) {
192
196
  // throw new error with duration as part of the error data
193
197
  throw { ...error, duration: endpoint?.monitor?.incrementErrorCount(callId, error?.response?.status || null) };
@@ -213,22 +217,22 @@ const getDuplicateRequestDelay = (index, duplicateRequestAfter) => {
213
217
  return duplicateRequestTimeout;
214
218
  }
215
219
 
216
- const postRequest = async (cortexRequest) => {
220
+ const makeRequest = async (cortexRequest) => {
217
221
  let promises = [];
218
222
  // retry certain errors up to MAX_RETRY times
219
223
  for (let i = 0; i < MAX_RETRY; i++) {
220
- const { url, data, params, headers, cache, selectedEndpoint, requestId, pathway, model, stream} = cortexRequest;
224
+ const { url, data, params, headers, cache, selectedEndpoint, requestId, pathway, model, stream, method} = cortexRequest;
221
225
  const enableDuplicateRequests = pathway?.enableDuplicateRequests !== undefined ? pathway.enableDuplicateRequests : config.get('enableDuplicateRequests');
222
226
  const maxDuplicateRequests = enableDuplicateRequests ? MAX_DUPLICATE_REQUESTS : 1;
223
227
  const duplicateRequestAfter = (pathway?.duplicateRequestAfter || DUPLICATE_REQUEST_AFTER) * 1000;
224
228
 
225
- const axiosConfigObj = { params, headers, cache };
229
+ const axiosConfigObj = { params, headers, cache, method };
226
230
  const streamRequested = (stream || params?.stream || data?.stream);
227
231
  // if we're using streaming, duplicate requests are
228
232
  // not supported, so we just push one promise into the array
229
233
  if (streamRequested && model.supportsStreaming) {
230
234
  axiosConfigObj.responseType = 'stream';
231
- promises.push(selectedEndpoint.limiter.schedule({expiration: pathway.timeout * 1000 + 1000, id: `${requestId}_${uuidv4()}`},() => postWithMonitor(selectedEndpoint, url, data, axiosConfigObj)));
235
+ promises.push(selectedEndpoint.limiter.schedule({expiration: pathway.timeout * 1000 + 1000, id: `${requestId}_${uuidv4()}`},() => requestWithMonitor(selectedEndpoint, url, data, axiosConfigObj)));
232
236
  } else {
233
237
  if (streamRequested) {
234
238
  logger.info(`>>> [${requestId}] ${model} does not support streaming - sending non-streaming request`);
@@ -253,7 +257,7 @@ const postRequest = async (cortexRequest) => {
253
257
  if (!selectedEndpoint.limiter) {
254
258
  throw new Error(`No limiter for endpoint ${endpointName}!`);
255
259
  }
256
- const axiosConfigObj = { params, headers, cache };
260
+ const axiosConfigObj = { params, headers, cache, method };
257
261
 
258
262
  let response = null;
259
263
  let duration = null;
@@ -269,7 +273,7 @@ const postRequest = async (cortexRequest) => {
269
273
  logger.info(`\n${header}\n${logMessage}`);
270
274
  }
271
275
 
272
- ({ response, duration } = await selectedEndpoint.limiter.schedule({expiration: pathway.timeout * 1000 + 1000, id: `${requestId}_${uuidv4()}`}, () => postWithMonitor(selectedEndpoint, url, data, axiosConfigObj)));
276
+ ({ response, duration } = await selectedEndpoint.limiter.schedule({expiration: pathway.timeout * 1000 + 1000, id: `${requestId}_${uuidv4()}`}, () => requestWithMonitor(selectedEndpoint, url, data, axiosConfigObj)));
273
277
 
274
278
  if (!controller.signal?.aborted) {
275
279
  logger.debug(`<<< [${requestId}] received response for request ${index}`);
@@ -341,7 +345,7 @@ const postRequest = async (cortexRequest) => {
341
345
 
342
346
  const executeRequest = async (cortexRequest) => {
343
347
  try {
344
- const { response, duration } = await postRequest(cortexRequest);
348
+ const { response, duration } = await makeRequest(cortexRequest);
345
349
  const requestId = cortexRequest.requestId;
346
350
  const { error, data, cached } = response;
347
351
  if (cached) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aj-archipelago/cortex",
3
- "version": "1.1.6",
3
+ "version": "1.1.7",
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": {
@@ -52,7 +52,7 @@
52
52
  "handlebars": "^4.7.7",
53
53
  "ioredis": "^5.3.1",
54
54
  "keyv": "^4.5.2",
55
- "langchain": "^0.0.47",
55
+ "langchain": "^0.1.28",
56
56
  "mime-types": "^2.1.35",
57
57
  "subsrt": "^1.1.1",
58
58
  "uuid": "^9.0.0",
@@ -0,0 +1,12 @@
1
+ // bing.js
2
+ // Web search tool
3
+
4
+ export default {
5
+ inputParameters: {
6
+ text: ``,
7
+ },
8
+ timeout: 400,
9
+ enableDuplicateRequests: false,
10
+ model: 'azure-bing',
11
+ };
12
+
package/pathways/index.js CHANGED
@@ -19,8 +19,10 @@ import transcribe from './transcribe.js';
19
19
  import translate from './translate.js';
20
20
  import embeddings from './embeddings.js';
21
21
  import vision from './vision.js';
22
+ import bing from './bing.js';
22
23
 
23
24
  export {
25
+ bing,
24
26
  edit,
25
27
  chat,
26
28
  bias,
@@ -19,6 +19,7 @@ import OpenAIDallE3Plugin from './plugins/openAiDallE3Plugin.js';
19
19
  import OpenAIVisionPlugin from './plugins/openAiVisionPlugin.js';
20
20
  import GeminiChatPlugin from './plugins/geminiChatPlugin.js';
21
21
  import GeminiVisionPlugin from './plugins/geminiVisionPlugin.js';
22
+ import AzureBingPlugin from './plugins/azureBingPlugin.js';
22
23
 
23
24
  class ModelExecutor {
24
25
  constructor(pathway, model) {
@@ -80,6 +81,9 @@ class ModelExecutor {
80
81
  case 'GEMINI-VISION':
81
82
  plugin = new GeminiVisionPlugin(pathway, model);
82
83
  break;
84
+ case 'AZURE-BING':
85
+ plugin = new AzureBingPlugin(pathway, model);
86
+ break;
83
87
  default:
84
88
  throw new Error(`Unsupported model type: ${model.type}`);
85
89
  }
@@ -0,0 +1,44 @@
1
+ import ModelPlugin from './modelPlugin.js';
2
+ import logger from '../../lib/logger.js';
3
+
4
+ class AzureBingPlugin extends ModelPlugin {
5
+ constructor(pathway, model) {
6
+ super(pathway, model);
7
+ }
8
+
9
+ getRequestParameters(text) {
10
+ const requestParameters = {
11
+ data: [
12
+ ],
13
+ params: {
14
+ q: text,
15
+ }
16
+ };
17
+ return requestParameters;
18
+ }
19
+
20
+ async execute(text, parameters, prompt, cortexRequest) {
21
+ const requestParameters = this.getRequestParameters(text, parameters, prompt);
22
+
23
+ cortexRequest.data = requestParameters.data;
24
+ cortexRequest.params = requestParameters.params;
25
+ cortexRequest.method = 'GET';
26
+
27
+ return this.executeRequest(cortexRequest);
28
+ }
29
+
30
+ parseResponse(data) {
31
+ return JSON.stringify(data);
32
+ }
33
+
34
+ // Override the logging function to display the request and response
35
+ logRequestData(data, responseData, prompt) {
36
+ this.logAIRequestFinished();
37
+
38
+ logger.debug(`${this.parseResponse(responseData)}`);
39
+
40
+ prompt && prompt.debugInfo && (prompt.debugInfo += `\n${JSON.stringify(data)}`);
41
+ }
42
+ }
43
+
44
+ export default AzureBingPlugin;