@dexto/tools-scheduler 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/LICENSE +44 -0
  2. package/dist/error-codes.cjs +44 -0
  3. package/dist/error-codes.d.cts +21 -0
  4. package/dist/error-codes.d.ts +21 -0
  5. package/dist/error-codes.js +20 -0
  6. package/dist/errors.cjs +163 -0
  7. package/dist/errors.d.cts +64 -0
  8. package/dist/errors.d.ts +64 -0
  9. package/dist/errors.js +138 -0
  10. package/dist/executor.cjs +161 -0
  11. package/dist/executor.d.cts +46 -0
  12. package/dist/executor.d.ts +46 -0
  13. package/dist/executor.js +137 -0
  14. package/dist/index.cjs +89 -0
  15. package/dist/index.d.cts +19 -0
  16. package/dist/index.d.ts +19 -0
  17. package/dist/index.js +56 -0
  18. package/dist/manager.cjs +461 -0
  19. package/dist/manager.d.cts +113 -0
  20. package/dist/manager.d.ts +113 -0
  21. package/dist/manager.js +430 -0
  22. package/dist/schemas.cjs +138 -0
  23. package/dist/schemas.d.cts +263 -0
  24. package/dist/schemas.d.ts +263 -0
  25. package/dist/schemas.js +105 -0
  26. package/dist/storage.cjs +249 -0
  27. package/dist/storage.d.cts +62 -0
  28. package/dist/storage.d.ts +62 -0
  29. package/dist/storage.js +225 -0
  30. package/dist/tool-provider.cjs +239 -0
  31. package/dist/tool-provider.d.cts +34 -0
  32. package/dist/tool-provider.d.ts +34 -0
  33. package/dist/tool-provider.js +212 -0
  34. package/dist/tool-types.cjs +16 -0
  35. package/dist/tool-types.d.cts +9 -0
  36. package/dist/tool-types.d.ts +9 -0
  37. package/dist/tool-types.js +0 -0
  38. package/dist/tools/create-schedule.cjs +75 -0
  39. package/dist/tools/create-schedule.d.cts +14 -0
  40. package/dist/tools/create-schedule.d.ts +14 -0
  41. package/dist/tools/create-schedule.js +51 -0
  42. package/dist/tools/delete-schedule.cjs +45 -0
  43. package/dist/tools/delete-schedule.d.cts +14 -0
  44. package/dist/tools/delete-schedule.d.ts +14 -0
  45. package/dist/tools/delete-schedule.js +21 -0
  46. package/dist/tools/get-history.cjs +63 -0
  47. package/dist/tools/get-history.d.cts +14 -0
  48. package/dist/tools/get-history.d.ts +14 -0
  49. package/dist/tools/get-history.js +39 -0
  50. package/dist/tools/get-schedule.cjs +68 -0
  51. package/dist/tools/get-schedule.d.cts +14 -0
  52. package/dist/tools/get-schedule.d.ts +14 -0
  53. package/dist/tools/get-schedule.js +44 -0
  54. package/dist/tools/list-schedules.cjs +67 -0
  55. package/dist/tools/list-schedules.d.cts +14 -0
  56. package/dist/tools/list-schedules.d.ts +14 -0
  57. package/dist/tools/list-schedules.js +43 -0
  58. package/dist/tools/trigger-schedule.cjs +56 -0
  59. package/dist/tools/trigger-schedule.d.cts +14 -0
  60. package/dist/tools/trigger-schedule.d.ts +14 -0
  61. package/dist/tools/trigger-schedule.js +32 -0
  62. package/dist/tools/update-schedule.cjs +53 -0
  63. package/dist/tools/update-schedule.d.cts +14 -0
  64. package/dist/tools/update-schedule.d.ts +14 -0
  65. package/dist/tools/update-schedule.js +29 -0
  66. package/dist/types.cjs +16 -0
  67. package/dist/types.d.cts +72 -0
  68. package/dist/types.d.ts +72 -0
  69. package/dist/types.js +0 -0
  70. package/package.json +41 -0
@@ -0,0 +1,430 @@
1
+ import cron from "node-cron";
2
+ import * as cronParser from "cron-parser";
3
+ import { randomUUID } from "crypto";
4
+ import { DextoRuntimeError } from "@dexto/core";
5
+ import {
6
+ CreateScheduleInputSchema,
7
+ UpdateScheduleFieldsOnlySchema
8
+ } from "./schemas.js";
9
+ import { ScheduleStorage } from "./storage.js";
10
+ import { ScheduleExecutor } from "./executor.js";
11
+ import { SchedulerError } from "./errors.js";
12
+ class SchedulerManager {
13
+ constructor(storageManager, config, logger) {
14
+ this.config = config;
15
+ this.logger = logger;
16
+ this.storage = new ScheduleStorage(storageManager, config.maxExecutionHistory, logger);
17
+ this.executor = new ScheduleExecutor(config.executionTimeout, logger);
18
+ }
19
+ cronTasks = /* @__PURE__ */ new Map();
20
+ storage;
21
+ executor;
22
+ executionChain = Promise.resolve();
23
+ initialized = false;
24
+ started = false;
25
+ cachedSchedules;
26
+ /**
27
+ * Set the executor function (called to run the agent with a prompt)
28
+ */
29
+ setExecutor(fn) {
30
+ this.executor.setExecutor(fn);
31
+ }
32
+ /**
33
+ * Initialize the scheduler (load schedules from storage)
34
+ */
35
+ async init() {
36
+ if (this.initialized) {
37
+ return;
38
+ }
39
+ try {
40
+ const storedSchedules = await this.storage.listSchedules();
41
+ this.cachedSchedules = storedSchedules;
42
+ this.logger.info(`Loaded ${storedSchedules.length} schedules from storage`);
43
+ this.initialized = true;
44
+ } catch (error) {
45
+ throw SchedulerError.invalidConfig(
46
+ `Failed to initialize scheduler: ${error instanceof Error ? error.message : String(error)}`
47
+ );
48
+ }
49
+ }
50
+ /**
51
+ * Start the scheduler (begin executing schedules)
52
+ */
53
+ async start() {
54
+ if (!this.initialized) {
55
+ await this.init();
56
+ }
57
+ if (this.started) {
58
+ return;
59
+ }
60
+ try {
61
+ const schedules = this.cachedSchedules ?? await this.storage.listSchedules();
62
+ this.cachedSchedules = void 0;
63
+ for (const schedule of schedules) {
64
+ if (schedule.enabled) {
65
+ await this.scheduleTask(schedule);
66
+ }
67
+ }
68
+ this.started = true;
69
+ this.logger.info(`Scheduler started with ${this.cronTasks.size} active schedules`);
70
+ } catch (error) {
71
+ throw SchedulerError.invalidConfig(
72
+ `Failed to start scheduler: ${error instanceof Error ? error.message : String(error)}`
73
+ );
74
+ }
75
+ }
76
+ /**
77
+ * Stop the scheduler (stop all running tasks)
78
+ */
79
+ async stop() {
80
+ if (!this.started) {
81
+ return;
82
+ }
83
+ for (const task of this.cronTasks.values()) {
84
+ task.stop();
85
+ }
86
+ this.cronTasks.clear();
87
+ this.started = false;
88
+ this.logger.info("Scheduler stopped");
89
+ }
90
+ /**
91
+ * Create a new schedule
92
+ *
93
+ * @param input - Schedule creation input
94
+ * @param currentSessionId - The current session ID (used for 'inherit' mode)
95
+ */
96
+ async createSchedule(input, currentSessionId) {
97
+ const validated = CreateScheduleInputSchema.parse(input);
98
+ const existingSchedules = await this.storage.listSchedules();
99
+ if (existingSchedules.length >= this.config.maxSchedules) {
100
+ throw SchedulerError.limitReached(existingSchedules.length, this.config.maxSchedules);
101
+ }
102
+ if (!cron.validate(validated.cronExpression)) {
103
+ throw SchedulerError.invalidCron(validated.cronExpression, "Invalid cron format");
104
+ }
105
+ let resolvedSessionId;
106
+ const sessionMode = validated.sessionMode ?? "ephemeral";
107
+ if (sessionMode === "inherit") {
108
+ if (!currentSessionId) {
109
+ throw SchedulerError.invalidInput(
110
+ 'sessionMode "inherit" requires a current session context'
111
+ );
112
+ }
113
+ resolvedSessionId = currentSessionId;
114
+ } else if (sessionMode === "fixed") {
115
+ resolvedSessionId = validated.sessionId;
116
+ }
117
+ const now = Date.now();
118
+ const taskMetadata = {
119
+ ...validated.metadata
120
+ };
121
+ if (validated.targetAgentId) {
122
+ taskMetadata.__os_targetAgentId = validated.targetAgentId;
123
+ }
124
+ const workspacePath = validated.workspacePath && validated.workspacePath.trim().length > 0 ? validated.workspacePath : void 0;
125
+ const schedule = {
126
+ id: randomUUID(),
127
+ name: validated.name,
128
+ cronExpression: validated.cronExpression,
129
+ timezone: validated.timezone || this.config.timezone,
130
+ enabled: validated.enabled,
131
+ task: {
132
+ instruction: validated.instruction,
133
+ ...Object.keys(taskMetadata).length > 0 && { metadata: taskMetadata }
134
+ },
135
+ sessionMode,
136
+ ...resolvedSessionId && { sessionId: resolvedSessionId },
137
+ ...workspacePath ? { workspacePath } : {},
138
+ createdAt: now,
139
+ updatedAt: now,
140
+ runCount: 0,
141
+ successCount: 0,
142
+ failureCount: 0
143
+ };
144
+ const nextRun = this.calculateNextRun(schedule);
145
+ if (nextRun !== void 0) {
146
+ schedule.nextRunAt = nextRun;
147
+ }
148
+ await this.storage.saveSchedule(schedule);
149
+ if (schedule.enabled && this.started) {
150
+ await this.scheduleTask(schedule);
151
+ }
152
+ this.logger.info(`Schedule created: ${schedule.name}`, {
153
+ scheduleId: schedule.id,
154
+ sessionMode,
155
+ cronExpression: schedule.cronExpression
156
+ });
157
+ return schedule;
158
+ }
159
+ /**
160
+ * Update an existing schedule
161
+ *
162
+ * @param scheduleId - The schedule ID to update
163
+ * @param updates - The updates to apply
164
+ * @param currentSessionId - The current session ID (used if changing to 'inherit' mode)
165
+ */
166
+ async updateSchedule(scheduleId, updates, currentSessionId) {
167
+ const validated = UpdateScheduleFieldsOnlySchema.parse(updates);
168
+ const existing = await this.storage.loadSchedule(scheduleId);
169
+ if (!existing) {
170
+ throw SchedulerError.notFound(scheduleId);
171
+ }
172
+ if (validated.cronExpression && !cron.validate(validated.cronExpression)) {
173
+ throw SchedulerError.invalidCron(validated.cronExpression, "Invalid cron format");
174
+ }
175
+ let updatedSessionId = existing.sessionId;
176
+ const newSessionMode = validated.sessionMode ?? existing.sessionMode;
177
+ if (validated.sessionMode !== void 0) {
178
+ if (newSessionMode === "inherit") {
179
+ if (!currentSessionId) {
180
+ throw SchedulerError.invalidInput(
181
+ 'sessionMode "inherit" requires a current session context'
182
+ );
183
+ }
184
+ updatedSessionId = currentSessionId;
185
+ } else if (newSessionMode === "fixed") {
186
+ updatedSessionId = validated.sessionId;
187
+ } else {
188
+ updatedSessionId = void 0;
189
+ }
190
+ } else if (validated.sessionId !== void 0) {
191
+ updatedSessionId = validated.sessionId;
192
+ }
193
+ const existingTaskMetadata = existing.task.metadata ?? {};
194
+ const updatedTaskMetadata = validated.metadata !== void 0 ? { ...validated.metadata } : { ...existingTaskMetadata };
195
+ for (const [key, value] of Object.entries(existingTaskMetadata)) {
196
+ if (key.startsWith("__os_")) {
197
+ updatedTaskMetadata[key] = value;
198
+ }
199
+ }
200
+ if (validated.targetAgentId !== void 0) {
201
+ if (validated.targetAgentId) {
202
+ updatedTaskMetadata.__os_targetAgentId = validated.targetAgentId;
203
+ } else {
204
+ delete updatedTaskMetadata.__os_targetAgentId;
205
+ }
206
+ }
207
+ const resolvedWorkspacePath = validated.workspacePath === void 0 ? existing.workspacePath : validated.workspacePath && validated.workspacePath.trim().length > 0 ? validated.workspacePath : void 0;
208
+ const updated = {
209
+ ...existing,
210
+ ...validated.name !== void 0 && { name: validated.name },
211
+ ...validated.cronExpression !== void 0 && {
212
+ cronExpression: validated.cronExpression
213
+ },
214
+ ...validated.timezone !== void 0 && { timezone: validated.timezone },
215
+ ...validated.enabled !== void 0 && { enabled: validated.enabled },
216
+ task: {
217
+ ...existing.task,
218
+ ...validated.instruction !== void 0 && { instruction: validated.instruction },
219
+ ...Object.keys(updatedTaskMetadata).length > 0 ? { metadata: updatedTaskMetadata } : {}
220
+ },
221
+ sessionMode: newSessionMode,
222
+ ...updatedSessionId !== void 0 ? { sessionId: updatedSessionId } : {},
223
+ updatedAt: Date.now()
224
+ };
225
+ if (resolvedWorkspacePath) {
226
+ updated.workspacePath = resolvedWorkspacePath;
227
+ } else {
228
+ delete updated.workspacePath;
229
+ }
230
+ if (newSessionMode === "ephemeral" || newSessionMode === "dedicated") {
231
+ delete updated.sessionId;
232
+ }
233
+ const nextRunTime = this.calculateNextRun(updated);
234
+ if (nextRunTime !== void 0) {
235
+ updated.nextRunAt = nextRunTime;
236
+ }
237
+ await this.storage.saveSchedule(updated);
238
+ if (this.started) {
239
+ this.unscheduleTask(scheduleId);
240
+ if (updated.enabled) {
241
+ await this.scheduleTask(updated);
242
+ }
243
+ }
244
+ this.logger.info(`Schedule updated: ${updated.name}`, {
245
+ scheduleId,
246
+ sessionMode: newSessionMode
247
+ });
248
+ return updated;
249
+ }
250
+ /**
251
+ * Delete a schedule
252
+ */
253
+ async deleteSchedule(scheduleId) {
254
+ const schedule = await this.storage.loadSchedule(scheduleId);
255
+ if (!schedule) {
256
+ throw SchedulerError.notFound(scheduleId);
257
+ }
258
+ if (this.started) {
259
+ this.unscheduleTask(scheduleId);
260
+ }
261
+ await this.storage.deleteSchedule(scheduleId);
262
+ this.logger.info(`Schedule deleted: ${schedule.name}`, { scheduleId });
263
+ }
264
+ /**
265
+ * Get a schedule by ID
266
+ */
267
+ async getSchedule(scheduleId) {
268
+ return this.storage.loadSchedule(scheduleId);
269
+ }
270
+ /**
271
+ * List schedules with optional filters
272
+ */
273
+ async listSchedules(filters) {
274
+ const schedules = await this.storage.listSchedules();
275
+ if (!filters) {
276
+ return schedules;
277
+ }
278
+ return schedules.filter((schedule) => {
279
+ if (filters.enabled !== void 0 && schedule.enabled !== filters.enabled) {
280
+ return false;
281
+ }
282
+ return true;
283
+ });
284
+ }
285
+ /**
286
+ * Trigger a schedule immediately (manual execution)
287
+ */
288
+ async triggerScheduleNow(scheduleId) {
289
+ const schedule = await this.storage.loadSchedule(scheduleId);
290
+ if (!schedule) {
291
+ throw SchedulerError.notFound(scheduleId);
292
+ }
293
+ this.logger.info(`Manually triggering schedule: ${schedule.name}`, { scheduleId });
294
+ return this.executeSchedule(schedule);
295
+ }
296
+ /**
297
+ * Get execution history for a schedule
298
+ */
299
+ async getExecutionHistory(scheduleId, limit) {
300
+ return this.storage.getExecutionLogs(scheduleId, limit);
301
+ }
302
+ /**
303
+ * Get scheduler status
304
+ */
305
+ getStatus() {
306
+ return {
307
+ initialized: this.initialized,
308
+ started: this.started,
309
+ activeSchedules: this.cronTasks.size
310
+ };
311
+ }
312
+ /**
313
+ * Schedule a task using cron
314
+ */
315
+ async scheduleTask(schedule) {
316
+ this.unscheduleTask(schedule.id);
317
+ if (!schedule.enabled) {
318
+ return;
319
+ }
320
+ try {
321
+ const task = cron.schedule(
322
+ schedule.cronExpression,
323
+ () => {
324
+ this.executeSchedule(schedule).catch((error) => {
325
+ this.logger.error(
326
+ `Failed to execute schedule ${schedule.id}: ${error instanceof Error ? error.message : String(error)}`
327
+ );
328
+ });
329
+ },
330
+ {
331
+ timezone: schedule.timezone,
332
+ name: schedule.id
333
+ }
334
+ );
335
+ task.start();
336
+ this.cronTasks.set(schedule.id, task);
337
+ this.logger.debug(`Schedule task registered: ${schedule.name}`, {
338
+ scheduleId: schedule.id,
339
+ cronExpression: schedule.cronExpression
340
+ });
341
+ } catch (error) {
342
+ throw SchedulerError.createFailed(
343
+ `Failed to schedule task: ${error instanceof Error ? error.message : String(error)}`
344
+ );
345
+ }
346
+ }
347
+ /**
348
+ * Unschedule a task
349
+ */
350
+ unscheduleTask(scheduleId) {
351
+ const task = this.cronTasks.get(scheduleId);
352
+ if (task) {
353
+ task.stop();
354
+ this.cronTasks.delete(scheduleId);
355
+ this.logger.debug(`Schedule task unregistered: ${scheduleId}`);
356
+ }
357
+ }
358
+ /**
359
+ * Execute a schedule
360
+ */
361
+ async executeSchedule(schedule) {
362
+ return await this.queueExecution(() => this.executeScheduleInternal(schedule));
363
+ }
364
+ async executeScheduleInternal(schedule) {
365
+ try {
366
+ const current = await this.storage.loadSchedule(schedule.id);
367
+ if (!current) {
368
+ throw SchedulerError.notFound(schedule.id);
369
+ }
370
+ const log = await this.executor.execute(current);
371
+ await this.storage.saveExecutionLog(log);
372
+ const updates = {
373
+ lastRunAt: log.triggeredAt,
374
+ runCount: current.runCount + 1,
375
+ updatedAt: Date.now()
376
+ };
377
+ if (log.status === "success") {
378
+ updates.successCount = current.successCount + 1;
379
+ } else if (log.status === "failed" || log.status === "timeout") {
380
+ updates.failureCount = current.failureCount + 1;
381
+ if (log.error) {
382
+ updates.lastError = log.error;
383
+ }
384
+ }
385
+ const nextRun = this.calculateNextRun(current);
386
+ if (nextRun !== void 0) {
387
+ updates.nextRunAt = nextRun;
388
+ }
389
+ const updated = { ...current, ...updates };
390
+ await this.storage.saveSchedule(updated);
391
+ return log;
392
+ } catch (error) {
393
+ if (error instanceof DextoRuntimeError) {
394
+ throw error;
395
+ }
396
+ throw SchedulerError.executionFailed(
397
+ schedule.id,
398
+ error instanceof Error ? error.message : String(error)
399
+ );
400
+ }
401
+ }
402
+ queueExecution(fn) {
403
+ const run = this.executionChain.then(fn);
404
+ this.executionChain = run.then(
405
+ () => void 0,
406
+ () => void 0
407
+ );
408
+ return run;
409
+ }
410
+ /**
411
+ * Calculate next run time for a schedule
412
+ */
413
+ calculateNextRun(schedule) {
414
+ try {
415
+ const interval = cronParser.parseExpression(schedule.cronExpression, {
416
+ tz: schedule.timezone
417
+ });
418
+ const next = interval.next();
419
+ return next.toDate().getTime();
420
+ } catch (error) {
421
+ this.logger.error(
422
+ `Failed to calculate next run: ${error instanceof Error ? error.message : String(error)}`
423
+ );
424
+ return void 0;
425
+ }
426
+ }
427
+ }
428
+ export {
429
+ SchedulerManager
430
+ };
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var schemas_exports = {};
20
+ __export(schemas_exports, {
21
+ CreateScheduleInputSchema: () => CreateScheduleInputSchema,
22
+ DeleteScheduleInputSchema: () => DeleteScheduleInputSchema,
23
+ GetScheduleHistoryInputSchema: () => GetScheduleHistoryInputSchema,
24
+ GetScheduleInputSchema: () => GetScheduleInputSchema,
25
+ ListSchedulesInputSchema: () => ListSchedulesInputSchema,
26
+ ScheduleSessionModeSchema: () => ScheduleSessionModeSchema,
27
+ SchedulerToolsConfigSchema: () => SchedulerToolsConfigSchema,
28
+ TriggerScheduleInputSchema: () => TriggerScheduleInputSchema,
29
+ UpdateScheduleFieldsOnlySchema: () => UpdateScheduleFieldsOnlySchema,
30
+ UpdateScheduleInputSchema: () => UpdateScheduleInputSchema
31
+ });
32
+ module.exports = __toCommonJS(schemas_exports);
33
+ var import_zod = require("zod");
34
+ const ScheduleSessionModeSchema = import_zod.z.enum(["ephemeral", "dedicated", "inherit", "fixed"]).describe(
35
+ `How to manage conversation context for scheduled executions:
36
+ \u2022 ephemeral - New isolated session each time (default). Use for standalone tasks like reports.
37
+ \u2022 dedicated - Persistent session for this schedule. Builds context over multiple runs.
38
+ \u2022 inherit - Continue in the current conversation. Use for "remind me later" scenarios.
39
+ \u2022 fixed - Use a specific sessionId. Advanced: for cross-session orchestration.`
40
+ );
41
+ const SchedulerToolsConfigSchema = import_zod.z.object({
42
+ type: import_zod.z.literal("scheduler-tools"),
43
+ timezone: import_zod.z.string().default("UTC").describe("Default timezone for schedules"),
44
+ maxSchedules: import_zod.z.number().default(100).describe("Maximum number of schedules"),
45
+ executionTimeout: import_zod.z.number().default(3e5).describe("Maximum execution time in milliseconds (default 5 minutes)"),
46
+ maxExecutionHistory: import_zod.z.number().default(100).describe("Maximum execution history entries to keep")
47
+ }).strict();
48
+ const CreateScheduleInputSchema = import_zod.z.object({
49
+ name: import_zod.z.string().min(1).max(100).describe(
50
+ 'Human-readable name for the schedule (e.g., "Coffee Reminder", "Daily Standup")'
51
+ ),
52
+ cronExpression: import_zod.z.string().describe('Cron expression (e.g., "0 9 * * 1-5" for weekdays at 9am)'),
53
+ instruction: import_zod.z.string().min(1).describe(
54
+ "What should happen when this schedule triggers. Be natural and clear about the intent."
55
+ ),
56
+ timezone: import_zod.z.string().optional().describe("Optional timezone (defaults to config timezone)"),
57
+ enabled: import_zod.z.boolean().default(true).describe("Whether schedule is enabled"),
58
+ metadata: import_zod.z.record(import_zod.z.unknown()).optional().describe("Optional metadata for the task"),
59
+ workspacePath: import_zod.z.string().optional().nullable().describe("Optional workspace path for scheduled runs"),
60
+ sessionMode: ScheduleSessionModeSchema.default("ephemeral").describe(
61
+ `Session context mode:
62
+ \u2022 ephemeral (default) - Fresh session each run. Example: "Send daily report"
63
+ \u2022 dedicated - Same session across runs. Example: "Track project progress daily"
64
+ \u2022 inherit - Continue current conversation. Example: "Remind me about this in 2 hours"
65
+ \u2022 fixed - Specific session. Example: "Post update to session abc-123"`
66
+ ),
67
+ sessionId: import_zod.z.string().optional().describe(
68
+ 'Target session ID. Required for "fixed" mode. For "inherit", this is auto-captured.'
69
+ ),
70
+ targetAgentId: import_zod.z.string().optional().describe(
71
+ 'Target agent ID to execute this schedule (e.g., "notes", "filesystem", "coding"). If not specified, executes in the creator agent context. Use this to delegate scheduled tasks to specialized agents.'
72
+ )
73
+ }).strict().superRefine((data, ctx) => {
74
+ if (data.sessionMode === "fixed" && !data.sessionId) {
75
+ ctx.addIssue({
76
+ code: import_zod.z.ZodIssueCode.custom,
77
+ message: 'sessionId is required when sessionMode is "fixed"',
78
+ path: ["sessionId"]
79
+ });
80
+ }
81
+ });
82
+ const UpdateScheduleFieldsSchema = import_zod.z.object({
83
+ name: import_zod.z.string().min(1).max(100).optional().describe("Updated name"),
84
+ cronExpression: import_zod.z.string().optional().describe("Updated cron expression"),
85
+ instruction: import_zod.z.string().min(1).optional().describe("Updated instruction - what should happen when this schedule triggers"),
86
+ timezone: import_zod.z.string().optional().describe("Updated timezone"),
87
+ enabled: import_zod.z.boolean().optional().describe("Updated enabled state"),
88
+ metadata: import_zod.z.record(import_zod.z.unknown()).optional().describe("Updated metadata"),
89
+ workspacePath: import_zod.z.string().optional().nullable().describe("Updated workspace path for scheduled runs"),
90
+ sessionMode: ScheduleSessionModeSchema.optional().describe(
91
+ "Updated session mode (ephemeral, dedicated, inherit, fixed)"
92
+ ),
93
+ sessionId: import_zod.z.string().optional().describe('Updated session ID (required if changing to "fixed" mode)'),
94
+ targetAgentId: import_zod.z.string().optional().describe(
95
+ "Updated target agent ID. Set to reassign schedule execution to a different agent."
96
+ )
97
+ }).strict();
98
+ const UpdateScheduleInputSchema = UpdateScheduleFieldsSchema.extend({
99
+ scheduleId: import_zod.z.string().describe("The schedule ID to update")
100
+ }).superRefine((data, ctx) => {
101
+ if (data.sessionMode === "fixed" && !data.sessionId) {
102
+ ctx.addIssue({
103
+ code: import_zod.z.ZodIssueCode.custom,
104
+ message: 'sessionId is required when sessionMode is "fixed"',
105
+ path: ["sessionId"]
106
+ });
107
+ }
108
+ });
109
+ const UpdateScheduleFieldsOnlySchema = UpdateScheduleFieldsSchema;
110
+ const GetScheduleInputSchema = import_zod.z.object({
111
+ scheduleId: import_zod.z.string().describe("The schedule ID")
112
+ }).strict();
113
+ const DeleteScheduleInputSchema = import_zod.z.object({
114
+ scheduleId: import_zod.z.string().describe("The schedule ID to delete")
115
+ }).strict();
116
+ const TriggerScheduleInputSchema = import_zod.z.object({
117
+ scheduleId: import_zod.z.string().describe("The schedule ID to trigger")
118
+ }).strict();
119
+ const GetScheduleHistoryInputSchema = import_zod.z.object({
120
+ scheduleId: import_zod.z.string().describe("The schedule ID"),
121
+ limit: import_zod.z.number().optional().describe("Maximum number of history entries to return (default: 10)")
122
+ }).strict();
123
+ const ListSchedulesInputSchema = import_zod.z.object({
124
+ enabled: import_zod.z.boolean().optional().describe("Filter by enabled status (true/false)")
125
+ }).strict();
126
+ // Annotate the CommonJS export names for ESM import in node:
127
+ 0 && (module.exports = {
128
+ CreateScheduleInputSchema,
129
+ DeleteScheduleInputSchema,
130
+ GetScheduleHistoryInputSchema,
131
+ GetScheduleInputSchema,
132
+ ListSchedulesInputSchema,
133
+ ScheduleSessionModeSchema,
134
+ SchedulerToolsConfigSchema,
135
+ TriggerScheduleInputSchema,
136
+ UpdateScheduleFieldsOnlySchema,
137
+ UpdateScheduleInputSchema
138
+ });