@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
package/src/index.ts CHANGED
@@ -54,12 +54,14 @@ export * from './Core/boot';
54
54
  export * from './Core/Connector.class';
55
55
  export * from './Core/ConnectorsService';
56
56
  export * from './Core/DummyConnector';
57
+ export * from './Core/ExternalEventsReceiver';
57
58
  export * from './Core/HookService';
58
59
  export * from './Core/SmythRuntime.class';
59
60
  export * from './Core/SystemEvents';
60
61
  export * from './helpers/AWSLambdaCode.helper';
61
62
  export * from './helpers/BinaryInput.helper';
62
63
  export * from './helpers/Conversation.helper';
64
+ export * from './helpers/Crypto.helper';
63
65
  export * from './helpers/ECMASandbox.helper';
64
66
  export * from './helpers/JsonContent.helper';
65
67
  export * from './helpers/LocalCache.helper';
@@ -92,6 +94,10 @@ export * from './Components/APICall/parseHeaders';
92
94
  export * from './Components/APICall/parseProxy';
93
95
  export * from './Components/APICall/parseUrl';
94
96
  export * from './Components/Image/imageSettings.config';
97
+ export * from './Components/Triggers/Gmail.trigger';
98
+ export * from './Components/Triggers/JobScheduler.trigger';
99
+ export * from './Components/Triggers/Trigger.class';
100
+ export * from './Components/Triggers/WhatsApp.trigger';
95
101
  export * from './subsystems/AgentManager/Agent.class';
96
102
  export * from './subsystems/AgentManager/Agent.helper';
97
103
  export * from './subsystems/AgentManager/AgentLogger.class';
@@ -116,6 +122,10 @@ export * from './subsystems/AgentManager/AgentData.service/AgentDataConnector';
116
122
  export * from './subsystems/AgentManager/AgentData.service/index';
117
123
  export * from './subsystems/AgentManager/Component.service/ComponentConnector';
118
124
  export * from './subsystems/AgentManager/Component.service/index';
125
+ export * from './subsystems/AgentManager/Scheduler.service/index';
126
+ export * from './subsystems/AgentManager/Scheduler.service/Job.class';
127
+ export * from './subsystems/AgentManager/Scheduler.service/Schedule.class';
128
+ export * from './subsystems/AgentManager/Scheduler.service/SchedulerConnector';
119
129
  export * from './subsystems/ComputeManager/Code.service/CodeConnector';
120
130
  export * from './subsystems/ComputeManager/Code.service/index';
121
131
  export * from './subsystems/IO/CLI.service/CLIConnector';
@@ -144,6 +154,8 @@ export * from './subsystems/Security/AccessControl/AccessRequest.class';
144
154
  export * from './subsystems/Security/AccessControl/ACL.class';
145
155
  export * from './subsystems/Security/Account.service/AccountConnector';
146
156
  export * from './subsystems/Security/Account.service/index';
157
+ export * from './subsystems/Security/Credentials/Credentials.class';
158
+ export * from './subsystems/Security/Credentials/ManagedOAuth2Credentials.class';
147
159
  export * from './subsystems/Security/ManagedVault.service/index';
148
160
  export * from './subsystems/Security/ManagedVault.service/ManagedVaultConnector';
149
161
  export * from './subsystems/Security/Vault.service/index';
@@ -153,6 +165,7 @@ export * from './subsystems/AgentManager/AgentData.service/connectors/CLIAgentDa
153
165
  export * from './subsystems/AgentManager/AgentData.service/connectors/LocalAgentDataConnector.class';
154
166
  export * from './subsystems/AgentManager/AgentData.service/connectors/NullAgentData.class';
155
167
  export * from './subsystems/AgentManager/Component.service/connectors/LocalComponentConnector.class';
168
+ export * from './subsystems/AgentManager/Scheduler.service/connectors/LocalScheduler.class';
156
169
  export * from './subsystems/ComputeManager/Code.service/connectors/AWSLambdaCode.class';
157
170
  export * from './subsystems/IO/Log.service/connectors/ConsoleLog.class';
158
171
  export * from './subsystems/IO/NKV.service/connectors/NKVLocalStorage.class';
package/src/index.ts.bak CHANGED
@@ -54,12 +54,14 @@ export * from './Core/boot';
54
54
  export * from './Core/Connector.class';
55
55
  export * from './Core/ConnectorsService';
56
56
  export * from './Core/DummyConnector';
57
+ export * from './Core/ExternalEventsReceiver';
57
58
  export * from './Core/HookService';
58
59
  export * from './Core/SmythRuntime.class';
59
60
  export * from './Core/SystemEvents';
60
61
  export * from './helpers/AWSLambdaCode.helper';
61
62
  export * from './helpers/BinaryInput.helper';
62
63
  export * from './helpers/Conversation.helper';
64
+ export * from './helpers/Crypto.helper';
63
65
  export * from './helpers/ECMASandbox.helper';
64
66
  export * from './helpers/JsonContent.helper';
65
67
  export * from './helpers/LocalCache.helper';
@@ -92,6 +94,10 @@ export * from './Components/APICall/parseHeaders';
92
94
  export * from './Components/APICall/parseProxy';
93
95
  export * from './Components/APICall/parseUrl';
94
96
  export * from './Components/Image/imageSettings.config';
97
+ export * from './Components/Triggers/Gmail.trigger';
98
+ export * from './Components/Triggers/JobScheduler.trigger';
99
+ export * from './Components/Triggers/Trigger.class';
100
+ export * from './Components/Triggers/WhatsApp.trigger';
95
101
  export * from './subsystems/AgentManager/Agent.class';
96
102
  export * from './subsystems/AgentManager/Agent.helper';
97
103
  export * from './subsystems/AgentManager/AgentLogger.class';
@@ -116,6 +122,10 @@ export * from './subsystems/AgentManager/AgentData.service/AgentDataConnector';
116
122
  export * from './subsystems/AgentManager/AgentData.service/index';
117
123
  export * from './subsystems/AgentManager/Component.service/ComponentConnector';
118
124
  export * from './subsystems/AgentManager/Component.service/index';
125
+ export * from './subsystems/AgentManager/Scheduler.service/index';
126
+ export * from './subsystems/AgentManager/Scheduler.service/Job.class';
127
+ export * from './subsystems/AgentManager/Scheduler.service/Schedule.class';
128
+ export * from './subsystems/AgentManager/Scheduler.service/SchedulerConnector';
119
129
  export * from './subsystems/ComputeManager/Code.service/CodeConnector';
120
130
  export * from './subsystems/ComputeManager/Code.service/index';
121
131
  export * from './subsystems/IO/CLI.service/CLIConnector';
@@ -144,6 +154,8 @@ export * from './subsystems/Security/AccessControl/AccessRequest.class';
144
154
  export * from './subsystems/Security/AccessControl/ACL.class';
145
155
  export * from './subsystems/Security/Account.service/AccountConnector';
146
156
  export * from './subsystems/Security/Account.service/index';
157
+ export * from './subsystems/Security/Credentials/Credentials.class';
158
+ export * from './subsystems/Security/Credentials/ManagedOAuth2Credentials.class';
147
159
  export * from './subsystems/Security/ManagedVault.service/index';
148
160
  export * from './subsystems/Security/ManagedVault.service/ManagedVaultConnector';
149
161
  export * from './subsystems/Security/Vault.service/index';
@@ -153,6 +165,7 @@ export * from './subsystems/AgentManager/AgentData.service/connectors/CLIAgentDa
153
165
  export * from './subsystems/AgentManager/AgentData.service/connectors/LocalAgentDataConnector.class';
154
166
  export * from './subsystems/AgentManager/AgentData.service/connectors/NullAgentData.class';
155
167
  export * from './subsystems/AgentManager/Component.service/connectors/LocalComponentConnector.class';
168
+ export * from './subsystems/AgentManager/Scheduler.service/connectors/LocalScheduler.class';
156
169
  export * from './subsystems/ComputeManager/Code.service/connectors/AWSLambdaCode.class';
157
170
  export * from './subsystems/IO/Log.service/connectors/ConsoleLog.class';
158
171
  export * from './subsystems/IO/NKV.service/connectors/NKVLocalStorage.class';
@@ -0,0 +1,594 @@
1
+ # Agent Subsystem Documentation
2
+
3
+ ## User Prompt
4
+
5
+ @Scheduler.service/ implement a SchedulerConnector.ts here
6
+ it provides the following function
7
+
8
+ list() //list jobs
9
+ add(jobId, schedule, job) //add or update existing job
10
+ delete(jobId);
11
+
12
+ schedule is an instance of an object called Schedule that supports this syntax
13
+
14
+ Schedule.starts(Date).ends(Date).every("10m"); ==> returns a json representation that can be parsed.
15
+
16
+ job is an instance of Job class
17
+ job = new Job(fn(), metadata);
18
+
19
+ and also implement a version of this scheduler called LocalScheduler, it uses disk to store jobs data under a .smyth subfolder, and works entierly locally.
20
+ it loads the jobs every start (if any) and triggers them periodically.
21
+
22
+ for references check how @VectorDBConnector.ts and @RAMVecrtorDB.class.ts are implemented
23
+ other examples @StorageConnector.ts and @LocalStorage.class.ts
24
+
25
+ it's important to handle the access rights and isolation properly
26
+
27
+ ## Important Instructions for LLMs
28
+
29
+ ⚠️ **CRITICAL: Do NOT start implementation immediately**
30
+
31
+ When receiving a user prompt to create a new connector or service:
32
+
33
+ 1. **Assess Information Completeness**
34
+
35
+ - Review the user's request for completeness
36
+ - Identify what information is missing or unclear
37
+ - Determine what patterns and architecture decisions need to be defined
38
+
39
+ 2. **DO NOT IMPLEMENT if information is incomplete**
40
+
41
+ - If the prompt lacks critical details (interfaces, methods, config options, persistence strategy, etc.)
42
+ - If access control requirements are unclear
43
+ - If the connector pattern to follow is not specified
44
+ - If testing requirements are not mentioned
45
+
46
+ 3. **ASK QUESTIONS FIRST**
47
+
48
+ - Request clarification on missing details
49
+ - Ask about specific methods and their signatures
50
+ - Inquire about configuration options
51
+ - Confirm access control and isolation requirements
52
+ - Verify testing expectations
53
+
54
+ 4. **Establish an Elaborated Plan**
55
+
56
+ - Only after gathering ALL necessary information
57
+ - Create a detailed specification document (like the one below)
58
+ - Include complete interfaces, method signatures, and config types
59
+ - Define file structure and naming conventions
60
+ - Specify testing requirements
61
+ - Outline security and ACL patterns
62
+
63
+ 5. **Get User Approval**
64
+
65
+ - Present the elaborated plan to the user
66
+ - Wait for confirmation before proceeding
67
+ - Make adjustments based on feedback
68
+
69
+ 6. **Then Implement**
70
+ - Only start implementation after the plan is complete and approved
71
+ - Follow the elaborated specification exactly
72
+ - Maintain consistency with existing SRE patterns
73
+
74
+ ## Processing the user prompt
75
+
76
+ Before processing the user prompt, elaborate it in order to make it more clear and detailed. check below :
77
+
78
+ ## The elaborated prompt
79
+
80
+ Implement a **Scheduler service** following the SRE connector pattern. This service will manage scheduled jobs with full ACL-based access control and multi-candidate isolation.
81
+
82
+ ### Architecture Requirements
83
+
84
+ #### 1. Service Structure
85
+
86
+ Create the following structure under `packages/core/src/subsystems/AgentManager/Scheduler.service/`:
87
+
88
+ ```
89
+ Scheduler.service/
90
+ ├── index.ts # Service entry point
91
+ ├── SchedulerConnector.ts # Abstract base connector
92
+ ├── Schedule.class.ts # Schedule builder with fluent API
93
+ ├── Job.class.ts # Job wrapper class
94
+ └── connectors/
95
+ └── LocalScheduler.class.ts # Local disk-based implementation
96
+ ```
97
+
98
+ #### 2. SchedulerConnector (Abstract Base Class)
99
+
100
+ **File**: `SchedulerConnector.ts`
101
+
102
+ **Requirements**:
103
+
104
+ - Extend `SecureConnector<ISchedulerRequest>`
105
+ - Define the `ISchedulerRequest` interface with public-facing methods
106
+ - Implement `requester(candidate: AccessCandidate): ISchedulerRequest` to expose access-controlled operations
107
+ - Define abstract protected methods decorated with `@SecureConnector.AccessControl`
108
+ - Implement `abstract getResourceACL(resourceId: string, candidate: IAccessCandidate): Promise<ACL>`
109
+
110
+ **Core Methods** (to be exposed via ISchedulerRequest):
111
+
112
+ ```typescript
113
+ interface ISchedulerRequest {
114
+ list(): Promise<IScheduledJob[]>;
115
+ add(jobId: string, schedule: Schedule, job: Job): Promise<void>;
116
+ delete(jobId: string): Promise<void>;
117
+ get(jobId: string): Promise<IScheduledJob | undefined>;
118
+ pause(jobId: string): Promise<void>;
119
+ resume(jobId: string): Promise<void>;
120
+ }
121
+ ```
122
+
123
+ **Protected Abstract Methods** (implementations):
124
+
125
+ ```typescript
126
+ protected abstract list(acRequest: AccessRequest): Promise<IScheduledJob[]>;
127
+ protected abstract add(acRequest: AccessRequest, jobId: string, schedule: Schedule, job: Job): Promise<void>;
128
+ protected abstract delete(acRequest: AccessRequest, jobId: string): Promise<void>;
129
+ protected abstract get(acRequest: AccessRequest, jobId: string): Promise<IScheduledJob | undefined>;
130
+ protected abstract pause(acRequest: AccessRequest, jobId: string): Promise<void>;
131
+ protected abstract resume(acRequest: AccessRequest, jobId: string): Promise<void>;
132
+ ```
133
+
134
+ **Pattern Reference**:
135
+
136
+ - See `VectorDBConnector.ts` for how `requester()` wraps protected methods with candidate access requests
137
+ - See `StorageConnector.ts` for the generic type parameter pattern `extends SecureConnector<IRequest>`
138
+
139
+ #### 3. Schedule Class (Fluent Builder)
140
+
141
+ **File**: `Schedule.class.ts`
142
+
143
+ **Requirements**:
144
+
145
+ - Fluent API for building schedule definitions
146
+ - Support for common time intervals: seconds (s), minutes (m), hours (h), days (d), weeks (w)
147
+ - Optional start and end dates
148
+ - Serializable to JSON for persistence
149
+ - Parseable from JSON for restoration
150
+
151
+ **Example API**:
152
+
153
+ ```typescript
154
+ // Build a schedule
155
+ const schedule = Schedule.starts(new Date('2025-01-01')).ends(new Date('2025-12-31')).every('10m');
156
+
157
+ // Alternative patterns
158
+ Schedule.every('30s');
159
+ Schedule.every('2h').starts(tomorrow);
160
+ Schedule.cron('0 0 * * *'); // Optional: cron syntax support
161
+
162
+ // Serialization
163
+ const json = schedule.toJSON();
164
+ const restored = Schedule.fromJSON(json);
165
+ ```
166
+
167
+ **JSON Format** (suggested):
168
+
169
+ ```typescript
170
+ interface IScheduleData {
171
+ interval: string; // e.g., "10m", "30s", "2h"
172
+ startDate?: string; // ISO 8601
173
+ endDate?: string; // ISO 8601
174
+ cron?: string; // Optional cron expression
175
+ }
176
+ ```
177
+
178
+ #### 4. Job Class
179
+
180
+ **File**: `Job.class.ts`
181
+
182
+ **Requirements**:
183
+
184
+ - Wrap executable function with metadata
185
+ - Support async and sync functions
186
+ - Store serializable metadata about the job
187
+ - Handle execution context and error handling
188
+
189
+ **Example API**:
190
+
191
+ ```typescript
192
+ const job = new Job(
193
+ async () => {
194
+ console.log('Executing scheduled task');
195
+ // Task logic here
196
+ },
197
+ {
198
+ name: 'Daily Cleanup',
199
+ description: 'Clean up temporary files',
200
+ tags: ['maintenance', 'cleanup'],
201
+ retryOnFailure: true,
202
+ maxRetries: 3,
203
+ }
204
+ );
205
+ ```
206
+
207
+ **Interface**:
208
+
209
+ ```typescript
210
+ interface IJobMetadata {
211
+ name: string;
212
+ description?: string;
213
+ tags?: string[];
214
+ retryOnFailure?: boolean;
215
+ maxRetries?: number;
216
+ timeout?: number; // in milliseconds
217
+ [key: string]: any; // Additional custom metadata
218
+ }
219
+
220
+ interface IScheduledJob {
221
+ id: string;
222
+ schedule: IScheduleData;
223
+ metadata: IJobMetadata;
224
+ acl: IACL;
225
+ status: 'active' | 'paused'; // User-controlled state only (not execution results)
226
+ lastRun?: Date;
227
+ nextRun?: Date;
228
+ createdBy: {
229
+ role: TAccessRole;
230
+ id: string;
231
+ };
232
+ executionHistory?: IJobExecution[]; // Execution results stored here
233
+ }
234
+ ```
235
+
236
+ #### 5. LocalScheduler Implementation
237
+
238
+ **File**: `connectors/LocalScheduler.class.ts`
239
+
240
+ **Requirements**:
241
+
242
+ **Persistence**:
243
+
244
+ - Store job data in JSON files under `~/.smyth/scheduler/` or configurable folder
245
+ - File naming: `{candidateRole}_{candidateId}_{jobId}.json`
246
+ - Each file contains: schedule, metadata, ACL, status, execution history
247
+ - Load all jobs on initialization
248
+ - Auto-save on add/update/delete operations
249
+
250
+ **Execution**:
251
+
252
+ - Use `node-cron` or `node-schedule` library for time-based triggers (or implement custom timer logic)
253
+ - On service start, load all jobs and schedule active ones
254
+ - Execute jobs in their own try-catch blocks with error logging
255
+ - Track last run time and calculate next run time
256
+ - Support pause/resume functionality
257
+ - Clean up completed or expired jobs
258
+
259
+ **Access Control**:
260
+
261
+ - Each job is owned by the candidate who created it
262
+ - Job IDs are scoped per candidate (different candidates can have jobs with same ID)
263
+ - `getResourceACL()` should:
264
+ - Return owner-level ACL if job doesn't exist (allow creation)
265
+ - Return stored ACL if job exists
266
+ - Read ACL from the persisted JSON file
267
+ - All protected methods must use `@SecureConnector.AccessControl` decorator
268
+ - Follow ownership preservation pattern: creator ALWAYS retains Owner access
269
+
270
+ **Constructor Config**:
271
+
272
+ ```typescript
273
+ export type LocalSchedulerConfig = {
274
+ folder?: string; // Storage folder, defaults to ~/.smyth/scheduler
275
+ autoStart?: boolean; // Auto-start scheduler on init, defaults to true
276
+ persistExecutionHistory?: boolean; // Keep execution logs
277
+ };
278
+ ```
279
+
280
+ **Internal Structure**:
281
+
282
+ ```typescript
283
+ class LocalScheduler extends SchedulerConnector {
284
+ public name = 'LocalScheduler';
285
+ public id = 'local';
286
+
287
+ private folder: string;
288
+ private jobs: Map<string, ScheduledJobRuntime>; // In-memory job registry
289
+ private isInitialized = false;
290
+
291
+ constructor(protected _settings?: LocalSchedulerConfig) {
292
+ super(_settings);
293
+ this.folder = this.findSchedulerFolder(_settings?.folder);
294
+ this.initialize();
295
+ }
296
+
297
+ private async initialize() {
298
+ // Create storage folder if not exists
299
+ // Load all job files from disk
300
+ // Schedule active jobs
301
+ // Start internal timer/scheduler
302
+ }
303
+
304
+ private constructJobPath(candidate: IAccessCandidate, jobId: string): string {
305
+ // Return: {folder}/{role}_{candidateId}_{jobId}.json
306
+ }
307
+
308
+ private async scheduleJob(jobData: IScheduledJob) {
309
+ // Parse schedule and set up timer
310
+ // Store timer reference for cleanup
311
+ }
312
+
313
+ private async unscheduleJob(jobId: string) {
314
+ // Cancel timer
315
+ // Remove from active jobs
316
+ }
317
+ }
318
+ ```
319
+
320
+ **Pattern References**:
321
+
322
+ - See `LocalStorage.class.ts` for:
323
+ - File-based persistence patterns
324
+ - Folder initialization (`~/.smyth/...`)
325
+ - Metadata serialization/deserialization
326
+ - ACL preservation in `setACL()` method (line 244)
327
+ - See `RAMVectorDB.class.ts` for:
328
+ - In-memory data structures
329
+ - Static storage for shared state across instances
330
+ - `getResourceACL()` implementation (line 82-93)
331
+ - Access control patterns
332
+
333
+ #### 6. Service Index
334
+
335
+ **File**: `index.ts`
336
+
337
+ Export all public classes and types:
338
+
339
+ ```typescript
340
+ export { SchedulerConnector } from './SchedulerConnector';
341
+ export { LocalScheduler } from './connectors/LocalScheduler.class';
342
+ export { Schedule } from './Schedule.class';
343
+ export { Job } from './Job.class';
344
+ export type { ISchedulerRequest, IScheduledJob, IJobMetadata, IScheduleData } from './SchedulerConnector';
345
+ ```
346
+
347
+ ### Security & Isolation Requirements
348
+
349
+ 1. **ACL Ownership Preservation** ⚠️ CRITICAL
350
+
351
+ - When updating job ACL, ALWAYS preserve original creator's Owner access
352
+ - Pattern: `ACL.from(acl).addAccess(candidate.role, candidate.id, TAccessLevel.Owner)`
353
+
354
+ 2. **Candidate Isolation**
355
+
356
+ - Jobs are scoped per candidate (role + id)
357
+ - Candidates can only list/access their own jobs (unless shared via ACL)
358
+ - File paths must include candidate identifier
359
+
360
+ 3. **Access Control Decorator**
361
+
362
+ - ALL protected methods MUST use `@SecureConnector.AccessControl`
363
+ - This decorator automatically validates access before method execution
364
+ - Throws error if access denied
365
+
366
+ 4. **Resource Naming**
367
+ - JobId as resourceId for ACL lookup
368
+ - Construct unique paths: `{role}_{id}_{jobId}`
369
+
370
+ ### Testing Requirements
371
+
372
+ Create comprehensive tests following SRE patterns:
373
+
374
+ **Unit Tests** (`tests/unit/scheduler.test.ts`):
375
+
376
+ - Mock file system operations
377
+ - Test Schedule builder API
378
+ - Test Job class
379
+ - Test ACL validation logic
380
+ - Test schedule parsing and calculation
381
+
382
+ **Integration Tests** (`tests/integration/scheduler.test.ts`):
383
+
384
+ - Real LocalScheduler instance
385
+ - Create/list/delete jobs
386
+ - Test job execution triggers
387
+ - Verify persistence across restarts
388
+ - Test multi-candidate isolation
389
+ - Validate ACL ownership preservation
390
+
391
+ ### Dependencies
392
+
393
+ Add to `packages/core/package.json` if needed:
394
+
395
+ ```json
396
+ {
397
+ "dependencies": {
398
+ "node-cron": "^3.0.3" // or "node-schedule": "^2.1.1"
399
+ }
400
+ }
401
+ ```
402
+
403
+ ### Implementation Checklist
404
+
405
+ - [ ] Create service folder structure
406
+ - [ ] Implement `ISchedulerRequest` interface
407
+ - [ ] Implement `SchedulerConnector` abstract base class
408
+ - [ ] Implement `Schedule` class with fluent API
409
+ - [ ] Implement `Job` class
410
+ - [ ] Implement `LocalScheduler` with file persistence
411
+ - [ ] Add job scheduling/execution logic
412
+ - [ ] Implement `getResourceACL()` with proper ACL handling
413
+ - [ ] Add `@SecureConnector.AccessControl` to all protected methods
414
+ - [ ] Create service index with exports
415
+ - [ ] **Integrate service into SRE boot sequence** (see below)
416
+ - [ ] Write unit tests (mocked)
417
+ - [ ] Write integration tests (real connector)
418
+ - [ ] Update main exports in `packages/core/src/index.ts`
419
+ - [ ] Add documentation
420
+ - [ ] Test ACL ownership preservation
421
+ - [ ] Test candidate isolation
422
+
423
+ ### Integrating a New Service into SRE Boot Sequence
424
+
425
+ When creating a **brand new service** (not just a connector for an existing service), you must integrate it into the SRE initialization process. Follow these steps:
426
+
427
+ #### 1. Update Type Definitions (`packages/core/src/types/SRE.types.ts`)
428
+
429
+ Add your service to the type system:
430
+
431
+ ```typescript
432
+ // Import the service class
433
+ import { SchedulerService } from '@sre/AgentManager/Scheduler.service';
434
+
435
+ // Add to TServiceRegistry
436
+ export type TServiceRegistry = {
437
+ // ... existing services
438
+ Scheduler?: SchedulerService;
439
+ };
440
+
441
+ // Add to TConnectorService enum
442
+ export enum TConnectorService {
443
+ // ... existing connectors
444
+ Scheduler = 'Scheduler',
445
+ }
446
+ ```
447
+
448
+ #### 2. Create Service Class (`packages/core/src/subsystems/.../YourService/index.ts`)
449
+
450
+ Create a service class that extends `ConnectorServiceProvider`:
451
+
452
+ ```typescript
453
+ //==[ SRE: YourService ]======================
454
+
455
+ import { ConnectorService, ConnectorServiceProvider } from '@sre/Core/ConnectorsService';
456
+ import { TConnectorService } from '@sre/types/SRE.types';
457
+ import { YourConnector } from './connectors/YourConnector.class';
458
+
459
+ export class YourService extends ConnectorServiceProvider {
460
+ public register() {
461
+ // Register all connector implementations for this service
462
+ ConnectorService.register(TConnectorService.YourService, 'DefaultConnector', YourConnector);
463
+ // Register additional connectors if needed
464
+ }
465
+ }
466
+
467
+ // Export your connector classes and types below
468
+ export { YourConnector } from './YourConnector';
469
+ // ... other exports
470
+ ```
471
+
472
+ #### 3. Update Boot Sequence (`packages/core/src/Core/boot.ts`)
473
+
474
+ Register your service in the boot sequence:
475
+
476
+ ```typescript
477
+ // Add import
478
+ import { YourService } from '@sre/path/to/YourService';
479
+
480
+ export function boot() {
481
+ // ... existing code
482
+
483
+ // Add service instantiation (order matters for dependencies)
484
+ service.YourService = new YourService();
485
+
486
+ // ... rest of boot code
487
+ }
488
+ ```
489
+
490
+ **Note**: Service initialization order matters if there are dependencies. For example, NKV should be loaded before VectorDB.
491
+
492
+ #### 4. Add Default Configuration (`packages/core/src/Core/SmythRuntime.class.ts`)
493
+
494
+ Add default connector configuration:
495
+
496
+ ```typescript
497
+ private defaultConfig: SREConfig = {
498
+ // ... existing configs
499
+ YourService: {
500
+ Connector: 'DefaultConnector',
501
+ Settings: {
502
+ // Default settings
503
+ option1: true,
504
+ option2: 'default-value',
505
+ },
506
+ },
507
+ };
508
+ ```
509
+
510
+ #### 5. Add Connector Getter (`packages/core/src/Core/ConnectorsService.ts`)
511
+
512
+ Add import and getter method:
513
+
514
+ ```typescript
515
+ // Add import at top
516
+ import { YourConnector } from '@sre/path/to/YourService/YourConnector';
517
+
518
+ // Add getter method in ConnectorService class
519
+ static getYourServiceConnector(name?: string): YourConnector {
520
+ return ConnectorService.getInstance<YourConnector>(TConnectorService.YourService, name);
521
+ }
522
+ ```
523
+
524
+ #### 6. Verification
525
+
526
+ After integration, verify:
527
+
528
+ - ✅ Service appears in `TServiceRegistry` type
529
+ - ✅ Connector type in `TConnectorService` enum
530
+ - ✅ Service instantiated in `boot.ts`
531
+ - ✅ Default config in `SmythRuntime.class.ts`
532
+ - ✅ Getter method in `ConnectorsService.ts`
533
+ - ✅ Service class extends `ConnectorServiceProvider`
534
+ - ✅ Connectors registered in service's `register()` method
535
+
536
+ #### Example: Scheduler Service Integration
537
+
538
+ ```typescript
539
+ // 1. SRE.types.ts
540
+ import { SchedulerService } from '@sre/AgentManager/Scheduler.service';
541
+ export type TServiceRegistry = {
542
+ Scheduler?: SchedulerService;
543
+ };
544
+ export enum TConnectorService {
545
+ Scheduler = 'Scheduler',
546
+ }
547
+
548
+ // 2. Scheduler.service/index.ts
549
+ export class SchedulerService extends ConnectorServiceProvider {
550
+ public register() {
551
+ ConnectorService.register(TConnectorService.Scheduler, 'LocalScheduler', LocalScheduler);
552
+ }
553
+ }
554
+
555
+ // 3. boot.ts
556
+ import { SchedulerService } from '@sre/AgentManager/Scheduler.service';
557
+ service.Scheduler = new SchedulerService();
558
+
559
+ // 4. SmythRuntime.class.ts
560
+ Scheduler: {
561
+ Connector: 'LocalScheduler',
562
+ Settings: { autoStart: true },
563
+ },
564
+
565
+ // 5. ConnectorsService.ts
566
+ import { SchedulerConnector } from '@sre/AgentManager/Scheduler.service/SchedulerConnector';
567
+ static getSchedulerConnector(name?: string): SchedulerConnector {
568
+ return ConnectorService.getInstance<SchedulerConnector>(TConnectorService.Scheduler, name);
569
+ }
570
+ ```
571
+
572
+ ### Key Patterns to Follow
573
+
574
+ 1. **Connector Pattern**: Abstract base + concrete implementations
575
+ 2. **Requester Pattern**: Public interface via `requester(candidate)`
576
+ 3. **Access Control**: Decorator on all protected methods
577
+ 4. **ACL Ownership**: Always preserve creator's Owner access
578
+ 5. **Naming Convention**: `.class.ts` for classes, `.service.ts` for top-level services
579
+ 6. **Isolation**: Candidate-scoped resources
580
+ 7. **Serialization**: JSON for persistence, include ACL in stored data
581
+
582
+ ### Summary
583
+
584
+ This scheduler service provides cron-like functionality with:
585
+
586
+ - ✅ Full ACL-based access control
587
+ - ✅ Multi-candidate isolation
588
+ - ✅ Persistent local storage
589
+ - ✅ Fluent schedule definition API
590
+ - ✅ Automatic job execution
591
+ - ✅ Pause/resume capabilities
592
+ - ✅ Follows established SRE connector patterns
593
+
594
+ The implementation should be production-ready, well-tested, and consistent with existing SRE subsystems.