@aj-archipelago/cortex 1.1.34 → 1.1.35

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.
@@ -80,7 +80,7 @@ class AzureBlobStorage extends StorageStrategy {
80
80
  }
81
81
 
82
82
  const downloadBlockBlobResponse = await blockBlobClient.download();
83
- const data = await this.streamToString(downloadBlockBlobResponse.readableStreamBody);
83
+ const data = await streamToString(downloadBlockBlobResponse.readableStreamBody);
84
84
  const parsedData = JSON.parse(data);
85
85
  logger.info(`Loaded pathways from Azure Blob Storage. ${Object.keys(parsedData).map(user => `${user}(${Object.keys(parsedData[user])})`).join(', ')}`);
86
86
  return parsedData;
@@ -124,18 +124,33 @@ class AzureBlobStorage extends StorageStrategy {
124
124
  class S3Storage extends StorageStrategy {
125
125
  constructor(config) {
126
126
  super();
127
- this.s3 = new S3(config);
128
- this.bucketName = config.bucketName;
127
+ this.s3 = new S3({
128
+ credentials: {
129
+ accessKeyId: config.awsAccessKeyId,
130
+ secretAccessKey: config.awsSecretAccessKey
131
+ },
132
+ region: config.awsRegion
133
+ });
134
+ this.bucketName = config.awsBucketName;
129
135
  }
130
136
 
131
137
  async load() {
132
138
  try {
139
+ // Check if bucket exists, create if it doesn't
140
+ await this.ensureBucketExists();
141
+
142
+ // Check if file exists, create if it doesn't
143
+ await this.ensureFileExists();
144
+
133
145
  const params = {
134
146
  Bucket: this.bucketName,
135
147
  Key: 'pathways.json'
136
148
  };
137
149
  const data = await this.s3.getObject(params);
138
- return JSON.parse(data.Body.toString());
150
+
151
+ const readableStream = data.Body;
152
+ const dataString = await streamToString(readableStream);
153
+ return JSON.parse(dataString);
139
154
  } catch (error) {
140
155
  logger.error('Error loading pathways from S3:', error);
141
156
  throw error;
@@ -164,6 +179,41 @@ class S3Storage extends StorageStrategy {
164
179
  const data = await this.s3.headObject(params);
165
180
  return new Date(data.LastModified).getTime();
166
181
  }
182
+
183
+ async ensureBucketExists() {
184
+ try {
185
+ await this.s3.headBucket({ Bucket: this.bucketName });
186
+ } catch (error) {
187
+ if (error.name === 'NotFound') {
188
+ logger.info(`Bucket ${this.bucketName} does not exist, creating it`);
189
+ await this.s3.createBucket({ Bucket: this.bucketName });
190
+ } else {
191
+ throw error;
192
+ }
193
+ }
194
+ }
195
+
196
+ async ensureFileExists() {
197
+ try {
198
+ await this.s3.headObject({
199
+ Bucket: this.bucketName,
200
+ Key: 'pathways.json'
201
+ });
202
+ } catch (error) {
203
+ if (error.name === 'NotFound') {
204
+ logger.info('pathways.json does not exist, creating it with empty object');
205
+ const emptyContent = JSON.stringify({});
206
+ await this.s3.putObject({
207
+ Bucket: this.bucketName,
208
+ Key: 'pathways.json',
209
+ Body: emptyContent,
210
+ ContentType: 'application/json'
211
+ });
212
+ } else {
213
+ throw error;
214
+ }
215
+ }
216
+ }
167
217
  }
168
218
 
169
219
  class PathwayManager {
@@ -354,20 +404,19 @@ class PathwayManager {
354
404
 
355
405
  return pathways[userId][pathwayName];
356
406
  }
407
+ }
357
408
 
358
- // Helper function to convert a readable stream to a string
359
- async streamToString(readableStream) {
360
- return new Promise((resolve, reject) => {
361
- const chunks = [];
362
- readableStream.on('data', (data) => {
363
- chunks.push(data.toString());
364
- });
365
- readableStream.on('end', () => {
366
- resolve(chunks.join(''));
367
- });
368
- readableStream.on('error', reject);
409
+ // Helper function to convert a readable stream to a string
410
+ async function streamToString(readableStream) {
411
+ return new Promise((resolve, reject) => {
412
+ const chunks = [];
413
+ readableStream.on('data', (data) => {
414
+ chunks.push(data.toString());
369
415
  });
370
- }
416
+ readableStream.on('end', () => {
417
+ resolve(chunks.join(''));
418
+ });
419
+ readableStream.on('error', reject);
420
+ });
371
421
  }
372
-
373
- export default PathwayManager;
422
+ export default PathwayManager;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aj-archipelago/cortex",
3
- "version": "1.1.34",
3
+ "version": "1.1.35",
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": {
@@ -27,17 +27,18 @@ class OpenAIVisionPlugin extends OpenAIChatPlugin {
27
27
  }
28
28
  if (Array.isArray(message.content)) {
29
29
  message.content = message.content.map(item => {
30
- if (typeof item === 'string') {
31
- const parsedItem = safeJsonParse(item);
32
- return parsedItem.type ? parsedItem : { type: 'text', text: item };
33
- } else if (typeof item === 'object') {
34
- const { type, image_url, url } = item;
35
- if (type === 'image_url') {
36
- image_url.url = url || image_url.url;
37
- return { type, image_url };
38
- }
30
+ const parsedItem = safeJsonParse(item);
31
+
32
+ if (typeof parsedItem === 'string') {
33
+ return { type: 'text', text: parsedItem };
34
+ }
35
+
36
+ if (typeof parsedItem === 'object' && parsedItem !== null && parsedItem.type === 'image_url') {
37
+ parsedItem.image_url.url = parsedItem.url || parsedItem.image_url.url;
38
+ return parsedItem;
39
39
  }
40
- return item;
40
+
41
+ return parsedItem;
41
42
  });
42
43
  }
43
44
  } catch (e) {