@smythos/sre 1.6.13 → 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 (83) 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/helpers/Sysconfig.helper.ts +50 -14
  50. package/src/index.ts +13 -0
  51. package/src/index.ts.bak +13 -0
  52. package/src/subsystems/AGENTS.md +594 -0
  53. package/src/subsystems/AgentManager/Agent.class.ts +71 -21
  54. package/src/subsystems/AgentManager/AgentData.service/AgentDataConnector.ts +24 -1
  55. package/src/subsystems/AgentManager/AgentData.service/connectors/NullAgentData.class.ts +2 -2
  56. package/src/subsystems/AgentManager/AgentRuntime.class.ts +34 -5
  57. package/src/subsystems/AgentManager/Scheduler.service/Job.class.ts +414 -0
  58. package/src/subsystems/AgentManager/Scheduler.service/Schedule.class.ts +200 -0
  59. package/src/subsystems/AgentManager/Scheduler.service/SchedulerConnector.ts +200 -0
  60. package/src/subsystems/AgentManager/Scheduler.service/connectors/LocalScheduler.class.ts +767 -0
  61. package/src/subsystems/AgentManager/Scheduler.service/index.ts +11 -0
  62. package/src/subsystems/IO/VectorDB.service/connectors/MilvusVectorDB.class.ts +1 -1
  63. package/src/subsystems/LLMManager/LLM.service/LLMCredentials.helper.ts +61 -2
  64. package/src/subsystems/LLMManager/LLM.service/connectors/Anthropic.class.ts +3 -0
  65. package/src/subsystems/LLMManager/LLM.service/connectors/Bedrock.class.ts +3 -1
  66. package/src/subsystems/LLMManager/LLM.service/connectors/Echo.class.ts +5 -1
  67. package/src/subsystems/LLMManager/LLM.service/connectors/GoogleAI.class.ts +247 -56
  68. package/src/subsystems/LLMManager/LLM.service/connectors/Groq.class.ts +3 -0
  69. package/src/subsystems/LLMManager/LLM.service/connectors/Ollama.class.ts +28 -21
  70. package/src/subsystems/LLMManager/LLM.service/connectors/Perplexity.class.ts +3 -0
  71. package/src/subsystems/LLMManager/LLM.service/connectors/VertexAI.class.ts +121 -33
  72. package/src/subsystems/LLMManager/LLM.service/connectors/openai/OpenAIConnector.class.ts +38 -27
  73. package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ResponsesApiInterface.ts +115 -18
  74. package/src/subsystems/LLMManager/LLM.service/connectors/xAI.class.ts +3 -0
  75. package/src/subsystems/LLMManager/ModelsProvider.service/ModelsProviderConnector.ts +1 -6
  76. package/src/subsystems/MemoryManager/LLMContext.ts +3 -8
  77. package/src/subsystems/MemoryManager/RuntimeContext.ts +10 -9
  78. package/src/subsystems/Security/Credentials/Credentials.class.ts +1 -0
  79. package/src/subsystems/Security/Credentials/ManagedOAuth2Credentials.class.ts +106 -0
  80. package/src/subsystems/Security/Vault.service/connectors/JSONFileVault.class.ts +2 -2
  81. package/src/types/Agent.types.ts +1 -0
  82. package/src/types/LLM.types.ts +2 -2
  83. package/src/types/SRE.types.ts +3 -0
@@ -0,0 +1,101 @@
1
+ import { Agent } from '@sre/AgentManager/Agent.class';
2
+ import { Component } from '../Component.class';
3
+ import { LogHelper } from '@sre/helpers/Log.helper';
4
+ import express from 'express';
5
+ import { AgentRequest } from '@sre/AgentManager/AgentRequest.class';
6
+ import { IAgent } from '@sre/types/Agent.types';
7
+
8
+ export class Trigger extends Component {
9
+ protected logger: LogHelper;
10
+
11
+ async process(input, settings, agent: Agent) {
12
+ await super.process(input, settings, agent);
13
+ this.logger = this.createComponentLogger(agent, settings);
14
+ try {
15
+ const agentRequest: AgentRequest = agent.agentRequest;
16
+ const processedRequest = await this.requestHandler(input, settings, agent);
17
+ if (processedRequest) {
18
+ agent.kill('TRIGGER_REQ_HANDLED'); //should not be handled by the agent
19
+ return processedRequest;
20
+ }
21
+
22
+ //a trigger should always return an array of payloads
23
+ //if it's a single object, it should be wrapped in an array
24
+ let inputArray = await this.collectPayload(input, settings, agent);
25
+ if (inputArray.length < 2) {
26
+ return { Payload: inputArray?.[0], _error: null, _in_progress: false, _debug: this.logger.output };
27
+ }
28
+ return await this.processIteration(inputArray, settings, agent);
29
+ } catch (error) {
30
+ this.logger.error(error);
31
+ return { Payload: {}, Result: [], _error: error, _in_progress: false, _debug: this.logger.output };
32
+ }
33
+ }
34
+ protected async collectPayload(input, settings, agent: Agent): Promise<any[]> {
35
+ return [];
36
+ }
37
+ public async requestHandler(input, settings, agent: Agent): Promise<any> {}
38
+
39
+ protected async processIteration(inputArray, settings, agent) {
40
+ let Payload = {};
41
+ let Result;
42
+ let _temp_result;
43
+ let _error = null;
44
+ let _in_progress = true;
45
+ const logger = this.logger;
46
+
47
+ const runtimeData = agent.agentRuntime.getRuntimeData(settings.id);
48
+ const _LoopData = runtimeData._LoopData || { parentId: settings.id, loopIndex: 0, loopLength: inputArray.length };
49
+
50
+ logger.debug(`Loop: ${_LoopData.loopIndex} / ${_LoopData.loopLength}`);
51
+ delete _LoopData.branches; //reset branches (the number of branches is calculated in CallComponent@Agent.class.ts )
52
+
53
+ if (_LoopData.result) {
54
+ _temp_result = _LoopData.result;
55
+ logger.debug(` => Trigger Iteration Result : ${JSON.stringify(Payload, null, 2)}`);
56
+ logger.debug(`---------------------------------------------------`);
57
+ }
58
+
59
+ Payload = inputArray[_LoopData.loopIndex];
60
+
61
+ logger.debug(` => Trigger Iteration Data : ${JSON.stringify(Payload, null, 2)}`);
62
+
63
+ _in_progress = Payload !== undefined;
64
+ if (_in_progress) {
65
+ _LoopData.loopIndex++;
66
+ }
67
+ _LoopData._in_progress = _in_progress;
68
+
69
+ agent.agentRuntime.updateRuntimeData(settings.id, { _LoopData: _LoopData });
70
+
71
+ if (!_in_progress) {
72
+ Result = (_temp_result || []).map((item) => cleanupResult(item.result || item));
73
+ }
74
+ return { Payload, Result, _temp_result, _error, _in_progress, _debug: logger.output };
75
+ }
76
+
77
+ async postProcess(output, settings, agent: Agent): Promise<any> {
78
+ output = await super.postProcess(output, settings, agent);
79
+ return output?.result.Result;
80
+ }
81
+
82
+ /**
83
+ * This function is used to register a trigger,
84
+ * It can be called by a visual builder when saving a trigger component.
85
+ * it performs the necessary actions to register the trigger with the external service or with the internal scheduler.
86
+ * @param componentId - The id of the component to register
87
+ * @param componentSettings - The settings of the component to register
88
+ * @param payload - The payload to register the trigger with
89
+ * @returns A promise that resolves to the result of the registration
90
+ */
91
+ async register(componentId: string, componentSettings: any, payload: { agentData: IAgent; triggerUrl: string }) {}
92
+ }
93
+
94
+ function cleanupResult(result) {
95
+ if (typeof result !== 'object') return result;
96
+ if (result._debug) delete result._debug;
97
+ if (result._error) delete result._error;
98
+ if (result._temp_result) delete result._temp_result;
99
+ if (result._in_progress) delete result._in_progress;
100
+ return result;
101
+ }
@@ -0,0 +1,219 @@
1
+ import { IAgent as Agent } from '@sre/types/Agent.types';
2
+ import { Trigger } from './Trigger.class';
3
+ import { AgentRequest } from '@sre/AgentManager/AgentRequest.class';
4
+ import express from 'express';
5
+
6
+ type WhatsAppIncomingMessage = {
7
+ id?: string;
8
+ from?: string;
9
+ profileName?: string;
10
+ text?: string;
11
+ type?: string;
12
+ timestamp?: string;
13
+ phoneNumberId?: string;
14
+ };
15
+
16
+ export class WhatsAppTrigger extends Trigger {
17
+ async collectPayload(input, settings, agent: Agent) {
18
+ const req = agent.agentRequest;
19
+ const body = req?.body || {};
20
+ agent.agentRequest.res.sendStatus(200); //Whatsapp expects immediate response
21
+
22
+ const message = extractFirstIncomingMessage(body);
23
+ if (!message) return [];
24
+
25
+ return [
26
+ {
27
+ message,
28
+ },
29
+ ];
30
+ }
31
+
32
+ async requestHandler(input, settings, agent: Agent) {
33
+ const req = agent.agentRequest?.req || agent.agentRequest;
34
+ const res = agent.agentRequest?.res;
35
+
36
+ if (!req || !res) return null;
37
+
38
+ const method = (req?.method || 'POST').toUpperCase();
39
+ const query = req?.query || {};
40
+
41
+ // Handle Facebook webhook verification (GET request)
42
+ if (method === 'GET') {
43
+ // Get config from request (should be attached by the router)
44
+
45
+ const verificationResult = handleVerification(query, settings?.data);
46
+
47
+ if (verificationResult) {
48
+ if (verificationResult.valid) {
49
+ // Send plain text response with the challenge (exactly as Facebook expects)
50
+ res.status(200).type('text/plain').send(verificationResult.challenge);
51
+ } else {
52
+ res.status(403).send('Forbidden');
53
+ }
54
+ return true; // Indicate that we handled the response
55
+ }
56
+ }
57
+
58
+ // For POST requests (actual messages), return null to let normal flow continue
59
+ return null;
60
+ }
61
+
62
+ async register(componentId: string, componentSettings: any, payload?: { triggerUrl: string }) {
63
+ const verifyToken = componentSettings?.verifyToken || componentSettings?.verify_token;
64
+ const clientId = componentSettings?.clientId || componentSettings?.appId;
65
+ const clientSecret = componentSettings?.clientSecret || componentSettings?.appSecret;
66
+ const subscriptionFields = ['messages', 'message_template_status_update'];
67
+
68
+ const inferredWebhookUrl = payload?.triggerUrl;
69
+ const webhookUrl = (componentSettings?.webhookUrl || inferredWebhookUrl || '').split('?')[0];
70
+
71
+ if (!clientId || !clientSecret) throw new Error('WhatsAppTrigger.register: Missing clientId/clientSecret');
72
+ if (!verifyToken) throw new Error('WhatsAppTrigger.register: Missing verifyToken');
73
+ if (!webhookUrl) throw new Error('WhatsAppTrigger.register: Missing webhookUrl');
74
+
75
+ const accessToken = await getAppAccessToken(clientId, clientSecret);
76
+
77
+ // If a subscription exists, delete it first, then create a new one
78
+ const existingSubscriptions = await listWebhookSubscriptions(clientId, accessToken);
79
+ const existing = (existingSubscriptions || []).find((s: any) => s.object === 'whatsapp_business_account' && s.active);
80
+ if (existing) {
81
+ await deleteWebhookSubscription(clientId, accessToken);
82
+ }
83
+
84
+ await createWebhookSubscription(clientId, accessToken, {
85
+ callback_url: webhookUrl,
86
+ verify_token: verifyToken,
87
+ fields: subscriptionFields,
88
+ });
89
+ }
90
+
91
+ async unregister(componentId: string, agent: Agent, payload?: any) {
92
+ const componentSchema = await agent.components[componentId];
93
+ const data = componentSchema?.data || {};
94
+ const clientId = data?.clientId || data?.appId;
95
+ const clientSecret = data?.clientSecret || data?.appSecret;
96
+
97
+ if (!clientId || !clientSecret) throw new Error('WhatsAppTrigger.unregister: Missing clientId/clientSecret');
98
+
99
+ const accessToken = await getAppAccessToken(clientId, clientSecret);
100
+ await deleteWebhookSubscription(clientId, accessToken);
101
+ }
102
+ }
103
+
104
+ function handleVerification(query: any, config: any) {
105
+ if (!(query?.['hub.mode'] === 'subscribe' || query?.['hub.mode'] === 'SUBSCRIBE')) return null;
106
+
107
+ const providedToken = query['hub.verify_token'] || query['hub.verifyToken'];
108
+ const expectedToken = config?.verifyToken || config?.verify_token;
109
+ const challenge = query['hub.challenge'];
110
+ const valid = expectedToken ? String(providedToken) === String(expectedToken) : false;
111
+
112
+ return {
113
+ valid,
114
+ challenge,
115
+ mode: query['hub.mode'],
116
+ };
117
+ }
118
+
119
+ async function getAppAccessToken(clientId: string, clientSecret: string) {
120
+ const url = 'https://graph.facebook.com/v19.0/oauth/access_token';
121
+ const body = new URLSearchParams({
122
+ client_id: clientId,
123
+ client_secret: clientSecret,
124
+ grant_type: 'client_credentials',
125
+ }).toString();
126
+
127
+ const res = await fetch(url, {
128
+ method: 'POST',
129
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
130
+ body,
131
+ });
132
+ const json = await res.json();
133
+ if (!res.ok) throw new Error(`getAppAccessToken failed: ${json?.error?.message || res.status}`);
134
+ return json.access_token as string;
135
+ }
136
+
137
+ async function listWebhookSubscriptions(clientId: string, accessToken: string) {
138
+ const url = `https://graph.facebook.com/v19.0/${clientId}/subscriptions`;
139
+ const res = await fetch(url, {
140
+ method: 'GET',
141
+ headers: { Authorization: `Bearer ${accessToken}` },
142
+ });
143
+ const json = await res.json();
144
+ if (!res.ok) throw new Error(`listWebhookSubscriptions failed: ${json?.error?.message || res.status}`);
145
+ return json?.data || [];
146
+ }
147
+
148
+ async function deleteWebhookSubscription(clientId: string, accessToken: string) {
149
+ const url = `https://graph.facebook.com/v19.0/${clientId}/subscriptions`;
150
+ const body = new URLSearchParams({ object: 'whatsapp_business_account' }).toString();
151
+ const res = await fetch(url, {
152
+ method: 'DELETE',
153
+ headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/x-www-form-urlencoded' },
154
+ body,
155
+ });
156
+ if (!res.ok) {
157
+ const json = await res.json().catch(() => ({}));
158
+ throw new Error(`deleteWebhookSubscription failed: ${json?.error?.message || res.status}`);
159
+ }
160
+ return true;
161
+ }
162
+
163
+ async function createWebhookSubscription(
164
+ clientId: string,
165
+ accessToken: string,
166
+ params: { callback_url: string; verify_token: string; fields: string[] }
167
+ ) {
168
+ const url = `https://graph.facebook.com/v19.0/${clientId}/subscriptions`;
169
+ const body = new URLSearchParams({
170
+ object: 'whatsapp_business_account',
171
+ callback_url: params.callback_url,
172
+ verify_token: params.verify_token,
173
+ fields: JSON.stringify(params.fields),
174
+ include_values: 'true',
175
+ }).toString();
176
+
177
+ const res = await fetch(url, {
178
+ method: 'POST',
179
+ headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/x-www-form-urlencoded' },
180
+ body,
181
+ });
182
+ const json = await res.json();
183
+ if (!res.ok) throw new Error(`createWebhookSubscription failed: ${json?.error?.message || res.status}`);
184
+ return json;
185
+ }
186
+
187
+ function extractFirstIncomingMessage(body: any): WhatsAppIncomingMessage | null {
188
+ try {
189
+ const entries = Array.isArray(body?.entry) ? body.entry : [];
190
+ for (const entry of entries) {
191
+ const changes = Array.isArray(entry?.changes) ? entry.changes : [];
192
+ for (const change of changes) {
193
+ const value = change?.value || {};
194
+ const messages = Array.isArray(value?.messages) ? value.messages : [];
195
+ if (!messages.length) continue;
196
+
197
+ const m = messages.find((x) => x?.text?.body) || messages[0] || {};
198
+ const contacts = Array.isArray(value?.contacts) ? value.contacts : [];
199
+ const contact = contacts.length ? contacts[0] : undefined;
200
+
201
+ const text = m?.text?.body || m?.button?.text || m?.interactive?.list_reply?.title || '';
202
+ const timestampIso = m?.timestamp ? new Date(parseInt(m.timestamp, 10) * 1000).toISOString() : undefined;
203
+
204
+ return {
205
+ id: m?.id,
206
+ from: m?.from || contact?.wa_id,
207
+ profileName: contact?.profile?.name,
208
+ text,
209
+ type: m?.type,
210
+ timestamp: timestampIso,
211
+ phoneNumberId: value?.metadata?.phone_number_id,
212
+ };
213
+ }
214
+ }
215
+ return null;
216
+ } catch {
217
+ return null;
218
+ }
219
+ }
@@ -42,6 +42,9 @@ import { MemoryWriteKeyVal } from './MemoryWriteKeyVal.class';
42
42
  import { MemoryReadKeyVal } from './MemoryReadKeyVal.class';
43
43
  import { MemoryDeleteKeyVal } from './MemoryDeleteKeyVal.class';
44
44
  import { MemoryWriteObject } from './MemoryWriteObject.class';
45
+ import { GmailTrigger } from './Triggers/Gmail.trigger';
46
+ import { WhatsAppTrigger } from './Triggers/WhatsApp.trigger';
47
+ import { JobSchedulerTrigger } from './Triggers/JobScheduler.trigger';
45
48
 
46
49
  const components = {
47
50
  Component: new Component(),
@@ -92,6 +95,11 @@ const components = {
92
95
  MemoryReadKeyVal: new MemoryReadKeyVal(),
93
96
  MemoryDeleteKeyVal: new MemoryDeleteKeyVal(),
94
97
  MemoryWriteObject: new MemoryWriteObject(),
98
+
99
+ // Triggers
100
+ GmailTrigger: new GmailTrigger(),
101
+ WhatsAppTrigger: new WhatsAppTrigger(),
102
+ JobSchedulerTrigger: new JobSchedulerTrigger(),
95
103
  };
96
104
 
97
105
  export const ComponentInstances = components;
@@ -11,16 +11,14 @@ import fs from 'fs';
11
11
  import mime from 'mime';
12
12
  import path from 'path';
13
13
  import { ConnectorService } from './ConnectorsService';
14
+ import { TemplateString } from '@sre/helpers/TemplateString.helper';
14
15
 
15
16
  export class AgentProcess {
16
17
  public agent: Agent;
17
18
 
18
19
  private _loadPromise: Promise<any>;
19
20
 
20
- private constructor(
21
- private agentData: any,
22
- private agentVersion?: string,
23
- ) {
21
+ private constructor(private agentData: any, private agentVersion?: string) {
24
22
  this.initAgent(agentData, agentVersion);
25
23
  }
26
24
  private async initAgent(agentData: any, agentVersion?: string) {
@@ -101,7 +99,7 @@ export class AgentProcess {
101
99
  */
102
100
  public async run(
103
101
  reqConfig: TAgentProcessParams | Array<string> | AgentRequest,
104
- callback?: (data: any) => void,
102
+ callback?: (data: any) => void
105
103
  ): Promise<{
106
104
  status?: number;
107
105
  data: any;
@@ -116,7 +114,7 @@ export class AgentProcess {
116
114
  this.agent.setCallback(callback);
117
115
  }
118
116
 
119
- const pathMatches = request.path.match(/(^\/v[0-9]+\.[0-9]+?)?(\/api\/(.+)?)/);
117
+ const pathMatches = request.path.match(/(^\/v[0-9]+\.[0-9]+?)?(\/(api|trigger)\/(.+)?)/);
120
118
  if (!pathMatches || !pathMatches[2]) {
121
119
  return { status: 404, data: { error: 'Endpoint not found' } };
122
120
  }
@@ -3,7 +3,7 @@ import { Logger } from '../helpers/Log.helper';
3
3
  import { createHash } from 'crypto';
4
4
  import { AccessCandidate } from '@sre/Security/AccessControl/AccessCandidate.class';
5
5
 
6
- const console = Logger('Connector');
6
+ const logger = Logger('Connector');
7
7
  //const lCache = new LocalCache();
8
8
 
9
9
  export class Connector<TRequest = any> {
@@ -68,12 +68,12 @@ export class Connector<TRequest = any> {
68
68
  }
69
69
 
70
70
  public async start() {
71
- console.info(`Starting ${this.name} connector ...`);
71
+ logger.info(`Starting ${this.name} connector ...`);
72
72
  this.started = true;
73
73
  }
74
74
 
75
75
  public async stop() {
76
- console.info(`Stopping ${this.name} connector ...`);
76
+ logger.info(`Stopping ${this.name} connector ...`);
77
77
  }
78
78
 
79
79
  public ready() {
@@ -110,6 +110,10 @@ export class Connector<TRequest = any> {
110
110
  if (typeof candidate === 'string') {
111
111
  return this.requester(AccessCandidate.user(candidate));
112
112
  }
113
+
114
+ //backward compatibility
115
+ //this will be deprecated in the future, use .requester for this case
116
+ // .user will only accept strings representing the user id
113
117
  return this.requester(candidate);
114
118
  }
115
119
 
@@ -120,4 +124,8 @@ export class Connector<TRequest = any> {
120
124
  public agent(agentId: string): TRequest {
121
125
  return this.requester(AccessCandidate.agent(agentId));
122
126
  }
127
+
128
+ public handleEvent(eventName: string, data: any): void {
129
+ logger.debug(`Connector ${this.name} received event ${eventName} `);
130
+ }
123
131
  }
@@ -19,6 +19,7 @@ import { LogConnector } from '@sre/IO/Log.service/LogConnector';
19
19
  import { ComponentConnector } from '@sre/AgentManager/Component.service/ComponentConnector';
20
20
  import { ModelsProviderConnector } from '@sre/LLMManager/ModelsProvider.service/ModelsProviderConnector';
21
21
  import { CodeConnector } from '@sre/ComputeManager/Code.service/CodeConnector';
22
+ import { SchedulerConnector } from '@sre/AgentManager/Scheduler.service/SchedulerConnector';
22
23
  const console = Logger('ConnectorService');
23
24
 
24
25
  let ServiceRegistry: TServiceRegistry = {};
@@ -186,6 +187,10 @@ export class ConnectorService {
186
187
  static getCodeConnector(name?: string): CodeConnector {
187
188
  return ConnectorService.getInstance<CodeConnector>(TConnectorService.Code, name);
188
189
  }
190
+
191
+ static getSchedulerConnector(name?: string): SchedulerConnector {
192
+ return ConnectorService.getInstance<SchedulerConnector>(TConnectorService.Scheduler, name);
193
+ }
189
194
  }
190
195
 
191
196
  export abstract class ConnectorServiceProvider {