@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.
- package/lib/pathwayManager.js +67 -18
- package/package.json +1 -1
- package/server/plugins/openAiVisionPlugin.js +11 -10
package/lib/pathwayManager.js
CHANGED
|
@@ -80,7 +80,7 @@ class AzureBlobStorage extends StorageStrategy {
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
const downloadBlockBlobResponse = await blockBlobClient.download();
|
|
83
|
-
const data = await
|
|
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(
|
|
128
|
-
|
|
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
|
-
|
|
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
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
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.
|
|
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
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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
|
-
|
|
40
|
+
|
|
41
|
+
return parsedItem;
|
|
41
42
|
});
|
|
42
43
|
}
|
|
43
44
|
} catch (e) {
|