@smythos/sre 1.6.14 → 1.7.1

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 (81) hide show
  1. package/CHANGELOG +15 -0
  2. package/dist/index.js +52 -46
  3. package/dist/index.js.map +1 -1
  4. package/dist/types/Components/APIEndpoint.class.d.ts +2 -8
  5. package/dist/types/Components/Component.class.d.ts +9 -0
  6. package/dist/types/Components/Triggers/Gmail.trigger.d.ts +0 -17
  7. package/dist/types/Components/Triggers/JobScheduler.trigger.d.ts +10 -0
  8. package/dist/types/Components/Triggers/Trigger.class.d.ts +11 -0
  9. package/dist/types/Components/index.d.ts +6 -0
  10. package/dist/types/Core/Connector.class.d.ts +1 -0
  11. package/dist/types/Core/ConnectorsService.d.ts +2 -0
  12. package/dist/types/Core/HookService.d.ts +1 -1
  13. package/dist/types/helpers/Conversation.helper.d.ts +2 -0
  14. package/dist/types/helpers/Crypto.helper.d.ts +8 -0
  15. package/dist/types/index.d.ts +13 -0
  16. package/dist/types/subsystems/AgentManager/Agent.class.d.ts +4 -2
  17. package/dist/types/subsystems/AgentManager/AgentData.service/AgentDataConnector.d.ts +13 -0
  18. package/dist/types/subsystems/AgentManager/AgentData.service/connectors/NullAgentData.class.d.ts +1 -4
  19. package/dist/types/subsystems/AgentManager/Scheduler.service/Job.class.d.ts +29 -6
  20. package/dist/types/subsystems/AgentManager/Scheduler.service/SchedulerConnector.d.ts +11 -3
  21. package/dist/types/subsystems/AgentManager/Scheduler.service/connectors/LocalScheduler.class.d.ts +31 -7
  22. package/dist/types/subsystems/LLMManager/LLM.service/connectors/Perplexity.class.d.ts +2 -5
  23. package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/OpenAIConnector.class.d.ts +3 -6
  24. package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ResponsesApiInterface.d.ts +7 -0
  25. package/dist/types/subsystems/LLMManager/LLM.service/connectors/xAI.class.d.ts +2 -5
  26. package/dist/types/types/Agent.types.d.ts +1 -0
  27. package/dist/types/types/LLM.types.d.ts +2 -5
  28. package/dist/types/types/SRE.types.d.ts +4 -1
  29. package/package.json +6 -2
  30. package/src/Components/APICall/OAuth.helper.ts +30 -35
  31. package/src/Components/APIEndpoint.class.ts +25 -6
  32. package/src/Components/Component.class.ts +11 -0
  33. package/src/Components/Triggers/Gmail.trigger.ts +282 -0
  34. package/src/Components/Triggers/JobScheduler.trigger.ts +45 -0
  35. package/src/Components/Triggers/README.md +3 -0
  36. package/src/Components/Triggers/Trigger.class.ts +101 -0
  37. package/src/Components/Triggers/WhatsApp.trigger.ts +219 -0
  38. package/src/Components/index.ts +8 -0
  39. package/src/Core/AgentProcess.helper.ts +4 -6
  40. package/src/Core/Connector.class.ts +11 -3
  41. package/src/Core/ConnectorsService.ts +5 -0
  42. package/src/Core/ExternalEventsReceiver.ts +317 -0
  43. package/src/Core/HookService.ts +20 -6
  44. package/src/Core/SmythRuntime.class.ts +7 -0
  45. package/src/Core/SystemEvents.ts +17 -0
  46. package/src/Core/boot.ts +2 -0
  47. package/src/helpers/Conversation.helper.ts +35 -11
  48. package/src/helpers/Crypto.helper.ts +28 -0
  49. package/src/index.ts +208 -195
  50. package/src/index.ts.bak +208 -195
  51. package/src/subsystems/AGENTS.md +594 -0
  52. package/src/subsystems/AgentManager/Agent.class.ts +71 -21
  53. package/src/subsystems/AgentManager/AgentData.service/AgentDataConnector.ts +24 -1
  54. package/src/subsystems/AgentManager/AgentData.service/connectors/NullAgentData.class.ts +2 -2
  55. package/src/subsystems/AgentManager/AgentRuntime.class.ts +34 -5
  56. package/src/subsystems/AgentManager/Scheduler.service/Job.class.ts +414 -0
  57. package/src/subsystems/AgentManager/Scheduler.service/Schedule.class.ts +200 -0
  58. package/src/subsystems/AgentManager/Scheduler.service/SchedulerConnector.ts +200 -0
  59. package/src/subsystems/AgentManager/Scheduler.service/connectors/LocalScheduler.class.ts +767 -0
  60. package/src/subsystems/AgentManager/Scheduler.service/index.ts +11 -0
  61. package/src/subsystems/IO/VectorDB.service/connectors/MilvusVectorDB.class.ts +1 -1
  62. package/src/subsystems/LLMManager/LLM.service/LLMCredentials.helper.ts +61 -2
  63. package/src/subsystems/LLMManager/LLM.service/connectors/Anthropic.class.ts +3 -0
  64. package/src/subsystems/LLMManager/LLM.service/connectors/Bedrock.class.ts +3 -1
  65. package/src/subsystems/LLMManager/LLM.service/connectors/Echo.class.ts +5 -1
  66. package/src/subsystems/LLMManager/LLM.service/connectors/GoogleAI.class.ts +247 -56
  67. package/src/subsystems/LLMManager/LLM.service/connectors/Groq.class.ts +3 -0
  68. package/src/subsystems/LLMManager/LLM.service/connectors/Ollama.class.ts +28 -21
  69. package/src/subsystems/LLMManager/LLM.service/connectors/Perplexity.class.ts +3 -0
  70. package/src/subsystems/LLMManager/LLM.service/connectors/VertexAI.class.ts +121 -33
  71. package/src/subsystems/LLMManager/LLM.service/connectors/openai/OpenAIConnector.class.ts +38 -27
  72. package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ResponsesApiInterface.ts +115 -18
  73. package/src/subsystems/LLMManager/LLM.service/connectors/xAI.class.ts +3 -0
  74. package/src/subsystems/LLMManager/ModelsProvider.service/ModelsProviderConnector.ts +1 -6
  75. package/src/subsystems/MemoryManager/LLMContext.ts +3 -8
  76. package/src/subsystems/MemoryManager/RuntimeContext.ts +10 -9
  77. package/src/subsystems/Security/Credentials/Credentials.class.ts +1 -0
  78. package/src/subsystems/Security/Credentials/ManagedOAuth2Credentials.class.ts +106 -0
  79. package/src/types/Agent.types.ts +1 -0
  80. package/src/types/LLM.types.ts +2 -2
  81. package/src/types/SRE.types.ts +3 -0
@@ -12,6 +12,7 @@ import { Logger } from '@sre/helpers/Log.helper';
12
12
  import { TemplateString } from '@sre/helpers/TemplateString.helper';
13
13
  import { IModelsProviderRequest, ModelsProviderConnector } from '@sre/LLMManager/ModelsProvider.service/ModelsProviderConnector';
14
14
  import { AccessCandidate } from '@sre/Security/AccessControl/AccessCandidate.class';
15
+ import { Trigger } from '@sre/Components/Triggers/Trigger.class';
15
16
  import { IAgent } from '@sre/types/Agent.types';
16
17
  import { AgentSSE } from './AgentSSE.class';
17
18
 
@@ -26,10 +27,12 @@ export class Agent implements IAgent {
26
27
  public components: any;
27
28
  public connections: any;
28
29
  public endpoints: any = {};
30
+ public triggers: any = {};
29
31
  public sessionId;
30
32
  public sessionTag = '';
31
33
  public callerSessionId;
32
34
  public apiBasePath = '/api';
35
+ public triggerBasePath = '/trigger';
33
36
  public agentRuntime: AgentRuntime | any;
34
37
 
35
38
  public usingTestDomain = false;
@@ -40,7 +43,7 @@ export class Agent implements IAgent {
40
43
 
41
44
  //public baseUrl = '';
42
45
  public agentVariables: any = {};
43
- private _kill = false;
46
+ private _killReason = '';
44
47
  //public agentRequest: Request | AgentRequest | any;
45
48
  public async = false;
46
49
  public jobID = '';
@@ -89,6 +92,11 @@ export class Agent implements IAgent {
89
92
  this.endpoints[`${this.apiBasePath}/${endpoint.data.endpoint}`][method] = endpoint;
90
93
  }
91
94
 
95
+ const triggers = this.data.components.filter((c) => typeof c.data?.triggerEndpoint == 'string');
96
+ for (let trigger of triggers) {
97
+ this.triggers[`${this.triggerBasePath}/${trigger.data.triggerEndpoint}`] = trigger;
98
+ }
99
+
92
100
  this.components = {};
93
101
  for (let component of this.data.components) {
94
102
  //FIXME : this does not persist in debug mode, it breaks key value mem logic
@@ -117,14 +125,27 @@ export class Agent implements IAgent {
117
125
  const output = sourceComponent.outputs[sourceIndex];
118
126
  output.index = sourceIndex; // legacy ids (numbers)
119
127
 
120
- const input = targetComponent.inputs[targetIndex];
121
- input.index = targetIndex;
122
-
123
128
  if (!output.next) output.next = [];
124
129
  output.next.push(targetComponent.id);
125
130
 
126
- if (!input.prev) input.prev = [];
127
- input.prev.push(sourceComponent.id);
131
+ //when a trigger is connected to an APIEndpoint it does not use the standard inputs
132
+ //the targetIndex is then -1 and the input does not really exist
133
+ //in that case, we should consider the trigger as an ancestor for all APIEndpoint inputs
134
+
135
+ if (targetIndex >= 0) {
136
+ const input = targetComponent.inputs[targetIndex];
137
+ if (input) {
138
+ input.index = targetIndex;
139
+ if (!input.prev) input.prev = [];
140
+ input.prev.push(sourceComponent.id);
141
+ }
142
+ } else {
143
+ //if the targetIndex is -1, we should consider the trigger as an ancestor for all APIEndpoint inputs
144
+ for (let input of targetComponent.inputs) {
145
+ if (!input.prev) input.prev = [];
146
+ input.prev.push(sourceComponent.id);
147
+ }
148
+ }
128
149
  }
129
150
 
130
151
  this.tagAsyncComponents();
@@ -183,8 +204,12 @@ export class Agent implements IAgent {
183
204
  const sessionTags = this?.agentRequest?.headers['x-session-tag'];
184
205
  if (sessionTags) this.sessionTag += this.sessionTag ? `,${sessionTags}` : sessionTags;
185
206
 
186
- var regex = new RegExp(`^\/v[0-9]+(\.[0-9]+)?${this.apiBasePath}\/(.*)`);
187
- if (this.agentRequest?.path?.startsWith(`${this.apiBasePath}/`) || this.agentRequest?.path?.match(regex)) {
207
+ var regex = new RegExp(`^\/v[0-9]+(\.[0-9]+)?(${this.apiBasePath}|${this.triggerBasePath})\/(.*)`);
208
+ if (
209
+ this.agentRequest?.path?.startsWith(`${this.apiBasePath}/`) ||
210
+ this.agentRequest?.path?.startsWith(`${this.triggerBasePath}/`) ||
211
+ this.agentRequest?.path?.match(regex)
212
+ ) {
188
213
  //we only need runtime context for API calls
189
214
  this.agentRuntime = new AgentRuntime(this);
190
215
  this.callerSessionId =
@@ -197,11 +222,11 @@ export class Agent implements IAgent {
197
222
  this.callback = callback;
198
223
  }
199
224
 
200
- public kill() {
201
- this._kill = true;
225
+ public kill(reason: string = 'kill') {
226
+ this._killReason = reason;
202
227
  }
203
228
  public isKilled() {
204
- return this._kill;
229
+ return !!this._killReason;
205
230
  }
206
231
  private async parseVariables() {
207
232
  //parse vault agent variables
@@ -216,7 +241,7 @@ export class Agent implements IAgent {
216
241
  }
217
242
  }
218
243
 
219
- @hookAsync('Agent.process')
244
+ @hookAsync('SREAgent.process')
220
245
  async process(endpointPath, input) {
221
246
  await this.agentRuntime.ready();
222
247
 
@@ -252,7 +277,7 @@ export class Agent implements IAgent {
252
277
  });
253
278
 
254
279
  const method = this.agentRequest.method.toUpperCase();
255
- const endpoint = this.endpoints[endpointPath]?.[method];
280
+ const endpoint = this.endpoints[endpointPath]?.[method] || this.triggers[endpointPath];
256
281
 
257
282
  //first check if this is a debug session, and return debug result if it's the case
258
283
  if (this.agentRuntime.debug) {
@@ -307,9 +332,9 @@ export class Agent implements IAgent {
307
332
  const qosLatency = Math.floor(OSResourceMonitor.cpu.load * MAX_LATENCY || 0);
308
333
 
309
334
  await delay(10 + qosLatency);
310
- } while (!step?.finalResult && !this._kill);
335
+ } while (!step?.finalResult && !this._killReason);
311
336
 
312
- if (this._kill) {
337
+ if (this._killReason) {
313
338
  const endTime = Date.now();
314
339
  const duration = endTime - startTime;
315
340
  this.sse.send('agent', {
@@ -325,7 +350,7 @@ export class Agent implements IAgent {
325
350
  error: 'Agent killed',
326
351
  });
327
352
  console.warn(`Agent ${this.id} was killed`, AccessCandidate.agent(this.id));
328
- return { error: 'Agent killed' };
353
+ return { error: 'AGENT_KILLED', reason: this._killReason };
329
354
  }
330
355
  result = await this.postProcess(step?.finalResult).catch((error) => ({ error }));
331
356
 
@@ -379,7 +404,7 @@ export class Agent implements IAgent {
379
404
  //tasks count update logic
380
405
  }
381
406
 
382
- @hookAsync('Agent.postProcess')
407
+ @hookAsync('SREAgent.postProcess')
383
408
  public async postProcess(result) {
384
409
  if (Array.isArray(result)) result = result.flat(Infinity);
385
410
  if (!Array.isArray(result)) result = [result];
@@ -425,16 +450,31 @@ export class Agent implements IAgent {
425
450
  // this.agentRuntime.resetComponent(componentId);
426
451
  // }
427
452
 
453
+ // private hasLoopAncestor(inputEntry) {
454
+ // if (!inputEntry.prev) return false;
455
+ // for (let prevId of inputEntry.prev) {
456
+ // const prevComponentData = this.components[prevId];
457
+ // if (prevComponentData.name == 'ForEach') return true;
458
+
459
+ // for (let inputEntry of prevComponentData.inputs) {
460
+ // if (this.hasLoopAncestor(inputEntry)) return true;
461
+ // }
462
+ // }
463
+ // }
428
464
  private hasLoopAncestor(inputEntry) {
429
465
  if (!inputEntry.prev) return false;
430
466
  for (let prevId of inputEntry.prev) {
431
467
  const prevComponentData = this.components[prevId];
432
- if (prevComponentData.name == 'ForEach') return true;
468
+ const prevRuntimeData = this.agentRuntime.getRuntimeData(prevId);
469
+
470
+ // Consider any component with _LoopData as a loop ancestor
471
+ if (prevRuntimeData?._LoopData) return true;
433
472
 
434
473
  for (let inputEntry of prevComponentData.inputs) {
435
474
  if (this.hasLoopAncestor(inputEntry)) return true;
436
475
  }
437
476
  }
477
+ return false;
438
478
  }
439
479
 
440
480
  private clearChildLoopRuntimeComponentData(componentId) {
@@ -527,7 +567,7 @@ export class Agent implements IAgent {
527
567
  agentRuntime.updateComponent(componentId, { step });
528
568
  }
529
569
 
530
- @hookAsync('Agent.callComponent')
570
+ @hookAsync('SREAgent.callComponent')
531
571
  async callComponent(sourceId, componentId, input?) {
532
572
  const startTime = Date.now();
533
573
  const agentRuntime = this.agentRuntime;
@@ -547,7 +587,7 @@ export class Agent implements IAgent {
547
587
  input,
548
588
  });
549
589
 
550
- if (this._kill) {
590
+ if (this._killReason) {
551
591
  console.warn(`Agent ${this.id} was killed, skipping component ${componentData.name}`, AccessCandidate.agent(this.id));
552
592
 
553
593
  const output = { id: componentData.id, name: componentData.displayName, result: null, error: 'Agent killed' };
@@ -850,7 +890,7 @@ export class Agent implements IAgent {
850
890
  return currentProperty;
851
891
  }
852
892
 
853
- @hookAsync('Agent.callNextComponents')
893
+ @hookAsync('SREAgent.callNextComponents')
854
894
  async callNextComponents(componentId, output) {
855
895
  const agentRuntime = this.agentRuntime;
856
896
  //agentRuntime.incStep();
@@ -914,6 +954,16 @@ export class Agent implements IAgent {
914
954
  if (Array.isArray(connections) && connections.length > 0) {
915
955
  const nextInput = {};
916
956
  for (let connection of connections) {
957
+ // if (component instanceof Trigger) {
958
+ // //handle trigger connections
959
+ // console.log('Trigger', connection);
960
+ // for (let input of targetComponentData.inputs) {
961
+ // if (connection.output?.Payload) {
962
+ // nextInput[input.name] = TemplateString(input.defaultVal).parse(connection.output?.Payload).clean().result;
963
+ // }
964
+ // }
965
+ // continue;
966
+ // }
917
967
  const output = connection.output;
918
968
  const componentData = connection.componentData;
919
969
  const outputEndpoint = componentData.outputs[connection.sourceIndex]; //source
@@ -52,7 +52,13 @@ const openapiEndpointTemplate = JSON.stringify({
52
52
  },
53
53
  },
54
54
  });
55
+
56
+ //TODO: use SecureConnector instead of Connector to harden agent data security
57
+ //When implemented, the getEphemeralAgentData becomes part of the default requester
55
58
  export abstract class AgentDataConnector extends Connector implements IAgentDataConnector {
59
+ //Ephemeral agent data is used to store data that is not persistent and is only available for the current session
60
+ //this is usually the case of programmatic agents implemented with the SDK
61
+ static ephemeralAgentData: Map<string, any> = new Map();
56
62
  public name = 'AgentDataConnector';
57
63
  public abstract getAgentData(agentId: string, version?: string): Promise<any>;
58
64
  public abstract getAgentIdByDomain(domain: string): Promise<string>;
@@ -107,7 +113,7 @@ export abstract class AgentDataConnector extends Connector implements IAgentData
107
113
  summary: summary?.replace(/"/g, '\\"'),
108
114
  operationId: component?.data?.endpoint,
109
115
  })
110
- .clean().result,
116
+ .clean().result
111
117
  ).tryParse();
112
118
 
113
119
  if (typeof openAPIEntry !== 'object') {
@@ -188,6 +194,23 @@ export abstract class AgentDataConnector extends Connector implements IAgentData
188
194
 
189
195
  return openAPIObj;
190
196
  }
197
+
198
+ /**
199
+ * Sets ephemeral agent data for the given agent ID
200
+ * @param agentId
201
+ * @param data
202
+ */
203
+ public async setEphemeralAgentData(agentId: string, data: any) {
204
+ AgentDataConnector.ephemeralAgentData.set(agentId, data);
205
+ }
206
+ /**
207
+ * Gets ephemeral agent data for the given agent ID
208
+ * @param agentId
209
+ * @returns
210
+ */
211
+ public async getEphemeralAgentData(agentId: string) {
212
+ return AgentDataConnector.ephemeralAgentData.get(agentId);
213
+ }
191
214
  }
192
215
 
193
216
  function getOpenAPIInputSchema(input_type) {
@@ -12,11 +12,11 @@ export class NullAgentData extends AgentDataConnector {
12
12
  }
13
13
 
14
14
  public getAgentConfig(agentId: string): Partial<TArgs> {
15
- return {};
15
+ return null; //{};
16
16
  }
17
17
 
18
18
  public async getAgentData(agentId: string, version?: string) {
19
- return { data: {}, version: '1.0' };
19
+ return null; // { data: {}, version: '1.0' };
20
20
  }
21
21
 
22
22
  public getAgentIdByDomain(domain: string): Promise<string> {
@@ -140,6 +140,11 @@ export class AgentRuntime {
140
140
 
141
141
  this.agentContext = new RuntimeContext(this);
142
142
  this.agentContext.on('ready', () => {
143
+ let method = (agent.agentRequest.method || 'POST').toUpperCase();
144
+ const endpoint = agent.endpoints?.[agent.agentRequest.path]?.[method];
145
+ const trigger = agent.triggers?.[agent.agentRequest.path];
146
+ const endpointDBGCall = this.xDebugId?.startsWith('dbg-');
147
+
143
148
  this.alwaysActiveComponents = {};
144
149
  this.exclusiveComponents = {};
145
150
  for (let component of this.agent.data.components) {
@@ -149,6 +154,15 @@ export class AgentRuntime {
149
154
  continue;
150
155
  }
151
156
 
157
+ if (trigger && trigger.id != undefined && component.id == trigger.id && this.xDebugId?.startsWith('dbg-')) {
158
+ this.updateComponent(component.id, { active: true });
159
+ }
160
+
161
+ //if this debug session was initiated from an endpoint, we mark the endpoint component as active
162
+ if (endpoint && endpoint.id != undefined && component.id == endpoint.id && endpointDBGCall) {
163
+ this.updateComponent(component.id, { active: true });
164
+ }
165
+
152
166
  if (cpt.alwaysActive) {
153
167
  this.alwaysActiveComponents[component.id] = cpt;
154
168
  this.updateComponent(component.id, { active: true, alwaysActive: true });
@@ -380,7 +394,20 @@ export class AgentRuntime {
380
394
  ctxData.sessionResult = true;
381
395
  }
382
396
 
383
- //capture results
397
+ //capture triggers results
398
+
399
+ const triggers = Object.values(agent.triggers);
400
+ let triggersResults = dbgResults.flat().filter(
401
+ (e) =>
402
+ e.id &&
403
+ e.result &&
404
+ !e.result._missing_inputs &&
405
+ !e.result._in_progress &&
406
+ //check if the current result is a trigger
407
+ triggers.find((t: any) => t.id == e.id)
408
+ );
409
+
410
+ //capture workflow results
384
411
  let sessionResults = dbgResults.flat().filter(
385
412
  (e) =>
386
413
  e.id &&
@@ -390,6 +417,8 @@ export class AgentRuntime {
390
417
  !agent.connections.find((c) => c.sourceId == e.id)
391
418
  );
392
419
 
420
+ sessionResults = sessionResults.concat(triggersResults);
421
+
393
422
  let errorResults = dbgResults.flat().filter((e) => e.id && (e.error || e.result?._error));
394
423
 
395
424
  //also filter out erroneous components that are children of a loop
@@ -452,13 +481,13 @@ export class AgentRuntime {
452
481
  const circularLimitData = this.circularLimitReached;
453
482
  result = { error: `Circular Calls Limit Reached on ${circularLimitData}. Current circular limit is ${this.agent.circularLimit}` };
454
483
  } else {
455
- let state = [sessionResults, errorResults].flat(Infinity);
456
- if (!state || state.length == 0) state = errorResults.flat(Infinity);
484
+ let _state = [sessionResults, errorResults].flat(Infinity);
485
+ if (!_state || _state.length == 0) _state = errorResults.flat(Infinity);
457
486
 
458
487
  //post process run cycle results
459
488
  //deduplicating redundant entries
460
489
 
461
- const data = state
490
+ const _data = _state
462
491
  .reduce(
463
492
  (acc, current) => {
464
493
  if (!acc.seen[current.id]) {
@@ -473,7 +502,7 @@ export class AgentRuntime {
473
502
 
474
503
  //data.forEach((d: any) => delete d?.result?._debug);
475
504
 
476
- result = data;
505
+ result = _data;
477
506
  /////////////
478
507
  }
479
508