@smythos/sre 1.7.11 → 1.7.16

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 (39) hide show
  1. package/dist/index.js +48 -48
  2. package/dist/index.js.map +1 -1
  3. package/dist/types/Components/APICall/OAuth.helper.d.ts +1 -1
  4. package/dist/types/Core/ConnectorsService.d.ts +3 -1
  5. package/dist/types/Core/HookService.d.ts +18 -0
  6. package/dist/types/helpers/Conversation.helper.d.ts +3 -0
  7. package/dist/types/index.d.ts +7 -3
  8. package/dist/types/subsystems/ObservabilityManager/Log.service/LogConnector.d.ts +2 -1
  9. package/dist/types/subsystems/ObservabilityManager/Log.service/connectors/OTel/OTel.class.d.ts +59 -0
  10. package/dist/types/subsystems/ObservabilityManager/Log.service/connectors/OTel/OTelContextRegistry.d.ts +16 -0
  11. package/dist/types/subsystems/ObservabilityManager/Telemetry.service/TelemetryConnector.d.ts +13 -0
  12. package/dist/types/subsystems/ObservabilityManager/Telemetry.service/connectors/OTel/OTel.class.d.ts +59 -0
  13. package/dist/types/subsystems/ObservabilityManager/Telemetry.service/connectors/OTel/OTelContextRegistry.d.ts +16 -0
  14. package/dist/types/subsystems/ObservabilityManager/Telemetry.service/index.d.ts +4 -0
  15. package/dist/types/types/LLM.types.d.ts +3 -1
  16. package/dist/types/types/SRE.types.d.ts +5 -2
  17. package/package.json +9 -1
  18. package/src/Components/APICall/OAuth.helper.ts +24 -25
  19. package/src/Components/APICall/mimeTypeCategories.ts +16 -1
  20. package/src/Components/Component.class.ts +3 -1
  21. package/src/Core/ConnectorsService.ts +5 -1
  22. package/src/Core/HookService.ts +104 -12
  23. package/src/Core/boot.ts +3 -1
  24. package/src/helpers/Conversation.helper.ts +42 -15
  25. package/src/index.ts +7 -3
  26. package/src/index.ts.bak +7 -3
  27. package/src/subsystems/AgentManager/Agent.class.ts +9 -8
  28. package/src/subsystems/AgentManager/AgentRuntime.class.ts +4 -4
  29. package/src/subsystems/AgentManager/OSResourceMonitor.ts +69 -8
  30. package/src/subsystems/LLMManager/LLM.service/connectors/Echo.class.ts +1 -1
  31. package/src/subsystems/{IO → ObservabilityManager}/Log.service/LogConnector.ts +5 -1
  32. package/src/subsystems/{IO → ObservabilityManager}/Log.service/connectors/ConsoleLog.class.ts +3 -3
  33. package/src/subsystems/{IO → ObservabilityManager}/Log.service/index.ts +1 -2
  34. package/src/subsystems/ObservabilityManager/Telemetry.service/TelemetryConnector.ts +23 -0
  35. package/src/subsystems/ObservabilityManager/Telemetry.service/connectors/OTel/OTel.class.ts +759 -0
  36. package/src/subsystems/ObservabilityManager/Telemetry.service/connectors/OTel/OTelContextRegistry.ts +35 -0
  37. package/src/subsystems/ObservabilityManager/Telemetry.service/index.ts +12 -0
  38. package/src/types/LLM.types.ts +2 -0
  39. package/src/types/SRE.types.ts +4 -1
@@ -114,25 +114,119 @@ export function hook(hookName: string) {
114
114
  };
115
115
  }
116
116
 
117
+ // Store metadata about which methods should be auto-wrapped in child classes
118
+ // Maps constructor -> Map<methodName, {hookName, customContext}>
119
+ const hookableMethodsMetadata = new WeakMap<
120
+ any,
121
+ Map<string, { hookName: string; customContext?: Record<string, any> | ((instance: any) => Record<string, any>) }>
122
+ >();
123
+
124
+ /**
125
+ * Class decorator that automatically applies hookAsync to ALL child class methods
126
+ * that override parent methods decorated with hookAsync
127
+ *
128
+ * Usage:
129
+ * @hookableClass
130
+ * export class Component {
131
+ * @hookAsync('Component.process')
132
+ * async process(...) { ... }
133
+ *
134
+ * @hookAsync('Component.postProcess')
135
+ * async postProcess(...) { ... }
136
+ * }
137
+ */
138
+ export function hookableClass<T extends { new (...args: any[]): {} }>(constructor: T) {
139
+ return class extends constructor {
140
+ constructor(...args: any[]) {
141
+ super(...args);
142
+
143
+ // Get metadata for this class
144
+ const metadataMap = hookableMethodsMetadata.get(constructor);
145
+ if (!metadataMap) return; // No hooks to apply
146
+
147
+ const instance = this as any;
148
+ const childPrototype = Object.getPrototypeOf(instance);
149
+ const parentPrototype = constructor.prototype;
150
+
151
+ // Only process if this is a child class instance
152
+ if (childPrototype !== parentPrototype) {
153
+ // Apply hooks to all methods that have metadata
154
+ metadataMap.forEach((metadata, methodName) => {
155
+ // Get the method from the child prototype
156
+ const childMethod = childPrototype[methodName];
157
+ const parentMethod = parentPrototype[methodName];
158
+
159
+ // Check if child has overridden the method
160
+ if (childMethod && typeof childMethod === 'function' && childMethod !== parentMethod) {
161
+ // Get or create descriptor for the child method
162
+ let descriptor = Object.getOwnPropertyDescriptor(childPrototype, methodName);
163
+
164
+ // If not own property, create descriptor from the method
165
+ if (!descriptor) {
166
+ descriptor = {
167
+ value: childMethod,
168
+ writable: true,
169
+ enumerable: false,
170
+ configurable: true,
171
+ };
172
+ }
173
+
174
+ // Apply hookAsync decorator to child method
175
+ const modifiedDescriptor = hookAsync(metadata.hookName, metadata.customContext)(childPrototype, methodName, descriptor);
176
+
177
+ // Update the prototype with the modified descriptor
178
+ if (modifiedDescriptor && modifiedDescriptor.value) {
179
+ Object.defineProperty(childPrototype, methodName, {
180
+ value: modifiedDescriptor.value,
181
+ writable: true,
182
+ enumerable: false,
183
+ configurable: true,
184
+ });
185
+ }
186
+ }
187
+ });
188
+ }
189
+ }
190
+ } as T;
191
+ }
192
+
117
193
  /**
118
194
  * Decorator function that executes registered hooks asynchronously before and after the decorated method
195
+ * Automatically stores metadata for hookableClass decorator to enable automatic child class wrapping
119
196
  * @param hookName The name of the hook to trigger
120
197
  */
121
198
  export function hookAsync(hookName: string, customContext?: Record<string, any> | ((instance: any) => Record<string, any>)) {
122
199
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
123
200
  const originalMethod = descriptor.value;
124
201
 
202
+ // Store metadata for this hookable method (for hookableClass decorator)
203
+ if (!hookableMethodsMetadata.has(target.constructor)) {
204
+ hookableMethodsMetadata.set(target.constructor, new Map());
205
+ }
206
+ const metadataMap = hookableMethodsMetadata.get(target.constructor)!;
207
+ metadataMap.set(propertyKey, { hookName, customContext });
208
+
125
209
  descriptor.value = async function (...args: any[]) {
210
+ // Check if we're being called via super from a child class that has its own wrapper
211
+ // If this[propertyKey] is different from our wrapped method, a child has overridden it
212
+ const instanceMethod = (this as any)[propertyKey];
213
+ const isSuperCall = instanceMethod !== descriptor.value && instanceMethod !== originalMethod;
214
+
215
+ // If called via super from a wrapped child, skip hooks and call original method directly
216
+ // The child wrapper already handles hooks, so we just need parent logic
217
+ if (isSuperCall) {
218
+ return await originalMethod.apply(this, args);
219
+ }
220
+
126
221
  // Get additional context if contextFn is provided
127
222
  let _context;
128
223
  if (typeof customContext === 'function') {
129
- _context = await customContext(this);
224
+ _context = { instance: this, args: args, context: await customContext(this) };
130
225
  } else if (typeof customContext === 'object') {
131
- _context = customContext;
226
+ _context = { instance: this, args: args, context: customContext };
132
227
  } else {
133
- _context = this;
228
+ _context = { instance: this, args: args, context: {} };
134
229
  }
135
-
136
230
  // Execute non-blocking pre-hooks first (fire and forget)
137
231
  if (nonBlockingHooks[hookName]) {
138
232
  void Promise.allSettled(nonBlockingHooks[hookName].map((callback) => Promise.resolve(callback.apply(_context, args)))).catch((err) =>
@@ -186,7 +280,6 @@ export function hookAsync(hookName: string, customContext?: Record<string, any>
186
280
  return descriptor;
187
281
  };
188
282
  }
189
-
190
283
  /**
191
284
  * Decorator function that executes registered hooks asynchronously before the decorated method
192
285
  * @param hookName The name of the hook to trigger
@@ -200,11 +293,12 @@ export function hookAsyncWithContext(hookName: string, contextFn?: (instance: an
200
293
  // Get additional context if contextFn is provided
201
294
  const additionalContext = typeof contextFn === 'function' ? await contextFn(this) : {};
202
295
  const contextualArgs = [additionalContext, ...args];
296
+ const _context = { instance: this, args: args, context: additionalContext };
203
297
 
204
298
  // Execute non-blocking pre-hooks first (fire and forget)
205
299
  if (nonBlockingHooks[hookName]) {
206
300
  void Promise.allSettled(
207
- nonBlockingHooks[hookName].map((callback) => Promise.resolve().then(() => callback.apply(this, contextualArgs)))
301
+ nonBlockingHooks[hookName].map((callback) => Promise.resolve().then(() => callback.apply(_context, contextualArgs)))
208
302
  );
209
303
  }
210
304
 
@@ -214,7 +308,7 @@ export function hookAsyncWithContext(hookName: string, contextFn?: (instance: an
214
308
  try {
215
309
  // Execute blocking pre-hooks and wait for them
216
310
  if (blockingHooks[hookName]) {
217
- await Promise.all(blockingHooks[hookName].map((callback) => Promise.resolve(callback.apply(this, contextualArgs))));
311
+ await Promise.all(blockingHooks[hookName].map((callback) => Promise.resolve(callback.apply(_context, contextualArgs))));
218
312
  }
219
313
 
220
314
  // Call the original method
@@ -228,16 +322,14 @@ export function hookAsyncWithContext(hookName: string, contextFn?: (instance: an
228
322
  // Execute non-blocking after-hooks first (fire and forget)
229
323
  if (nonBlockingAfterHooks[hookName]) {
230
324
  void Promise.allSettled(
231
- nonBlockingAfterHooks[hookName].map((callback) =>
232
- Promise.resolve().then(() => callback({ result, args: contextualArgs, error }))
233
- )
234
- );
325
+ nonBlockingAfterHooks[hookName].map((callback) => Promise.resolve(callback.apply(_context, [{ result, args, error }])))
326
+ ).catch((err) => console.error(`Non-blocking after-hook ${hookName} error:`, err));
235
327
  }
236
328
 
237
329
  // Execute blocking after-hooks and wait for them
238
330
  if (blockingAfterHooks[hookName]) {
239
331
  await Promise.all(
240
- blockingAfterHooks[hookName].map((callback) => Promise.resolve(callback({ result, args: contextualArgs, error })))
332
+ blockingAfterHooks[hookName].map((callback) => Promise.resolve(callback.apply(_context, [{ result, args, error }])))
241
333
  );
242
334
  }
243
335
  } catch (afterHookError) {
package/src/Core/boot.ts CHANGED
@@ -12,11 +12,12 @@ import { CLIService } from '@sre/IO/CLI.service';
12
12
  import { NKVService } from '@sre/IO/NKV.service';
13
13
  import { RouterService } from '@sre/IO/Router.service';
14
14
  import { ManagedVaultService } from '@sre/Security/ManagedVault.service';
15
- import { LogService } from '@sre/IO/Log.service';
15
+ import { LogService } from '@sre/ObservabilityManager/Log.service';
16
16
  import { ComponentService } from '@sre/AgentManager/Component.service';
17
17
  import { ModelsProviderService } from '@sre/LLMManager/ModelsProvider.service';
18
18
  import { CodeService } from '@sre/ComputeManager/Code.service';
19
19
  import { SchedulerService } from '@sre/AgentManager/Scheduler.service';
20
+ import { TelemetryService } from '@sre/ObservabilityManager/Telemetry.service';
20
21
  const console = Logger('Boot');
21
22
  let _booted = false;
22
23
  export function boot() {
@@ -44,6 +45,7 @@ export function boot() {
44
45
  service.Component = new ComponentService();
45
46
  service.Code = new CodeService();
46
47
  service.Scheduler = new SchedulerService();
48
+ service.Telemetry = new TelemetryService();
47
49
 
48
50
  SystemEvents.on('SRE:Initialized', () => {
49
51
  console.debug('SRE Initialized');
@@ -38,6 +38,9 @@ type ToolParams = {
38
38
  //TODO: handle authentication
39
39
  export class Conversation extends EventEmitter {
40
40
  private _agentId: string = '';
41
+ public get agentId() {
42
+ return this._agentId;
43
+ }
41
44
  private _systemPrompt;
42
45
  private userDefinedSystemPrompt: string = '';
43
46
  public toolChoice: string = 'auto';
@@ -68,6 +71,11 @@ export class Conversation extends EventEmitter {
68
71
  private _agentVersion: string = undefined;
69
72
  public agentData: any;
70
73
 
74
+ private _id: string = '';
75
+ public get id() {
76
+ return this._id;
77
+ }
78
+
71
79
  public get context() {
72
80
  return this._context;
73
81
  }
@@ -128,6 +136,7 @@ export class Conversation extends EventEmitter {
128
136
  //TODO: handle loading previous session (messages)
129
137
  super();
130
138
 
139
+ this._id = 'conv_' + randomUUID();
131
140
  //this event listener avoids unhandled errors that can cause crashes
132
141
  this.on('error', (error) => {
133
142
  this._lastError = error;
@@ -310,6 +319,16 @@ export class Conversation extends EventEmitter {
310
319
  maxTokens = this.model.params.maxTokens;
311
320
  }
312
321
 
322
+ const llmReqUid = randomUUID();
323
+ this.emit(TLLMEvent.Requested, {
324
+ model: typeof this.model === 'string' ? this.model : this.model?.modelId,
325
+ contextWindow,
326
+ files,
327
+ maxTokens,
328
+ agentId: this._agentId,
329
+ requestId: llmReqUid,
330
+ });
331
+
313
332
  const eventEmitter: any = await llmInference
314
333
  .promptStream({
315
334
  contextWindow,
@@ -325,7 +344,7 @@ export class Conversation extends EventEmitter {
325
344
  })
326
345
  .catch((error) => {
327
346
  console.error('Error on promptStream: ', error);
328
- this.emit(TLLMEvent.Error, error);
347
+ this.emit(TLLMEvent.Error, error, { requestId: llmReqUid });
329
348
  });
330
349
 
331
350
  // remove listeners from llm event emitter to stop receiving stream data
@@ -338,20 +357,24 @@ export class Conversation extends EventEmitter {
338
357
  throw new Error('[LLM Request Error]');
339
358
  }
340
359
 
341
- if (message) this.emit('start');
342
- eventEmitter.on('data', (data) => {
343
- if (this.stop) return;
344
- this.emit('data', data);
345
- });
360
+ if (message) this.emit('start', { requestId: llmReqUid });
361
+ // eventEmitter.on(TLLMEvent.Data, (data) => {
362
+ // if (this.stop) return;
363
+ // this.emit('data', data);
364
+ // });
346
365
 
347
366
  eventEmitter.on(TLLMEvent.Thinking, (thinking) => {
348
367
  if (this.stop) return;
349
- this.emit(TLLMEvent.Thinking, thinking);
368
+ this.emit(TLLMEvent.Thinking, thinking, { requestId: llmReqUid });
350
369
  });
351
370
 
352
371
  eventEmitter.on(TLLMEvent.Data, (data) => {
353
372
  if (this.stop) return;
354
- this.emit(TLLMEvent.Data, data);
373
+ this.emit(TLLMEvent.Data, data, {
374
+ contextWindow,
375
+ requestId: llmReqUid,
376
+ model: typeof this.model === 'string' ? this.model : this.model?.modelId,
377
+ });
355
378
  });
356
379
 
357
380
  eventEmitter.on(TLLMEvent.Content, (content) => {
@@ -368,7 +391,7 @@ export class Conversation extends EventEmitter {
368
391
  // let s = true;
369
392
  // }
370
393
  _content += content;
371
- this.emit(TLLMEvent.Content, content);
394
+ this.emit(TLLMEvent.Content, content, { requestId: llmReqUid });
372
395
  });
373
396
 
374
397
  let finishReason = 'stop';
@@ -408,6 +431,9 @@ export class Conversation extends EventEmitter {
408
431
  toolsData.forEach((tool) => {
409
432
  tool.status = tool.name ? this._toolStatusMap?.[tool.name] : undefined;
410
433
  });
434
+ toolsData.content = _content;
435
+ toolsData.requestId = llmReqUid;
436
+ toolsData.contextWindow = contextWindow;
411
437
 
412
438
  llmMessage.tool_calls = toolsData.map((tool) => {
413
439
  return {
@@ -473,7 +499,7 @@ export class Conversation extends EventEmitter {
473
499
  this.emit('beforeToolCall', { tool, args }, llmMessage); //deprecated
474
500
 
475
501
  const status = tool.name ? this._toolStatusMap?.[tool.name] : undefined;
476
- this.emit(TLLMEvent.ToolCall, { tool, status, _llmRequest: llmMessage });
502
+ this.emit(TLLMEvent.ToolCall, { tool, status, _llmRequest: llmMessage, requestId: llmReqUid });
477
503
 
478
504
  const toolArgs = {
479
505
  type: tool?.type,
@@ -500,7 +526,7 @@ export class Conversation extends EventEmitter {
500
526
 
501
527
  //await afterFunctionCall(functionResponse, toolsData[tool.index]);
502
528
  this.emit('afterToolCall', { tool, args }, functionResponse); // Deprecated
503
- this.emit(TLLMEvent.ToolResult, { tool, result });
529
+ this.emit(TLLMEvent.ToolResult, { tool, result, requestId: llmReqUid });
504
530
 
505
531
  return { ...tool, result: functionResponse };
506
532
  }
@@ -542,7 +568,7 @@ export class Conversation extends EventEmitter {
542
568
  if (_finishReason) finishReason = _finishReason;
543
569
  if (usage_data) {
544
570
  //FIXME : normalize the usage data format
545
- this.emit(TLLMEvent.Usage, usage_data);
571
+ this.emit(TLLMEvent.Usage, usage_data, { requestId: llmReqUid });
546
572
  }
547
573
  if (hasError) return;
548
574
 
@@ -563,7 +589,7 @@ export class Conversation extends EventEmitter {
563
589
  const toolsContent = await toolsPromise.catch((error) => {
564
590
  console.error('Error in toolsPromise: ', error);
565
591
  //this.emit('error', error);
566
- this.emit(TLLMEvent.Error, error);
592
+ this.emit(TLLMEvent.Error, error, { requestId: llmReqUid });
567
593
  return '';
568
594
  });
569
595
  _content += toolsContent;
@@ -588,9 +614,9 @@ export class Conversation extends EventEmitter {
588
614
  //this._context.push({ role: 'assistant', content: content });
589
615
 
590
616
  if (finishReason !== 'stop') {
591
- this.emit(TLLMEvent.Interrupted, finishReason);
617
+ this.emit(TLLMEvent.Interrupted, finishReason, { requestId: llmReqUid });
592
618
  }
593
- this.emit(TLLMEvent.End);
619
+ this.emit(TLLMEvent.End, { requestId: llmReqUid });
594
620
  } else {
595
621
  //console.log('tool content', content);
596
622
  }
@@ -671,6 +697,7 @@ export class Conversation extends EventEmitter {
671
697
 
672
698
  reqConfig.headers['X-CACHE-ID'] = this._context?.llmCache?.id;
673
699
 
700
+ reqConfig.headers['X-REQUEST-TAG'] = this.id;
674
701
  /*
675
702
  * Objective for the following conditions:
676
703
  * - In case it is not a debug call and there is no monitor id, then we need to run the agent locally to reduce latency
package/src/index.ts CHANGED
@@ -130,8 +130,6 @@ export * from './subsystems/ComputeManager/Code.service/CodeConnector';
130
130
  export * from './subsystems/ComputeManager/Code.service/index';
131
131
  export * from './subsystems/IO/CLI.service/CLIConnector';
132
132
  export * from './subsystems/IO/CLI.service/index';
133
- export * from './subsystems/IO/Log.service/index';
134
- export * from './subsystems/IO/Log.service/LogConnector';
135
133
  export * from './subsystems/IO/NKV.service/index';
136
134
  export * from './subsystems/IO/NKV.service/NKVConnector';
137
135
  export * from './subsystems/IO/Router.service/index';
@@ -149,6 +147,10 @@ export * from './subsystems/LLMManager/ModelsProvider.service/ModelsProviderConn
149
147
  export * from './subsystems/MemoryManager/Cache.service/CacheConnector';
150
148
  export * from './subsystems/MemoryManager/Cache.service/index';
151
149
  export * from './subsystems/MemoryManager/LLMMemory.service/LLMMemoryConnector';
150
+ export * from './subsystems/ObservabilityManager/Log.service/index';
151
+ export * from './subsystems/ObservabilityManager/Log.service/LogConnector';
152
+ export * from './subsystems/ObservabilityManager/Telemetry.service/index';
153
+ export * from './subsystems/ObservabilityManager/Telemetry.service/TelemetryConnector';
152
154
  export * from './subsystems/Security/AccessControl/AccessCandidate.class';
153
155
  export * from './subsystems/Security/AccessControl/AccessRequest.class';
154
156
  export * from './subsystems/Security/AccessControl/ACL.class';
@@ -167,7 +169,6 @@ export * from './subsystems/AgentManager/AgentData.service/connectors/NullAgentD
167
169
  export * from './subsystems/AgentManager/Component.service/connectors/LocalComponentConnector.class';
168
170
  export * from './subsystems/AgentManager/Scheduler.service/connectors/LocalScheduler.class';
169
171
  export * from './subsystems/ComputeManager/Code.service/connectors/AWSLambdaCode.class';
170
- export * from './subsystems/IO/Log.service/connectors/ConsoleLog.class';
171
172
  export * from './subsystems/IO/NKV.service/connectors/NKVLocalStorage.class';
172
173
  export * from './subsystems/IO/NKV.service/connectors/NKVRAM.class';
173
174
  export * from './subsystems/IO/NKV.service/connectors/NKVRedis.class';
@@ -196,6 +197,7 @@ export * from './subsystems/MemoryManager/Cache.service/connectors/LocalStorageC
196
197
  export * from './subsystems/MemoryManager/Cache.service/connectors/RAMCache.class';
197
198
  export * from './subsystems/MemoryManager/Cache.service/connectors/RedisCache.class';
198
199
  export * from './subsystems/MemoryManager/Cache.service/connectors/S3Cache.class';
200
+ export * from './subsystems/ObservabilityManager/Log.service/connectors/ConsoleLog.class';
199
201
  export * from './subsystems/Security/Account.service/connectors/DummyAccount.class';
200
202
  export * from './subsystems/Security/Account.service/connectors/JSONFileAccount.class';
201
203
  export * from './subsystems/Security/Account.service/connectors/MySQLAccount.class';
@@ -207,5 +209,7 @@ export * from './subsystems/Security/Vault.service/connectors/NullVault.class';
207
209
  export * from './subsystems/Security/Vault.service/connectors/SecretsManager.class';
208
210
  export * from './subsystems/LLMManager/LLM.service/connectors/openai/OpenAIConnector.class';
209
211
  export * from './subsystems/LLMManager/LLM.service/connectors/openai/types';
212
+ export * from './subsystems/ObservabilityManager/Telemetry.service/connectors/OTel/OTel.class';
213
+ export * from './subsystems/ObservabilityManager/Telemetry.service/connectors/OTel/OTelContextRegistry';
210
214
  export * from './subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/constants';
211
215
  export * from './subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/utils';
package/src/index.ts.bak CHANGED
@@ -130,8 +130,6 @@ export * from './subsystems/ComputeManager/Code.service/CodeConnector';
130
130
  export * from './subsystems/ComputeManager/Code.service/index';
131
131
  export * from './subsystems/IO/CLI.service/CLIConnector';
132
132
  export * from './subsystems/IO/CLI.service/index';
133
- export * from './subsystems/IO/Log.service/index';
134
- export * from './subsystems/IO/Log.service/LogConnector';
135
133
  export * from './subsystems/IO/NKV.service/index';
136
134
  export * from './subsystems/IO/NKV.service/NKVConnector';
137
135
  export * from './subsystems/IO/Router.service/index';
@@ -149,6 +147,10 @@ export * from './subsystems/LLMManager/ModelsProvider.service/ModelsProviderConn
149
147
  export * from './subsystems/MemoryManager/Cache.service/CacheConnector';
150
148
  export * from './subsystems/MemoryManager/Cache.service/index';
151
149
  export * from './subsystems/MemoryManager/LLMMemory.service/LLMMemoryConnector';
150
+ export * from './subsystems/ObservabilityManager/Log.service/index';
151
+ export * from './subsystems/ObservabilityManager/Log.service/LogConnector';
152
+ export * from './subsystems/ObservabilityManager/Telemetry.service/index';
153
+ export * from './subsystems/ObservabilityManager/Telemetry.service/TelemetryConnector';
152
154
  export * from './subsystems/Security/AccessControl/AccessCandidate.class';
153
155
  export * from './subsystems/Security/AccessControl/AccessRequest.class';
154
156
  export * from './subsystems/Security/AccessControl/ACL.class';
@@ -167,7 +169,6 @@ export * from './subsystems/AgentManager/AgentData.service/connectors/NullAgentD
167
169
  export * from './subsystems/AgentManager/Component.service/connectors/LocalComponentConnector.class';
168
170
  export * from './subsystems/AgentManager/Scheduler.service/connectors/LocalScheduler.class';
169
171
  export * from './subsystems/ComputeManager/Code.service/connectors/AWSLambdaCode.class';
170
- export * from './subsystems/IO/Log.service/connectors/ConsoleLog.class';
171
172
  export * from './subsystems/IO/NKV.service/connectors/NKVLocalStorage.class';
172
173
  export * from './subsystems/IO/NKV.service/connectors/NKVRAM.class';
173
174
  export * from './subsystems/IO/NKV.service/connectors/NKVRedis.class';
@@ -196,6 +197,7 @@ export * from './subsystems/MemoryManager/Cache.service/connectors/LocalStorageC
196
197
  export * from './subsystems/MemoryManager/Cache.service/connectors/RAMCache.class';
197
198
  export * from './subsystems/MemoryManager/Cache.service/connectors/RedisCache.class';
198
199
  export * from './subsystems/MemoryManager/Cache.service/connectors/S3Cache.class';
200
+ export * from './subsystems/ObservabilityManager/Log.service/connectors/ConsoleLog.class';
199
201
  export * from './subsystems/Security/Account.service/connectors/DummyAccount.class';
200
202
  export * from './subsystems/Security/Account.service/connectors/JSONFileAccount.class';
201
203
  export * from './subsystems/Security/Account.service/connectors/MySQLAccount.class';
@@ -207,5 +209,7 @@ export * from './subsystems/Security/Vault.service/connectors/NullVault.class';
207
209
  export * from './subsystems/Security/Vault.service/connectors/SecretsManager.class';
208
210
  export * from './subsystems/LLMManager/LLM.service/connectors/openai/OpenAIConnector.class';
209
211
  export * from './subsystems/LLMManager/LLM.service/connectors/openai/types';
212
+ export * from './subsystems/ObservabilityManager/Telemetry.service/connectors/OTel/OTel.class';
213
+ export * from './subsystems/ObservabilityManager/Telemetry.service/connectors/OTel/OTelContextRegistry';
210
214
  export * from './subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/constants';
211
215
  export * from './subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/utils';
@@ -16,7 +16,7 @@ import { Trigger } from '@sre/Components/Triggers/Trigger.class';
16
16
  import { IAgent } from '@sre/types/Agent.types';
17
17
  import { AgentSSE } from './AgentSSE.class';
18
18
 
19
- const console = Logger('Agent');
19
+ const logger = Logger('Agent');
20
20
  const idPromise = (id) => id;
21
21
  const MAX_LATENCY = 50;
22
22
 
@@ -169,7 +169,7 @@ export class Agent implements IAgent {
169
169
  this._componentInstancesLoader.resolve(true);
170
170
  });
171
171
  } catch (error) {
172
- console.warn('Could not load custom components', AccessCandidate.agent(this.id));
172
+ logger.warn('Could not load custom components', AccessCandidate.agent(this.id));
173
173
  this._componentInstancesLoader.reject('Could not load custom components');
174
174
  }
175
175
 
@@ -329,9 +329,10 @@ export class Agent implements IAgent {
329
329
  step = await this.agentRuntime.runCycle();
330
330
 
331
331
  //adjust latency based on cpu load
332
- const qosLatency = Math.floor(OSResourceMonitor.cpu.load * MAX_LATENCY || 0);
332
+ const qosLatency = Math.floor((OSResourceMonitor.cpu.load / 100) * MAX_LATENCY || 0);
333
333
 
334
- await delay(10 + qosLatency);
334
+ await delay(qosLatency);
335
+ await new Promise((resolve) => setImmediate(resolve)); // yield to the event loop to prevent blocking other operations
335
336
  } while (!step?.finalResult && !this._killReason);
336
337
 
337
338
  if (this._killReason) {
@@ -349,7 +350,7 @@ export class Agent implements IAgent {
349
350
  input,
350
351
  error: 'Agent killed',
351
352
  });
352
- console.warn(`Agent ${this.id} was killed`, AccessCandidate.agent(this.id));
353
+ logger.warn(`Agent ${this.id} was killed`, AccessCandidate.agent(this.id));
353
354
  return { error: 'AGENT_KILLED', reason: this._killReason };
354
355
  }
355
356
  result = await this.postProcess(step?.finalResult).catch((error) => ({ error }));
@@ -590,7 +591,7 @@ export class Agent implements IAgent {
590
591
  });
591
592
 
592
593
  if (this._killReason) {
593
- console.warn(`Agent ${this.id} was killed, skipping component ${componentData.name}`, AccessCandidate.agent(this.id));
594
+ logger.warn(`Agent ${this.id} was killed, skipping component ${componentData.name}`, AccessCandidate.agent(this.id));
594
595
 
595
596
  const output = { id: componentData.id, name: componentData.displayName, result: null, error: 'Agent killed' };
596
597
 
@@ -714,10 +715,10 @@ export class Agent implements IAgent {
714
715
  await this.parseVariables(); //make sure that any vault variable is loaded before processing the component
715
716
  //TODO: apply type inference here instead of in the component .process method
716
717
  output = await component.process({ ...this.agentVariables, ..._input }, { ...componentData, eventId }, this);
717
- console.debug(output, AccessCandidate.agent(this.id));
718
+ logger.debug(output, AccessCandidate.agent(this.id));
718
719
  } catch (error: any) {
719
720
  //this are fatal errors requiring to cancel the execution of this component.
720
- console.error(
721
+ logger.error(
721
722
  'Error on component process: ',
722
723
  { componentId, name: componentData.name, input: _input },
723
724
  error,
@@ -7,7 +7,7 @@ import { RuntimeContext } from '@sre/MemoryManager/RuntimeContext';
7
7
  import { AccessCandidate } from '@sre/Security/AccessControl/AccessCandidate.class';
8
8
  import { uid } from '@sre/utils';
9
9
 
10
- const console = Logger('AgentRuntime');
10
+ const logger = Logger('AgentRuntime');
11
11
  const AgentRuntimeUnavailable = new Proxy(
12
12
  {},
13
13
  {
@@ -18,7 +18,7 @@ const AgentRuntimeUnavailable = new Proxy(
18
18
  } else {
19
19
  // Return a function that logs "unavailable"
20
20
  return function () {
21
- console.warn(`AgentRuntime Unavailable tried to call : ${prop.toString()}`);
21
+ logger.warn(`AgentRuntime Unavailable tried to call : ${prop.toString()}`);
22
22
  };
23
23
  }
24
24
  },
@@ -150,7 +150,7 @@ export class AgentRuntime {
150
150
  for (let component of this.agent.data.components) {
151
151
  const cpt: Component = this.agent.ComponentInstances[component.name];
152
152
  if (!cpt) {
153
- console.warn(`Component ${component.name} Exists in agent but has no implementation`, AccessCandidate.agent(this.agent.id));
153
+ logger.warn(`Component ${component.name} Exists in agent but has no implementation`, AccessCandidate.agent(this.agent.id));
154
154
  continue;
155
155
  }
156
156
 
@@ -316,7 +316,7 @@ export class AgentRuntime {
316
316
  * @returns
317
317
  */
318
318
  public async runCycle() {
319
- console.debug(
319
+ logger.debug(
320
320
  `runCycle agentId=${this.agent.id} wfReqId=${this.workflowReqId} reqTag=${this.reqTag} session=${this.xDebugRun} cycleId=${this.processID}`,
321
321
  AccessCandidate.agent(this.agent.id)
322
322
  );
@@ -1,12 +1,34 @@
1
1
  import os from 'os';
2
2
  import process from 'process';
3
3
 
4
- const OSResourceMonitor: any = {
4
+ // Store previous CPU times for delta calculation
5
+ let previousCpuTimes: { user: number; nice: number; sys: number; idle: number; irq: number } | null = null;
6
+
7
+ const monitorData: any = {
5
8
  mem: getMemoryUsage(),
6
- //processMemory: getProcessMemoryUsage(),
7
9
  cpu: getCpuUsage(),
10
+ //processMemory: getProcessMemoryUsage(),
8
11
  //processCpu: getProcessCpuUsage(),
9
12
  };
13
+
14
+ const itv = setInterval(() => {
15
+ monitorData.mem = getMemoryUsage();
16
+ monitorData.cpu = getCpuUsage();
17
+ //monitorData.processMemory = getProcessMemoryUsage();
18
+ //monitorData.processCpu = getProcessCpuUsage();
19
+ }, 5000);
20
+
21
+ itv.unref();
22
+
23
+ const OSResourceMonitor: any = {
24
+ get mem() {
25
+ return monitorData.mem;
26
+ },
27
+ get cpu() {
28
+ return monitorData.cpu;
29
+ },
30
+ };
31
+
10
32
  export { OSResourceMonitor };
11
33
 
12
34
  function getCpuUsage() {
@@ -16,8 +38,8 @@ function getCpuUsage() {
16
38
  let sys = 0;
17
39
  let idle = 0;
18
40
  let irq = 0;
19
- let total = 0;
20
41
 
42
+ // Sum up times across all CPU cores
21
43
  for (let cpu of cpus) {
22
44
  user += cpu.times.user;
23
45
  nice += cpu.times.nice;
@@ -26,13 +48,52 @@ function getCpuUsage() {
26
48
  irq += cpu.times.irq;
27
49
  }
28
50
 
29
- total = user + nice + sys + idle + irq;
51
+ const currentTimes = { user, nice, sys, idle, irq };
52
+
53
+ // If this is the first measurement, store it and return zero load
54
+ if (!previousCpuTimes) {
55
+ previousCpuTimes = currentTimes;
56
+ return {
57
+ user: 0,
58
+ sys: 0,
59
+ idle: 100,
60
+ load: 0,
61
+ };
62
+ }
63
+
64
+ // Calculate deltas since last measurement
65
+ const userDelta = currentTimes.user - previousCpuTimes.user;
66
+ const niceDelta = currentTimes.nice - previousCpuTimes.nice;
67
+ const sysDelta = currentTimes.sys - previousCpuTimes.sys;
68
+ const idleDelta = currentTimes.idle - previousCpuTimes.idle;
69
+ const irqDelta = currentTimes.irq - previousCpuTimes.irq;
70
+
71
+ const totalDelta = userDelta + niceDelta + sysDelta + idleDelta + irqDelta;
72
+
73
+ // Store current times for next calculation
74
+ previousCpuTimes = currentTimes;
75
+
76
+ // Avoid division by zero
77
+ if (totalDelta === 0) {
78
+ return {
79
+ user: 0,
80
+ sys: 0,
81
+ idle: 100,
82
+ load: 0,
83
+ };
84
+ }
85
+
86
+ // Calculate percentages based on delta (actual usage since last check)
87
+ const userPercent = (userDelta / totalDelta) * 100;
88
+ const sysPercent = (sysDelta / totalDelta) * 100;
89
+ const idlePercent = (idleDelta / totalDelta) * 100;
90
+ const loadPercent = 100 - idlePercent;
30
91
 
31
92
  return {
32
- user: (user / total) * 100,
33
- sys: (sys / total) * 100,
34
- idle: (idle / total) * 100,
35
- load: 100 - (idle / total) * 100,
93
+ user: Math.round(userPercent * 100) / 100, // Round to 2 decimals
94
+ sys: Math.round(sysPercent * 100) / 100,
95
+ idle: Math.round(idlePercent * 100) / 100,
96
+ load: Math.round(loadPercent * 100) / 100,
36
97
  };
37
98
  }
38
99
 
@@ -49,7 +49,7 @@ export class EchoConnector extends LLMConnector {
49
49
 
50
50
  for (let i = 0; i < chunks.length; i++) {
51
51
  // Simulate network delay
52
- await delay(10);
52
+ await delay(3);
53
53
 
54
54
  const isLastChunk = i === chunks.length - 1;
55
55
  // Add space between chunks except for the last one to avoid trailing space in file URLs