@smythos/sre 1.5.74 → 1.6.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 (32) hide show
  1. package/CHANGELOG +16 -10
  2. package/dist/index.js +8 -8
  3. package/dist/index.js.map +1 -1
  4. package/dist/types/Components/Component.class.d.ts +16 -2
  5. package/dist/types/helpers/AIPerformanceAnalyzer.helper.d.ts +45 -0
  6. package/dist/types/helpers/AIPerformanceCollector.helper.d.ts +111 -0
  7. package/dist/types/helpers/Conversation.helper.d.ts +1 -0
  8. package/dist/types/index.d.ts +1 -1
  9. package/dist/types/subsystems/IO/VectorDB.service/connectors/MilvusVectorDB.class.d.ts +7 -1
  10. package/dist/types/subsystems/IO/VectorDB.service/connectors/PineconeVectorDB.class.d.ts +1 -1
  11. package/dist/types/subsystems/IO/VectorDB.service/connectors/RAMVecrtorDB.class.d.ts +8 -5
  12. package/dist/types/subsystems/IO/VectorDB.service/connectors/WeaviateVectorDB.class.d.ts +187 -0
  13. package/dist/types/subsystems/MemoryManager/RuntimeContext.d.ts +1 -0
  14. package/dist/types/subsystems/PerformanceManager/Performance.service/PerformanceConnector.d.ts +102 -0
  15. package/dist/types/subsystems/PerformanceManager/Performance.service/connectors/LocalPerformanceConnector.class.d.ts +100 -0
  16. package/dist/types/subsystems/PerformanceManager/Performance.service/index.d.ts +22 -0
  17. package/dist/types/subsystems/Security/Account.service/connectors/MySQLAccount.class.d.ts +19 -0
  18. package/dist/types/types/Performance.types.d.ts +468 -0
  19. package/package.json +1 -1
  20. package/src/Components/Component.class.ts +16 -2
  21. package/src/helpers/Conversation.helper.ts +9 -1
  22. package/src/index.ts +1 -1
  23. package/src/index.ts.bak +1 -1
  24. package/src/subsystems/IO/Storage.service/SmythFS.class.ts +3 -4
  25. package/src/subsystems/IO/VectorDB.service/connectors/MilvusVectorDB.class.ts +12 -1
  26. package/src/subsystems/IO/VectorDB.service/connectors/PineconeVectorDB.class.ts +4 -1
  27. package/src/subsystems/IO/VectorDB.service/connectors/RAMVecrtorDB.class.ts +48 -46
  28. package/src/subsystems/MemoryManager/Cache.service/connectors/RAMCache.class.ts +14 -1
  29. package/src/subsystems/MemoryManager/RuntimeContext.ts +9 -2
  30. package/src/subsystems/Security/Account.service/connectors/JSONFileAccount.class.ts +6 -1
  31. package/src/subsystems/Security/Account.service/connectors/{AWSAccount.class.ts → MySQLAccount.class.ts} +3 -3
  32. package/src/subsystems/Security/Account.service/index.ts +2 -2
@@ -34,7 +34,10 @@ interface VectorData {
34
34
  }
35
35
 
36
36
  export type RAMVectorDBConfig = {
37
- embeddings: TEmbeddings;
37
+ /**
38
+ * The embeddings model to use
39
+ */
40
+ embeddings?: TEmbeddings;
38
41
  };
39
42
 
40
43
  /**
@@ -53,11 +56,13 @@ export class RAMVectorDB extends VectorDBConnector {
53
56
  private accountConnector: AccountConnector;
54
57
  //private embeddingsProvider: OpenAIEmbeds;
55
58
 
56
- // In-memory storage
57
- private vectors: Record<string, VectorData[]> = {};
58
- private namespaces: Record<string, IStorageVectorNamespace> = {};
59
- private datasources: Record<string, Record<string, IStorageVectorDataSource>> = {};
60
- private acls: Record<string, IACL> = {};
59
+ // In-memory storage (shared across connector instances)
60
+ private static vectors: Record<string, VectorData[]> = {};
61
+ private static namespaces: Record<string, IStorageVectorNamespace> = {};
62
+ private static datasources: Record<string, Record<string, IStorageVectorDataSource>> = {};
63
+ private static acls: Record<string, IACL> = {};
64
+
65
+ //embedder
61
66
  public embedder: BaseEmbedding;
62
67
 
63
68
  constructor(protected _settings: RAMVectorDBConfig) {
@@ -77,7 +82,7 @@ export class RAMVectorDB extends VectorDBConnector {
77
82
  public async getResourceACL(resourceId: string, candidate: IAccessCandidate): Promise<ACL> {
78
83
  //const teamId = await this.accountConnector.getCandidateTeam(AccessCandidate.clone(candidate));
79
84
  const preparedNs = this.constructNsName(candidate as AccessCandidate, resourceId);
80
- const acl = this.acls[preparedNs];
85
+ const acl = RAMVectorDB.acls[preparedNs];
81
86
  const exists = !!acl;
82
87
 
83
88
  if (!exists) {
@@ -92,7 +97,7 @@ export class RAMVectorDB extends VectorDBConnector {
92
97
  //const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
93
98
  const preparedNs = this.constructNsName(acRequest.candidate as AccessCandidate, namespace);
94
99
 
95
- if (!this.namespaces[preparedNs]) {
100
+ if (!RAMVectorDB.namespaces[preparedNs]) {
96
101
  const nsData = {
97
102
  namespace: preparedNs,
98
103
  displayName: namespace,
@@ -105,18 +110,18 @@ export class RAMVectorDB extends VectorDBConnector {
105
110
  };
106
111
 
107
112
  // Store namespace metadata in memory
108
- this.namespaces[preparedNs] = nsData;
113
+ RAMVectorDB.namespaces[preparedNs] = nsData;
109
114
 
110
115
  // Initialize namespace vectors storage
111
- this.vectors[preparedNs] = [];
116
+ RAMVectorDB.vectors[preparedNs] = [];
112
117
 
113
118
  // Initialize datasources storage for this namespace
114
- this.datasources[preparedNs] = {};
119
+ RAMVectorDB.datasources[preparedNs] = {};
115
120
  }
116
121
 
117
122
  // Store ACL in memory
118
123
  const acl = new ACL().addAccess(acRequest.candidate.role, acRequest.candidate.id, TAccessLevel.Owner).ACL;
119
- this.acls[preparedNs] = acl;
124
+ RAMVectorDB.acls[preparedNs] = acl;
120
125
 
121
126
  return new Promise<void>((resolve) => resolve());
122
127
  }
@@ -125,14 +130,14 @@ export class RAMVectorDB extends VectorDBConnector {
125
130
  protected async namespaceExists(acRequest: AccessRequest, namespace: string): Promise<boolean> {
126
131
  //const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
127
132
  const preparedNs = this.constructNsName(acRequest.candidate as AccessCandidate, namespace);
128
- return !!this.namespaces[preparedNs];
133
+ return !!RAMVectorDB.namespaces[preparedNs];
129
134
  }
130
135
 
131
136
  @SecureConnector.AccessControl
132
137
  protected async getNamespace(acRequest: AccessRequest, namespace: string): Promise<IStorageVectorNamespace> {
133
138
  //const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
134
139
  const preparedNs = this.constructNsName(acRequest.candidate as AccessCandidate, namespace);
135
- const nsData = this.namespaces[preparedNs];
140
+ const nsData = RAMVectorDB.namespaces[preparedNs];
136
141
  if (!nsData) {
137
142
  throw new Error(`Namespace ${namespace} not found`);
138
143
  }
@@ -144,7 +149,7 @@ export class RAMVectorDB extends VectorDBConnector {
144
149
  //const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
145
150
 
146
151
  // Filter namespaces by team
147
- return Object.values(this.namespaces).filter((ns) => ns.candidateId === acRequest.candidate.id);
152
+ return Object.values(RAMVectorDB.namespaces).filter((ns) => ns.candidateId === acRequest.candidate.id);
148
153
  }
149
154
 
150
155
  @SecureConnector.AccessControl
@@ -153,10 +158,10 @@ export class RAMVectorDB extends VectorDBConnector {
153
158
  const preparedNs = this.constructNsName(acRequest.candidate as AccessCandidate, namespace);
154
159
 
155
160
  // Delete from memory
156
- delete this.vectors[preparedNs];
157
- delete this.namespaces[preparedNs];
158
- delete this.datasources[preparedNs];
159
- delete this.acls[preparedNs];
161
+ delete RAMVectorDB.vectors[preparedNs];
162
+ delete RAMVectorDB.namespaces[preparedNs];
163
+ delete RAMVectorDB.datasources[preparedNs];
164
+ delete RAMVectorDB.acls[preparedNs];
160
165
  }
161
166
 
162
167
  @SecureConnector.AccessControl
@@ -169,7 +174,7 @@ export class RAMVectorDB extends VectorDBConnector {
169
174
  //const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
170
175
  const preparedNs = this.constructNsName(acRequest.candidate as AccessCandidate, namespace);
171
176
 
172
- if (!this.namespaces[preparedNs]) {
177
+ if (!RAMVectorDB.namespaces[preparedNs]) {
173
178
  throw new Error('Namespace does not exist');
174
179
  }
175
180
 
@@ -180,7 +185,7 @@ export class RAMVectorDB extends VectorDBConnector {
180
185
  }
181
186
 
182
187
  // Search in namespace data
183
- const namespaceData = this.vectors[preparedNs] || [];
188
+ const namespaceData = RAMVectorDB.vectors[preparedNs] || [];
184
189
  const results: Array<{ id: string; score: number; values: number[]; metadata?: any; text: string }> = [];
185
190
 
186
191
  for (const vector of namespaceData) {
@@ -236,8 +241,8 @@ export class RAMVectorDB extends VectorDBConnector {
236
241
 
237
242
  const transformedSource = await this.embedder.transformSource(sourceWrapper, sourceType, acRequest.candidate as AccessCandidate);
238
243
 
239
- if (!this.vectors[preparedNs]) {
240
- this.vectors[preparedNs] = [];
244
+ if (!RAMVectorDB.vectors[preparedNs]) {
245
+ RAMVectorDB.vectors[preparedNs] = [];
241
246
  }
242
247
 
243
248
  const insertedIds: string[] = [];
@@ -251,11 +256,11 @@ export class RAMVectorDB extends VectorDBConnector {
251
256
  };
252
257
 
253
258
  // Check if vector with this ID already exists and update it
254
- const existingIndex = this.vectors[preparedNs].findIndex((v) => v.id === source.id);
259
+ const existingIndex = RAMVectorDB.vectors[preparedNs].findIndex((v) => v.id === source.id);
255
260
  if (existingIndex >= 0) {
256
- this.vectors[preparedNs][existingIndex] = vectorData;
261
+ RAMVectorDB.vectors[preparedNs][existingIndex] = vectorData;
257
262
  } else {
258
- this.vectors[preparedNs].push(vectorData);
263
+ RAMVectorDB.vectors[preparedNs].push(vectorData);
259
264
  }
260
265
 
261
266
  insertedIds.push(source.id);
@@ -274,8 +279,10 @@ export class RAMVectorDB extends VectorDBConnector {
274
279
  if (isDeleteByFilter) {
275
280
  // Handle delete by filter (e.g., by datasourceId)
276
281
  if ('datasourceId' in deleteTarget && deleteTarget.datasourceId) {
277
- if (this.vectors[preparedNs]) {
278
- this.vectors[preparedNs] = this.vectors[preparedNs].filter((vector) => vector.datasource !== deleteTarget.datasourceId);
282
+ if (RAMVectorDB.vectors[preparedNs]) {
283
+ RAMVectorDB.vectors[preparedNs] = RAMVectorDB.vectors[preparedNs].filter(
284
+ (vector) => vector.datasource !== deleteTarget.datasourceId
285
+ );
279
286
  }
280
287
  } else {
281
288
  throw new Error('Unsupported delete filter');
@@ -283,8 +290,8 @@ export class RAMVectorDB extends VectorDBConnector {
283
290
  } else {
284
291
  // Handle delete by ID(s)
285
292
  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));
293
+ if (RAMVectorDB.vectors[preparedNs]) {
294
+ RAMVectorDB.vectors[preparedNs] = RAMVectorDB.vectors[preparedNs].filter((vector) => !ids.includes(vector.id));
288
295
  }
289
296
  }
290
297
  }
@@ -330,10 +337,10 @@ export class RAMVectorDB extends VectorDBConnector {
330
337
  };
331
338
 
332
339
  // Store datasource metadata in memory
333
- if (!this.datasources[formattedNs]) {
334
- this.datasources[formattedNs] = {};
340
+ if (!RAMVectorDB.datasources[formattedNs]) {
341
+ RAMVectorDB.datasources[formattedNs] = {};
335
342
  }
336
- this.datasources[formattedNs][dsId] = dsData;
343
+ RAMVectorDB.datasources[formattedNs][dsId] = dsData;
337
344
 
338
345
  return dsData;
339
346
  }
@@ -343,18 +350,13 @@ export class RAMVectorDB extends VectorDBConnector {
343
350
  //const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
344
351
  const formattedNs = this.constructNsName(acRequest.candidate as AccessCandidate, namespace);
345
352
 
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}`);
350
- }
351
-
352
- // Delete all vectors belonging to this datasource using the delete method
353
- await this.delete(acRequest, namespace, ds.vectorIds || []);
353
+ // Delete all vectors belonging to this datasource using a filter by datasourceId,
354
+ // so we remove vectors from any prior insert/update operations sharing the same datasource id
355
+ await this.delete(acRequest, namespace, { datasourceId });
354
356
 
355
- // Delete datasource metadata
356
- if (this.datasources[formattedNs]) {
357
- delete this.datasources[formattedNs][datasourceId];
357
+ // Delete datasource metadata (if present)
358
+ if (RAMVectorDB.datasources[formattedNs] && RAMVectorDB.datasources[formattedNs][datasourceId]) {
359
+ delete RAMVectorDB.datasources[formattedNs][datasourceId];
358
360
  }
359
361
  }
360
362
 
@@ -363,7 +365,7 @@ export class RAMVectorDB extends VectorDBConnector {
363
365
  //const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
364
366
  const preparedNs = this.constructNsName(acRequest.candidate as AccessCandidate, namespace);
365
367
 
366
- const namespaceDatasources = this.datasources[preparedNs] || {};
368
+ const namespaceDatasources = RAMVectorDB.datasources[preparedNs] || {};
367
369
  return Object.values(namespaceDatasources);
368
370
  }
369
371
 
@@ -372,7 +374,7 @@ export class RAMVectorDB extends VectorDBConnector {
372
374
  //const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
373
375
  const preparedNs = this.constructNsName(acRequest.candidate as AccessCandidate, namespace);
374
376
 
375
- const datasource = this.datasources[preparedNs]?.[datasourceId];
377
+ const datasource = RAMVectorDB.datasources[preparedNs]?.[datasourceId];
376
378
  return datasource; // Return undefined if not found, like MilvusVectorDB
377
379
  }
378
380
 
@@ -129,7 +129,20 @@ export class RAMCache extends CacheConnector {
129
129
  const entry = this.cache.get(fullMetadataKey);
130
130
 
131
131
  if (entry) {
132
- entry.metadata = metadata;
132
+ const existingMetadata = entry.metadata || {};
133
+ const existingAcl = existingMetadata?.acl;
134
+ const mergedMetadata: CacheMetadata = { ...existingMetadata, ...metadata } as CacheMetadata;
135
+
136
+ // Preserve or establish ACL; always ensure requester retains ownership
137
+ if (existingAcl) {
138
+ mergedMetadata.acl = ACL.from(existingAcl).addAccess(acRequest.candidate.role, acRequest.candidate.id, TAccessLevel.Owner).ACL;
139
+ } else if (mergedMetadata.acl) {
140
+ mergedMetadata.acl = ACL.from(mergedMetadata.acl).addAccess(acRequest.candidate.role, acRequest.candidate.id, TAccessLevel.Owner).ACL;
141
+ } else {
142
+ mergedMetadata.acl = new ACL().addAccess(acRequest.candidate.role, acRequest.candidate.id, TAccessLevel.Owner).ACL;
143
+ }
144
+
145
+ entry.metadata = mergedMetadata;
133
146
  this.cache.set(fullMetadataKey, entry);
134
147
  }
135
148
  }
@@ -36,6 +36,7 @@ export class RuntimeContext extends EventEmitter {
36
36
  private _cacheConnector: CacheConnector;
37
37
 
38
38
  private _readyPromise: Promise<boolean>;
39
+ private _lastCtxLength: number = 0;
39
40
 
40
41
  constructor(private runtime: AgentRuntime) {
41
42
  super();
@@ -153,7 +154,13 @@ export class RuntimeContext extends EventEmitter {
153
154
  //if (data) fs.writeFileSync(this.ctxFile, JSON.stringify(data, null, 2));
154
155
  if (data) {
155
156
  let serializedData = JSON.stringify(data);
156
- console.debug('Agent Context Size', this.ctxFile, serializedData.length, AccessCandidate.agent(this.runtime.agent.id));
157
+
158
+ if (serializedData.length != this._lastCtxLength) {
159
+ //only log if context has changes
160
+ //We use the length as a weak but fast way to detect changes
161
+ console.debug('Agent Context Size', this.ctxFile, serializedData.length, AccessCandidate.agent(this.runtime.agent.id));
162
+ this._lastCtxLength = serializedData.length;
163
+ }
157
164
 
158
165
  await this._cacheConnector
159
166
  .requester(AccessCandidate.agent(this.runtime.agent.id))
@@ -184,7 +191,7 @@ export class RuntimeContext extends EventEmitter {
184
191
 
185
192
  public enqueueSync() {
186
193
  if (!this.ctxFile) return;
187
- console.log('ENQUEUE SYNC');
194
+
188
195
  this._syncQueue = this._syncQueue
189
196
  .then(() => this.sync())
190
197
  .catch((err) => {
@@ -74,7 +74,12 @@ 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
77
+ if (team === DEFAULT_TEAM_ID) {
78
+ //non existing user
79
+ if (candidate.role === TAccessRole.User && !this.data[team].users?.[candidate.id]) return false;
80
+
81
+ return true; //everyone is a member of the default team
82
+ }
78
83
 
79
84
  if (!this.data[team]) return false;
80
85
 
@@ -4,9 +4,9 @@ import { AccessRequest } from '@sre/Security/AccessControl/AccessRequest.class';
4
4
  import { DEFAULT_TEAM_ID, IAccessCandidate, IACL, TAccessRole } from '@sre/types/ACL.types';
5
5
  import { AccountConnector } from '../AccountConnector';
6
6
  import { KeyValueObject } from '@sre/types/Common.types';
7
-
8
- export class AWSAccount extends AccountConnector {
9
- public name = 'AWSAccount';
7
+ //FIXME : this implementation is experimental and incomplete
8
+ export class MySQLAccount extends AccountConnector {
9
+ public name = 'MySQLAccount';
10
10
 
11
11
  private pool: mysql.Pool;
12
12
 
@@ -3,11 +3,11 @@
3
3
  import { ConnectorService, ConnectorServiceProvider } from '@sre/Core/ConnectorsService';
4
4
  import { TConnectorService } from '@sre/types/SRE.types';
5
5
  import { DummyAccount } from './connectors/DummyAccount.class';
6
- import { AWSAccount } from './connectors/AWSAccount.class';
6
+ import { MySQLAccount } from './connectors/MySQLAccount.class';
7
7
  import { JSONFileAccount } from './connectors/JSONFileAccount.class';
8
8
  export class AccountService extends ConnectorServiceProvider {
9
9
  public register() {
10
- ConnectorService.register(TConnectorService.Account, 'AWSAccount', AWSAccount);
10
+ ConnectorService.register(TConnectorService.Account, 'MySQLAccount', MySQLAccount);
11
11
  ConnectorService.register(TConnectorService.Account, 'DummyAccount', DummyAccount);
12
12
  ConnectorService.register(TConnectorService.Account, 'JSONFileAccount', JSONFileAccount);
13
13
  }