@smythos/sre 1.5.70 → 1.5.72
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/dist/index.js +14 -15
- package/dist/index.js.map +1 -1
- package/dist/types/Components/MemoryDeleteKeyVal.class.d.ts +8 -0
- package/dist/types/Components/MemoryReadKeyVal.class.d.ts +7 -0
- package/dist/types/subsystems/IO/Storage.service/connectors/AzureBlobStorage.class.d.ts +211 -0
- package/dist/types/subsystems/IO/VectorDB.service/connectors/RAMVecrtorDB.class.d.ts +3 -7
- package/dist/types/subsystems/LLMManager/ModelsProvider.service/connectors/JSONModelsProvider.class.d.ts +1 -0
- package/dist/types/subsystems/LLMManager/models.d.ts +0 -1
- package/dist/types/types/LLM.types.d.ts +1 -1
- package/package.json +5 -1
- package/src/Components/ECMASandbox.class.ts +4 -3
- package/src/Components/MemoryDeleteKeyVal.class.ts +3 -3
- package/src/Components/MemoryReadKeyVal.class.ts +5 -4
- package/src/Components/MemoryWriteObject.class.ts +1 -1
- package/src/helpers/AWSLambdaCode.helper.ts +30 -22
- package/src/helpers/Conversation.helper.ts +3 -2
- package/src/helpers/ECMASandbox.helper.ts +17 -7
- package/src/helpers/Sysconfig.helper.ts +18 -0
- package/src/subsystems/AgentManager/AgentData.service/connectors/LocalAgentDataConnector.class.ts +3 -0
- package/src/subsystems/IO/VectorDB.service/connectors/RAMVecrtorDB.class.ts +93 -108
- package/src/subsystems/IO/VectorDB.service/embed/GoogleEmbedding.ts +1 -1
- package/src/subsystems/IO/VectorDB.service/embed/OpenAIEmbedding.ts +1 -1
- package/src/subsystems/LLMManager/LLM.inference.ts +3 -0
- package/src/subsystems/LLMManager/ModelsProvider.service/connectors/JSONModelsProvider.class.ts +16 -0
- package/src/subsystems/LLMManager/models.ts +2 -2
- package/src/subsystems/Security/Account.service/connectors/JSONFileAccount.class.ts +6 -0
- package/src/types/LLM.types.ts +1 -1
|
@@ -13,6 +13,24 @@ export function findSmythPath(_path: string = '', callback?: (smythDir: string,
|
|
|
13
13
|
|
|
14
14
|
const searchDirectories = [];
|
|
15
15
|
|
|
16
|
+
if (process.env.SMYTH_PATH) {
|
|
17
|
+
if (!fs.existsSync(process.env.SMYTH_PATH)) {
|
|
18
|
+
console.error('CRITICAL : SMYTH_PATH environment variable is not a valid directory');
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const envDir = path.resolve(process.env.SMYTH_PATH, _path);
|
|
23
|
+
//check if the directory exists
|
|
24
|
+
if (!fs.existsSync(envDir)) {
|
|
25
|
+
callback?.(envDir, false, null);
|
|
26
|
+
console.error(`CRITICAL : missing directory (${envDir}) under SMYTH_PATH `);
|
|
27
|
+
//process.exit(1);
|
|
28
|
+
} else {
|
|
29
|
+
callback?.(envDir, true, null);
|
|
30
|
+
}
|
|
31
|
+
return envDir;
|
|
32
|
+
}
|
|
33
|
+
|
|
16
34
|
// 1. Try to find in local directory (the directory from which the program was run)
|
|
17
35
|
const localDir = path.resolve(process.cwd(), '.smyth', _path);
|
|
18
36
|
searchDirectories.push(localDir);
|
package/src/subsystems/AgentManager/AgentData.service/connectors/LocalAgentDataConnector.class.ts
CHANGED
|
@@ -2,6 +2,9 @@ import fs from 'fs';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { AgentDataConnector } from '../AgentDataConnector';
|
|
4
4
|
import { uid } from '@sre/utils/general.utils';
|
|
5
|
+
import { Logger } from '@sre/helpers/Log.helper';
|
|
6
|
+
|
|
7
|
+
const console = Logger('LocalAgentDataConnector');
|
|
5
8
|
|
|
6
9
|
export type LocalAgentDataSettings = { devDir: string; prodDir: string };
|
|
7
10
|
|
|
@@ -5,7 +5,7 @@ import { IAccessCandidate, IACL, TAccessLevel } from '@sre/types/ACL.types';
|
|
|
5
5
|
import { AccessRequest } from '@sre/Security/AccessControl/AccessRequest.class';
|
|
6
6
|
import { AccessCandidate } from '@sre/Security/AccessControl/AccessCandidate.class';
|
|
7
7
|
import { SecureConnector } from '@sre/Security/SecureConnector.class';
|
|
8
|
-
import { VectorDBConnector } from '../VectorDBConnector';
|
|
8
|
+
import { VectorDBConnector, DeleteTarget } from '../VectorDBConnector';
|
|
9
9
|
import {
|
|
10
10
|
DatasourceDto,
|
|
11
11
|
IStorageVectorDataSource,
|
|
@@ -21,6 +21,8 @@ import { OpenAIEmbeds } from '@sre/IO/VectorDB.service/embed/OpenAIEmbedding';
|
|
|
21
21
|
import crypto from 'crypto';
|
|
22
22
|
import { BaseEmbedding, TEmbeddings } from '../embed/BaseEmbedding';
|
|
23
23
|
import { EmbeddingsFactory } from '../embed';
|
|
24
|
+
import { chunkText } from '@sre/utils/string.utils';
|
|
25
|
+
import { jsonrepair } from 'jsonrepair';
|
|
24
26
|
|
|
25
27
|
const console = Logger('RAM VectorDB');
|
|
26
28
|
|
|
@@ -66,6 +68,7 @@ export class RAMVectorDB extends VectorDBConnector {
|
|
|
66
68
|
if (!_settings.embeddings) {
|
|
67
69
|
_settings.embeddings = { provider: 'OpenAI', model: 'text-embedding-3-large', params: { dimensions: 1024 } };
|
|
68
70
|
}
|
|
71
|
+
if (!_settings.embeddings.params) _settings.embeddings.params = { dimensions: 1024 };
|
|
69
72
|
if (!_settings.embeddings.params?.dimensions) _settings.embeddings.params.dimensions = 1024;
|
|
70
73
|
|
|
71
74
|
this.embedder = EmbeddingsFactory.create(_settings.embeddings.provider, _settings.embeddings);
|
|
@@ -182,12 +185,26 @@ export class RAMVectorDB extends VectorDBConnector {
|
|
|
182
185
|
|
|
183
186
|
for (const vector of namespaceData) {
|
|
184
187
|
const similarity = this.cosineSimilarity(queryVector as number[], vector.values);
|
|
188
|
+
|
|
189
|
+
let userMetadata = undefined;
|
|
190
|
+
if (options.includeMetadata) {
|
|
191
|
+
if (vector.metadata?.[this.USER_METADATA_KEY]) {
|
|
192
|
+
try {
|
|
193
|
+
userMetadata = JSON.parse(vector.metadata[this.USER_METADATA_KEY]);
|
|
194
|
+
} catch {
|
|
195
|
+
userMetadata = vector.metadata[this.USER_METADATA_KEY];
|
|
196
|
+
}
|
|
197
|
+
} else {
|
|
198
|
+
userMetadata = {}; // Return empty object when no metadata exists, like Milvus
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
185
202
|
results.push({
|
|
186
203
|
id: vector.id,
|
|
187
204
|
score: similarity,
|
|
188
205
|
values: vector.values,
|
|
189
|
-
|
|
190
|
-
|
|
206
|
+
text: vector.metadata?.text as string | undefined,
|
|
207
|
+
metadata: options.includeMetadata ? userMetadata : undefined,
|
|
191
208
|
});
|
|
192
209
|
}
|
|
193
210
|
|
|
@@ -207,28 +224,28 @@ export class RAMVectorDB extends VectorDBConnector {
|
|
|
207
224
|
//const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
|
|
208
225
|
const preparedNs = this.constructNsName(acRequest.candidate as AccessCandidate, namespace);
|
|
209
226
|
|
|
210
|
-
|
|
211
|
-
const insertedIds: string[] = [];
|
|
227
|
+
sourceWrapper = Array.isArray(sourceWrapper) ? sourceWrapper : [sourceWrapper];
|
|
212
228
|
|
|
213
|
-
|
|
214
|
-
|
|
229
|
+
// make sure that all sources are of the same type (source.source)
|
|
230
|
+
if (sourceWrapper.some((s) => this.embedder.detectSourceType(s.source) !== this.embedder.detectSourceType(sourceWrapper[0].source))) {
|
|
231
|
+
throw new Error('All sources must be of the same type');
|
|
215
232
|
}
|
|
216
233
|
|
|
217
|
-
|
|
218
|
-
|
|
234
|
+
const sourceType = this.embedder.detectSourceType(sourceWrapper[0].source);
|
|
235
|
+
if (sourceType === 'unknown' || sourceType === 'url') throw new Error('Invalid source type');
|
|
219
236
|
|
|
220
|
-
|
|
221
|
-
// Text embedding
|
|
237
|
+
const transformedSource = await this.embedder.transformSource(sourceWrapper, sourceType, acRequest.candidate as AccessCandidate);
|
|
222
238
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
239
|
+
if (!this.vectors[preparedNs]) {
|
|
240
|
+
this.vectors[preparedNs] = [];
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const insertedIds: string[] = [];
|
|
228
244
|
|
|
245
|
+
for (const source of transformedSource) {
|
|
229
246
|
const vectorData: VectorData = {
|
|
230
247
|
id: source.id,
|
|
231
|
-
values:
|
|
248
|
+
values: source.source as number[],
|
|
232
249
|
datasource: source.metadata?.datasourceId || 'unknown',
|
|
233
250
|
metadata: source.metadata,
|
|
234
251
|
};
|
|
@@ -248,107 +265,96 @@ export class RAMVectorDB extends VectorDBConnector {
|
|
|
248
265
|
}
|
|
249
266
|
|
|
250
267
|
@SecureConnector.AccessControl
|
|
251
|
-
protected async delete(acRequest: AccessRequest, namespace: string,
|
|
268
|
+
protected async delete(acRequest: AccessRequest, namespace: string, deleteTarget: DeleteTarget): Promise<void> {
|
|
252
269
|
//const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
|
|
253
270
|
const preparedNs = this.constructNsName(acRequest.candidate as AccessCandidate, namespace);
|
|
254
271
|
|
|
255
|
-
const
|
|
272
|
+
const isDeleteByFilter = typeof deleteTarget === 'object' && !Array.isArray(deleteTarget);
|
|
256
273
|
|
|
257
|
-
if (
|
|
258
|
-
|
|
274
|
+
if (isDeleteByFilter) {
|
|
275
|
+
// Handle delete by filter (e.g., by datasourceId)
|
|
276
|
+
if ('datasourceId' in deleteTarget && deleteTarget.datasourceId) {
|
|
277
|
+
if (this.vectors[preparedNs]) {
|
|
278
|
+
this.vectors[preparedNs] = this.vectors[preparedNs].filter((vector) => vector.datasource !== deleteTarget.datasourceId);
|
|
279
|
+
}
|
|
280
|
+
} else {
|
|
281
|
+
throw new Error('Unsupported delete filter');
|
|
282
|
+
}
|
|
283
|
+
} else {
|
|
284
|
+
// Handle delete by ID(s)
|
|
285
|
+
const ids = Array.isArray(deleteTarget) ? deleteTarget : [deleteTarget];
|
|
286
|
+
if (this.vectors[preparedNs]) {
|
|
287
|
+
this.vectors[preparedNs] = this.vectors[preparedNs].filter((vector) => !ids.includes(vector.id));
|
|
288
|
+
}
|
|
259
289
|
}
|
|
260
290
|
}
|
|
261
291
|
|
|
262
292
|
@SecureConnector.AccessControl
|
|
263
293
|
protected async createDatasource(acRequest: AccessRequest, namespace: string, datasource: DatasourceDto): Promise<IStorageVectorDataSource> {
|
|
264
294
|
//const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
|
|
265
|
-
const
|
|
266
|
-
const
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
const
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
const chunks = this.splitTextIntoChunks(datasource.text, chunkSize, chunkOverlap);
|
|
280
|
-
|
|
281
|
-
// Initialize namespace vectors if not exists (should already exist if namespace was created properly)
|
|
282
|
-
if (!this.vectors[preparedNs]) {
|
|
283
|
-
this.vectors[preparedNs] = [];
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
for (let i = 0; i < chunks.length; i++) {
|
|
287
|
-
const chunkId = `${datasourceId}_chunk_${i}`;
|
|
288
|
-
const vector = await this.embedder.embedText(chunks[i], acRequest.candidate as AccessCandidate);
|
|
289
|
-
|
|
290
|
-
const vectorData: VectorData = {
|
|
291
|
-
id: chunkId,
|
|
292
|
-
values: vector,
|
|
293
|
-
datasource: datasourceId,
|
|
295
|
+
const acl = new ACL().addAccess(acRequest.candidate.role, acRequest.candidate.id, TAccessLevel.Owner);
|
|
296
|
+
const dsId = datasource.id || crypto.randomUUID();
|
|
297
|
+
|
|
298
|
+
const formattedNs = this.constructNsName(acRequest.candidate as AccessCandidate, namespace);
|
|
299
|
+
const chunkedText = chunkText(datasource.text, {
|
|
300
|
+
chunkSize: datasource.chunkSize,
|
|
301
|
+
chunkOverlap: datasource.chunkOverlap,
|
|
302
|
+
});
|
|
303
|
+
const label = datasource.label || 'Untitled';
|
|
304
|
+
const ids = Array.from({ length: chunkedText.length }, (_, i) => `${dsId}_${crypto.randomUUID()}`);
|
|
305
|
+
const source: IVectorDataSourceDto[] = chunkedText.map((doc, i) => {
|
|
306
|
+
return {
|
|
307
|
+
id: ids[i],
|
|
308
|
+
source: doc,
|
|
294
309
|
metadata: {
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
310
|
+
acl: acl.serializedACL,
|
|
311
|
+
namespaceId: formattedNs,
|
|
312
|
+
datasourceId: dsId,
|
|
313
|
+
datasourceLabel: label,
|
|
314
|
+
[this.USER_METADATA_KEY]: datasource.metadata ? jsonrepair(JSON.stringify(datasource.metadata)) : undefined,
|
|
299
315
|
},
|
|
300
316
|
};
|
|
317
|
+
});
|
|
301
318
|
|
|
302
|
-
|
|
303
|
-
vectorIds.push(chunkId);
|
|
304
|
-
}
|
|
319
|
+
const _vIds = await this.insert(acRequest, namespace, source);
|
|
305
320
|
|
|
306
|
-
const
|
|
307
|
-
namespaceId:
|
|
321
|
+
const dsData: IStorageVectorDataSource = {
|
|
322
|
+
namespaceId: formattedNs,
|
|
308
323
|
candidateId: acRequest.candidate.id,
|
|
309
324
|
candidateRole: acRequest.candidate.role,
|
|
310
|
-
name: datasource.label ||
|
|
311
|
-
metadata: JSON.stringify(datasource.metadata
|
|
325
|
+
name: datasource.label || 'Untitled',
|
|
326
|
+
metadata: datasource.metadata ? jsonrepair(JSON.stringify(datasource.metadata)) : undefined,
|
|
312
327
|
text: datasource.text,
|
|
313
|
-
vectorIds,
|
|
314
|
-
id:
|
|
328
|
+
vectorIds: _vIds,
|
|
329
|
+
id: dsId,
|
|
315
330
|
};
|
|
316
331
|
|
|
317
332
|
// Store datasource metadata in memory
|
|
318
|
-
if (!this.datasources[
|
|
319
|
-
this.datasources[
|
|
320
|
-
}
|
|
321
|
-
if (!this.datasources[preparedNs][datasourceId]) {
|
|
322
|
-
this.datasources[preparedNs][datasourceId] = storageDataSource;
|
|
323
|
-
} else {
|
|
324
|
-
this.datasources[preparedNs][datasourceId].vectorIds.push(...vectorIds);
|
|
333
|
+
if (!this.datasources[formattedNs]) {
|
|
334
|
+
this.datasources[formattedNs] = {};
|
|
325
335
|
}
|
|
336
|
+
this.datasources[formattedNs][dsId] = dsData;
|
|
326
337
|
|
|
327
|
-
return
|
|
338
|
+
return dsData;
|
|
328
339
|
}
|
|
329
340
|
|
|
330
341
|
@SecureConnector.AccessControl
|
|
331
342
|
protected async deleteDatasource(acRequest: AccessRequest, namespace: string, datasourceId: string): Promise<void> {
|
|
332
343
|
//const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
|
|
333
|
-
const
|
|
344
|
+
const formattedNs = this.constructNsName(acRequest.candidate as AccessCandidate, namespace);
|
|
334
345
|
|
|
335
|
-
//
|
|
336
|
-
|
|
337
|
-
|
|
346
|
+
// Get datasource info to get vector IDs
|
|
347
|
+
const ds = this.datasources[formattedNs]?.[datasourceId];
|
|
348
|
+
if (!ds) {
|
|
349
|
+
throw new Error(`Data source not found with id: ${datasourceId}`);
|
|
338
350
|
}
|
|
339
351
|
|
|
340
|
-
//
|
|
341
|
-
|
|
342
|
-
if (datasource) {
|
|
343
|
-
// Delete all vectors belonging to this datasource
|
|
344
|
-
if (this.vectors[preparedNs]) {
|
|
345
|
-
this.vectors[preparedNs] = this.vectors[preparedNs].filter((vector) => vector.datasource !== datasourceId);
|
|
346
|
-
}
|
|
347
|
-
}
|
|
352
|
+
// Delete all vectors belonging to this datasource using the delete method
|
|
353
|
+
await this.delete(acRequest, namespace, ds.vectorIds || []);
|
|
348
354
|
|
|
349
355
|
// Delete datasource metadata
|
|
350
|
-
if (this.datasources[
|
|
351
|
-
delete this.datasources[
|
|
356
|
+
if (this.datasources[formattedNs]) {
|
|
357
|
+
delete this.datasources[formattedNs][datasourceId];
|
|
352
358
|
}
|
|
353
359
|
}
|
|
354
360
|
|
|
@@ -362,15 +368,12 @@ export class RAMVectorDB extends VectorDBConnector {
|
|
|
362
368
|
}
|
|
363
369
|
|
|
364
370
|
@SecureConnector.AccessControl
|
|
365
|
-
protected async getDatasource(acRequest: AccessRequest, namespace: string, datasourceId: string): Promise<IStorageVectorDataSource> {
|
|
371
|
+
protected async getDatasource(acRequest: AccessRequest, namespace: string, datasourceId: string): Promise<IStorageVectorDataSource | undefined> {
|
|
366
372
|
//const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
|
|
367
373
|
const preparedNs = this.constructNsName(acRequest.candidate as AccessCandidate, namespace);
|
|
368
374
|
|
|
369
375
|
const datasource = this.datasources[preparedNs]?.[datasourceId];
|
|
370
|
-
|
|
371
|
-
throw new Error(`Datasource ${datasourceId} not found`);
|
|
372
|
-
}
|
|
373
|
-
return datasource;
|
|
376
|
+
return datasource; // Return undefined if not found, like MilvusVectorDB
|
|
374
377
|
}
|
|
375
378
|
|
|
376
379
|
/**
|
|
@@ -400,22 +403,4 @@ export class RAMVectorDB extends VectorDBConnector {
|
|
|
400
403
|
|
|
401
404
|
return dotProduct / (normA * normB);
|
|
402
405
|
}
|
|
403
|
-
|
|
404
|
-
/**
|
|
405
|
-
* Split text into chunks with overlap
|
|
406
|
-
*/
|
|
407
|
-
private splitTextIntoChunks(text: string, chunkSize: number, overlap: number): string[] {
|
|
408
|
-
const chunks: string[] = [];
|
|
409
|
-
let start = 0;
|
|
410
|
-
|
|
411
|
-
while (start < text.length) {
|
|
412
|
-
const end = Math.min(start + chunkSize, text.length);
|
|
413
|
-
chunks.push(text.slice(start, end));
|
|
414
|
-
|
|
415
|
-
if (end === text.length) break;
|
|
416
|
-
start = end - overlap;
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
return chunks;
|
|
420
|
-
}
|
|
421
406
|
}
|
|
@@ -50,7 +50,7 @@ export class GoogleEmbeds extends BaseEmbedding {
|
|
|
50
50
|
const modelInfo: TLLMModel = {
|
|
51
51
|
provider: 'GoogleAI',
|
|
52
52
|
modelId: this.model,
|
|
53
|
-
credentials: this.settings?.credentials as unknown as TLLMCredentials,
|
|
53
|
+
credentials: (this.settings?.credentials as unknown as TLLMCredentials) || [TLLMCredentials.Internal, TLLMCredentials.Vault],
|
|
54
54
|
};
|
|
55
55
|
const credentials = await getLLMCredentials(candidate, modelInfo);
|
|
56
56
|
apiKey = (credentials as BasicCredentials)?.apiKey;
|
|
@@ -82,7 +82,7 @@ export class OpenAIEmbeds extends BaseEmbedding {
|
|
|
82
82
|
const modelInfo: TLLMModel = {
|
|
83
83
|
provider: 'OpenAI',
|
|
84
84
|
modelId: this.model,
|
|
85
|
-
credentials: this.settings?.credentials as unknown as TLLMCredentials,
|
|
85
|
+
credentials: (this.settings?.credentials as unknown as TLLMCredentials) || [TLLMCredentials.Internal, TLLMCredentials.Vault],
|
|
86
86
|
};
|
|
87
87
|
const credentials = await getLLMCredentials(candidate, modelInfo);
|
|
88
88
|
|
|
@@ -127,6 +127,7 @@ export class LLMInference {
|
|
|
127
127
|
return this.llmConnector.user(AccessCandidate.agent(params.agentId)).imageEditRequest(params);
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
+
//@deprecated
|
|
130
131
|
public async streamRequest(params: any, agent: string | IAgent) {
|
|
131
132
|
const agentId = isAgent(agent) ? (agent as IAgent).id : agent;
|
|
132
133
|
try {
|
|
@@ -149,6 +150,7 @@ export class LLMInference {
|
|
|
149
150
|
}
|
|
150
151
|
}
|
|
151
152
|
|
|
153
|
+
//@deprecated
|
|
152
154
|
public async multimodalStreamRequest(params: any, fileSources, agent: string | IAgent) {
|
|
153
155
|
const agentId = isAgent(agent) ? (agent as IAgent).id : agent;
|
|
154
156
|
|
|
@@ -180,6 +182,7 @@ export class LLMInference {
|
|
|
180
182
|
}
|
|
181
183
|
}
|
|
182
184
|
|
|
185
|
+
//@deprecated
|
|
183
186
|
public async multimodalStreamRequestLegacy(prompt, files: string[], config: any = {}, agent: string | IAgent) {
|
|
184
187
|
const agentId = isAgent(agent) ? (agent as IAgent).id : agent;
|
|
185
188
|
|
package/src/subsystems/LLMManager/ModelsProvider.service/connectors/JSONModelsProvider.class.ts
CHANGED
|
@@ -14,6 +14,7 @@ import chokidar from 'chokidar';
|
|
|
14
14
|
import fs from 'fs/promises';
|
|
15
15
|
import fsSync from 'fs';
|
|
16
16
|
import path from 'path';
|
|
17
|
+
import { findSmythPath } from '@sre/helpers/Sysconfig.helper';
|
|
17
18
|
|
|
18
19
|
const console = Logger('SmythModelsProvider');
|
|
19
20
|
|
|
@@ -52,6 +53,10 @@ export class JSONModelsProvider extends ModelsProviderConnector {
|
|
|
52
53
|
else this.models = this._settings.models as TLLMModelsList;
|
|
53
54
|
this.started = true;
|
|
54
55
|
} else {
|
|
56
|
+
const modelsFolder = this.findModelsFolder();
|
|
57
|
+
if (modelsFolder) {
|
|
58
|
+
this.initDirWatcher(modelsFolder);
|
|
59
|
+
}
|
|
55
60
|
this.started = true;
|
|
56
61
|
}
|
|
57
62
|
}
|
|
@@ -59,6 +64,17 @@ export class JSONModelsProvider extends ModelsProviderConnector {
|
|
|
59
64
|
super.start();
|
|
60
65
|
}
|
|
61
66
|
|
|
67
|
+
private findModelsFolder() {
|
|
68
|
+
const _modelsFolder = findSmythPath('models');
|
|
69
|
+
|
|
70
|
+
if (fsSync.existsSync(_modelsFolder)) {
|
|
71
|
+
console.warn('Using default models folder : ', _modelsFolder);
|
|
72
|
+
return _modelsFolder;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
62
78
|
@SecureConnector.AccessControl
|
|
63
79
|
public async addModels(acRequest: AccessRequest, models: TLLMModelsList): Promise<void> {
|
|
64
80
|
await this.ready();
|
|
@@ -68,11 +68,11 @@ export const models = {
|
|
|
68
68
|
// keep the gpt-4o-mini as default model for now
|
|
69
69
|
'gpt-4o-mini': {
|
|
70
70
|
llm: 'OpenAI',
|
|
71
|
-
|
|
71
|
+
|
|
72
72
|
components: ['PromptGenerator', 'LLMAssistant', 'Classifier', 'VisionLLM', 'AgentPlugin', 'Chatbot', 'GPTPlugin', 'GenAILLM'],
|
|
73
73
|
|
|
74
74
|
label: 'GPT 4o Mini',
|
|
75
|
-
modelId: 'gpt-4o-mini
|
|
75
|
+
modelId: 'gpt-4o-mini',
|
|
76
76
|
provider: 'OpenAI',
|
|
77
77
|
features: ['text', 'tools', 'image', 'search'],
|
|
78
78
|
tags: ['Personal'],
|
|
@@ -74,8 +74,14 @@ export class JSONFileAccount extends AccountConnector {
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
public async isTeamMember(team: string, candidate: IAccessCandidate): Promise<boolean> {
|
|
77
|
+
if (team === DEFAULT_TEAM_ID) return true; //everyone is a member of the default team
|
|
78
|
+
|
|
77
79
|
if (!this.data[team]) return false;
|
|
78
80
|
|
|
81
|
+
if (candidate.role === TAccessRole.Team && team === candidate.id) {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
|
|
79
85
|
if (candidate.role === TAccessRole.User) {
|
|
80
86
|
return !!this.data[team].users?.[candidate.id];
|
|
81
87
|
} else if (candidate.role === TAccessRole.Agent) {
|
package/src/types/LLM.types.ts
CHANGED
|
@@ -221,7 +221,7 @@ export type TLLMModel = {
|
|
|
221
221
|
tokens: number;
|
|
222
222
|
completionTokens: number;
|
|
223
223
|
};
|
|
224
|
-
credentials?: TLLMCredentials;
|
|
224
|
+
credentials?: TLLMCredentials | TLLMCredentials[];
|
|
225
225
|
|
|
226
226
|
//models can come with predefined params
|
|
227
227
|
//this can also be used to pass a preconfigured model object
|