@dexto/server 1.5.8 → 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 (58) hide show
  1. package/dist/events/a2a-sse-subscriber.d.ts +1 -1
  2. package/dist/hono/__tests__/test-fixtures.cjs +27 -6
  3. package/dist/hono/__tests__/test-fixtures.d.ts +2 -1
  4. package/dist/hono/__tests__/test-fixtures.d.ts.map +1 -1
  5. package/dist/hono/__tests__/test-fixtures.js +31 -6
  6. package/dist/hono/index.cjs +17 -2
  7. package/dist/hono/index.d.ts +875 -59
  8. package/dist/hono/index.d.ts.map +1 -1
  9. package/dist/hono/index.js +17 -2
  10. package/dist/hono/routes/a2a-tasks.d.ts +6 -6
  11. package/dist/hono/routes/agents.cjs +38 -27
  12. package/dist/hono/routes/agents.d.ts +2 -1
  13. package/dist/hono/routes/agents.d.ts.map +1 -1
  14. package/dist/hono/routes/agents.js +37 -31
  15. package/dist/hono/routes/discovery.cjs +99 -22
  16. package/dist/hono/routes/discovery.d.ts +14 -12
  17. package/dist/hono/routes/discovery.d.ts.map +1 -1
  18. package/dist/hono/routes/discovery.js +89 -22
  19. package/dist/hono/routes/llm.d.ts +1 -1
  20. package/dist/hono/routes/mcp.cjs +96 -14
  21. package/dist/hono/routes/mcp.d.ts +138 -3
  22. package/dist/hono/routes/mcp.d.ts.map +1 -1
  23. package/dist/hono/routes/mcp.js +97 -15
  24. package/dist/hono/routes/memory.d.ts +4 -4
  25. package/dist/hono/routes/models.d.ts +1 -1
  26. package/dist/hono/routes/resources.d.ts +1 -1
  27. package/dist/hono/routes/schedules.cjs +455 -0
  28. package/dist/hono/routes/schedules.d.ts +472 -0
  29. package/dist/hono/routes/schedules.d.ts.map +1 -0
  30. package/dist/hono/routes/schedules.js +439 -0
  31. package/dist/hono/routes/search.d.ts +1 -1
  32. package/dist/hono/routes/sessions.cjs +10 -4
  33. package/dist/hono/routes/sessions.d.ts +135 -5
  34. package/dist/hono/routes/sessions.d.ts.map +1 -1
  35. package/dist/hono/routes/sessions.js +10 -4
  36. package/dist/hono/routes/tools.cjs +12 -19
  37. package/dist/hono/routes/tools.d.ts +5 -3
  38. package/dist/hono/routes/tools.d.ts.map +1 -1
  39. package/dist/hono/routes/tools.js +12 -19
  40. package/dist/hono/routes/workspaces.cjs +136 -0
  41. package/dist/hono/routes/workspaces.d.ts +77 -0
  42. package/dist/hono/routes/workspaces.d.ts.map +1 -0
  43. package/dist/hono/routes/workspaces.js +112 -0
  44. package/dist/hono/schemas/responses.cjs +82 -7
  45. package/dist/hono/schemas/responses.d.ts +366 -16
  46. package/dist/hono/schemas/responses.d.ts.map +1 -1
  47. package/dist/hono/schemas/responses.js +75 -6
  48. package/dist/hono/start-server.cjs +3 -3
  49. package/dist/hono/start-server.d.ts +15 -6
  50. package/dist/hono/start-server.d.ts.map +1 -1
  51. package/dist/hono/start-server.js +3 -3
  52. package/dist/index.cjs +9 -0
  53. package/dist/index.d.ts +1 -0
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +4 -0
  56. package/dist/mcp/mcp-handler.d.ts +2 -2
  57. package/dist/mcp/mcp-handler.d.ts.map +1 -1
  58. package/package.json +8 -5
@@ -1,12 +1,16 @@
1
1
  import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
2
- import { logger, McpServerConfigSchema, MCP_CONNECTION_STATUSES } from "@dexto/core";
2
+ import { AgentError, logger, McpServerConfigSchema, MCP_CONNECTION_STATUSES } from "@dexto/core";
3
3
  import { updateAgentConfigFile } from "@dexto/agent-management";
4
4
  import { ResourceSchema } from "../schemas/responses.js";
5
5
  const McpServerRequestSchema = z.object({
6
6
  name: z.string().min(1, "Server name is required").describe("A unique name for the server"),
7
7
  config: McpServerConfigSchema.describe("The server configuration object"),
8
8
  persistToAgent: z.boolean().optional().describe("If true, saves the server to agent configuration file")
9
- }).describe("Request body for adding or updating an MCP server");
9
+ }).strict().describe("Request body for adding or updating an MCP server");
10
+ const McpServerUpdateSchema = z.object({
11
+ config: McpServerConfigSchema.describe("The updated server configuration object"),
12
+ persistToAgent: z.boolean().optional().describe("If true, saves the server to agent configuration file")
13
+ }).strict().describe("Request body for updating an MCP server");
10
14
  const ExecuteToolBodySchema = z.record(z.unknown()).describe(
11
15
  "Tool execution parameters as JSON object. The specific fields depend on the tool being executed and are defined by the tool's inputSchema."
12
16
  );
@@ -37,7 +41,8 @@ const ToolInfoSchema = z.object({
37
41
  id: z.string().describe("Tool identifier"),
38
42
  name: z.string().describe("Tool name"),
39
43
  description: z.string().describe("Tool description"),
40
- inputSchema: ToolInputSchema.optional().describe("JSON Schema for tool input parameters")
44
+ inputSchema: ToolInputSchema.optional().describe("JSON Schema for tool input parameters"),
45
+ _meta: z.record(z.unknown()).optional().describe("Optional tool metadata (e.g., MCP Apps UI resource info)")
41
46
  }).strict().describe("Tool information");
42
47
  const ToolsListResponseSchema = z.object({
43
48
  tools: z.array(ToolInfoSchema).describe("Array of available tools")
@@ -55,6 +60,10 @@ const ToolExecutionResponseSchema = z.object({
55
60
  data: z.any().optional().describe("Tool execution result data"),
56
61
  error: z.string().optional().describe("Error message if execution failed")
57
62
  }).strict().describe("Tool execution response");
63
+ const ServerConfigResponseSchema = z.object({
64
+ name: z.string().describe("Server name"),
65
+ config: McpServerConfigSchema.describe("Server configuration")
66
+ }).strict().describe("MCP server configuration response");
58
67
  const ResourcesListResponseSchema = z.object({
59
68
  success: z.boolean().describe("Success indicator"),
60
69
  resources: z.array(ResourceSchema).describe("Array of available resources")
@@ -66,7 +75,7 @@ const ResourceContentResponseSchema = z.object({
66
75
  success: z.boolean().describe("Success indicator"),
67
76
  data: ResourceContentSchema.describe("Resource content")
68
77
  }).strict().describe("Resource content response");
69
- function createMcpRouter(getAgent) {
78
+ function createMcpRouter(getAgent, getAgentConfigPath) {
70
79
  const app = new OpenAPIHono();
71
80
  const addServerRoute = createRoute({
72
81
  method: "post",
@@ -95,6 +104,41 @@ function createMcpRouter(getAgent) {
95
104
  }
96
105
  }
97
106
  });
107
+ const getServerConfigRoute = createRoute({
108
+ method: "get",
109
+ path: "/mcp/servers/{serverId}/config",
110
+ summary: "Get MCP Server Config",
111
+ description: "Retrieves the configuration for a specific MCP server",
112
+ tags: ["mcp"],
113
+ request: {
114
+ params: z.object({ serverId: z.string().describe("The ID of the MCP server") })
115
+ },
116
+ responses: {
117
+ 200: {
118
+ description: "Server configuration",
119
+ content: { "application/json": { schema: ServerConfigResponseSchema } }
120
+ },
121
+ 404: { description: "Not found" }
122
+ }
123
+ });
124
+ const updateServerRoute = createRoute({
125
+ method: "put",
126
+ path: "/mcp/servers/{serverId}",
127
+ summary: "Update MCP Server",
128
+ description: "Updates configuration for an existing MCP server",
129
+ tags: ["mcp"],
130
+ request: {
131
+ params: z.object({ serverId: z.string().describe("The ID of the MCP server") }),
132
+ body: { content: { "application/json": { schema: McpServerUpdateSchema } } }
133
+ },
134
+ responses: {
135
+ 200: {
136
+ description: "Server updated",
137
+ content: { "application/json": { schema: ServerStatusResponseSchema } }
138
+ },
139
+ 404: { description: "Not found" }
140
+ }
141
+ });
98
142
  const toolsRoute = createRoute({
99
143
  method: "get",
100
144
  path: "/mcp/servers/{serverId}/tools",
@@ -214,6 +258,10 @@ function createMcpRouter(getAgent) {
214
258
  );
215
259
  if (persistToAgent === true) {
216
260
  try {
261
+ const agentPath = await getAgentConfigPath(ctx);
262
+ if (!agentPath) {
263
+ throw AgentError.noConfigPath();
264
+ }
217
265
  const currentConfig = agent.getEffectiveConfig();
218
266
  const updates = {
219
267
  mcpServers: {
@@ -221,16 +269,7 @@ function createMcpRouter(getAgent) {
221
269
  [name]: config
222
270
  }
223
271
  };
224
- const newConfig = await updateAgentConfigFile(
225
- agent.getAgentFilePath(),
226
- updates
227
- );
228
- const reloadResult = await agent.reload(newConfig);
229
- if (reloadResult.restarted) {
230
- logger.info(
231
- `Agent restarted to apply changes: ${reloadResult.changesApplied.join(", ")}`
232
- );
233
- }
272
+ await updateAgentConfigFile(agentPath, updates);
234
273
  logger.info(`Saved server '${name}' to agent configuration file`);
235
274
  } catch (saveError) {
236
275
  const errorMessage = saveError instanceof Error ? saveError.message : String(saveError);
@@ -256,6 +295,48 @@ function createMcpRouter(getAgent) {
256
295
  servers.push({ id: name, name, status: "error" });
257
296
  }
258
297
  return ctx.json({ servers });
298
+ }).openapi(getServerConfigRoute, async (ctx) => {
299
+ const agent = await getAgent(ctx);
300
+ const { serverId } = ctx.req.valid("param");
301
+ const config = agent.getMcpServerConfig(serverId);
302
+ if (!config) {
303
+ return ctx.json({ error: `Server '${serverId}' not found.` }, 404);
304
+ }
305
+ return ctx.json({ name: serverId, config }, 200);
306
+ }).openapi(updateServerRoute, async (ctx) => {
307
+ const agent = await getAgent(ctx);
308
+ const { serverId } = ctx.req.valid("param");
309
+ const { config, persistToAgent } = ctx.req.valid("json");
310
+ const existingConfig = agent.getMcpServerConfig(serverId);
311
+ if (!existingConfig) {
312
+ return ctx.json({ error: `Server '${serverId}' not found.` }, 404);
313
+ }
314
+ await agent.updateMcpServer(serverId, config);
315
+ if (persistToAgent === true) {
316
+ try {
317
+ const agentPath = await getAgentConfigPath(ctx);
318
+ if (!agentPath) {
319
+ throw AgentError.noConfigPath();
320
+ }
321
+ const currentConfig = agent.getEffectiveConfig();
322
+ const updates = {
323
+ mcpServers: {
324
+ ...currentConfig.mcpServers || {},
325
+ [serverId]: config
326
+ }
327
+ };
328
+ await updateAgentConfigFile(agentPath, updates);
329
+ logger.info(`Saved server '${serverId}' to agent configuration file`);
330
+ } catch (saveError) {
331
+ const errorMessage = saveError instanceof Error ? saveError.message : String(saveError);
332
+ logger.warn(
333
+ `Failed to persist MCP server '${serverId}' update: ${errorMessage}`,
334
+ { error: saveError }
335
+ );
336
+ }
337
+ }
338
+ const status = config.enabled === false ? "registered" : "connected";
339
+ return ctx.json({ status, name: serverId }, 200);
259
340
  }).openapi(toolsRoute, async (ctx) => {
260
341
  const agent = await getAgent(ctx);
261
342
  const { serverId } = ctx.req.valid("param");
@@ -268,7 +349,8 @@ function createMcpRouter(getAgent) {
268
349
  id: toolName,
269
350
  name: toolName,
270
351
  description: toolDef.description || "",
271
- inputSchema: toolDef.parameters
352
+ inputSchema: toolDef.parameters,
353
+ _meta: toolDef._meta
272
354
  }));
273
355
  return ctx.json({ tools });
274
356
  }).openapi(deleteServerRoute, async (ctx) => {
@@ -19,8 +19,8 @@ export declare function createMemoryRouter(getAgent: GetAgentFn): OpenAPIHono<im
19
19
  ok: true;
20
20
  memory: {
21
21
  content: string;
22
- createdAt: number;
23
22
  id: string;
23
+ createdAt: number;
24
24
  updatedAt: number;
25
25
  metadata?: {
26
26
  [x: string]: import("hono/utils/types").JSONValue;
@@ -49,8 +49,8 @@ export declare function createMemoryRouter(getAgent: GetAgentFn): OpenAPIHono<im
49
49
  output: {
50
50
  memories: {
51
51
  content: string;
52
- createdAt: number;
53
52
  id: string;
53
+ createdAt: number;
54
54
  updatedAt: number;
55
55
  metadata?: {
56
56
  [x: string]: import("hono/utils/types").JSONValue;
@@ -77,8 +77,8 @@ export declare function createMemoryRouter(getAgent: GetAgentFn): OpenAPIHono<im
77
77
  ok: true;
78
78
  memory: {
79
79
  content: string;
80
- createdAt: number;
81
80
  id: string;
81
+ createdAt: number;
82
82
  updatedAt: number;
83
83
  metadata?: {
84
84
  [x: string]: import("hono/utils/types").JSONValue;
@@ -113,8 +113,8 @@ export declare function createMemoryRouter(getAgent: GetAgentFn): OpenAPIHono<im
113
113
  ok: true;
114
114
  memory: {
115
115
  content: string;
116
- createdAt: number;
117
116
  id: string;
117
+ createdAt: number;
118
118
  updatedAt: number;
119
119
  metadata?: {
120
120
  [x: string]: import("hono/utils/types").JSONValue;
@@ -15,7 +15,7 @@ export declare function createModelsRouter(): OpenAPIHono<import("hono").Env, {
15
15
  displayName: string;
16
16
  filePath: string;
17
17
  sizeBytes: number;
18
- source?: "manual" | "huggingface" | undefined;
18
+ source?: "huggingface" | "manual" | undefined;
19
19
  contextLength?: number | undefined;
20
20
  }[];
21
21
  };
@@ -5,7 +5,6 @@ export declare function createResourcesRouter(getAgent: GetAgentFn): OpenAPIHono
5
5
  $get: {
6
6
  input: {};
7
7
  output: {
8
- ok: true;
9
8
  resources: {
10
9
  uri: string;
11
10
  source: "mcp" | "internal";
@@ -19,6 +18,7 @@ export declare function createResourcesRouter(getAgent: GetAgentFn): OpenAPIHono
19
18
  size?: number | undefined;
20
19
  lastModified?: string | undefined;
21
20
  }[];
21
+ ok: true;
22
22
  };
23
23
  outputFormat: "json";
24
24
  status: 200;
@@ -0,0 +1,455 @@
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 schedules_exports = {};
20
+ __export(schedules_exports, {
21
+ createSchedulesRouter: () => createSchedulesRouter
22
+ });
23
+ module.exports = __toCommonJS(schedules_exports);
24
+ var import_zod_openapi = require("@hono/zod-openapi");
25
+ var import_responses = require("../schemas/responses.js");
26
+ var import_tools_scheduler = require("@dexto/tools-scheduler");
27
+ var import_core = require("@dexto/core");
28
+ const CreateScheduleSchema = import_zod_openapi.z.object({
29
+ name: import_zod_openapi.z.string().min(1).describe("Schedule name"),
30
+ instruction: import_zod_openapi.z.string().min(1).describe("Instruction to run on schedule"),
31
+ cronExpression: import_zod_openapi.z.string().min(1).describe("Cron expression"),
32
+ timezone: import_zod_openapi.z.string().optional().describe("Timezone for schedule"),
33
+ enabled: import_zod_openapi.z.boolean().optional().describe("Whether the schedule is enabled"),
34
+ workspacePath: import_zod_openapi.z.string().optional().nullable().describe("Optional workspace path for scheduled runs")
35
+ }).strict().describe("Request body for creating a schedule");
36
+ const UpdateScheduleSchema = CreateScheduleSchema.partial().strict().describe("Request body for updating a schedule");
37
+ const isScheduleNotFoundError = (error) => error instanceof import_core.DextoRuntimeError && error.type === import_core.ErrorType.NOT_FOUND && error.code === import_tools_scheduler.SchedulerErrorCode.SCHEDULE_NOT_FOUND;
38
+ const logSchedulerError = (agent, message, error) => {
39
+ if (!agent?.logger) {
40
+ return;
41
+ }
42
+ agent.logger.error(message, {
43
+ error: error instanceof Error ? error.message : String(error ?? "Unknown error"),
44
+ stack: error instanceof Error ? error.stack : void 0,
45
+ code: error instanceof import_core.DextoRuntimeError ? error.code : void 0
46
+ });
47
+ };
48
+ const toErrorResponse = (message, code) => ({
49
+ ok: false,
50
+ error: {
51
+ message,
52
+ ...code ? { code } : {}
53
+ }
54
+ });
55
+ function createSchedulesRouter(getAgent) {
56
+ const app = new import_zod_openapi.OpenAPIHono();
57
+ const resolveScheduler = async (ctx) => {
58
+ const agent = await getAgent(ctx);
59
+ const agentId = agent.config?.agentId ?? "default";
60
+ let scheduler = (0, import_tools_scheduler.getSchedulerManager)(agentId) ?? null;
61
+ if (!scheduler) {
62
+ scheduler = await (0, import_tools_scheduler.ensureSchedulerManagerForAgent)(agent);
63
+ }
64
+ return { scheduler, agent };
65
+ };
66
+ const listRoute = (0, import_zod_openapi.createRoute)({
67
+ method: "get",
68
+ path: "/schedules",
69
+ summary: "List Schedules",
70
+ description: "Retrieves all automation schedules",
71
+ tags: ["schedules"],
72
+ responses: {
73
+ 200: {
74
+ description: "List of schedules",
75
+ content: {
76
+ "application/json": {
77
+ schema: import_zod_openapi.z.object({
78
+ schedules: import_zod_openapi.z.array(import_responses.ScheduleSchema).describe("Schedule list")
79
+ }).strict()
80
+ }
81
+ }
82
+ },
83
+ 500: {
84
+ description: "Failed to list schedules",
85
+ content: {
86
+ "application/json": {
87
+ schema: import_responses.ErrorResponseSchema
88
+ }
89
+ }
90
+ },
91
+ 503: {
92
+ description: "Scheduler tools are not enabled",
93
+ content: {
94
+ "application/json": {
95
+ schema: import_responses.ErrorResponseSchema
96
+ }
97
+ }
98
+ }
99
+ }
100
+ });
101
+ const createRouteDef = (0, import_zod_openapi.createRoute)({
102
+ method: "post",
103
+ path: "/schedules",
104
+ summary: "Create Schedule",
105
+ description: "Creates a new automation schedule",
106
+ tags: ["schedules"],
107
+ request: { body: { content: { "application/json": { schema: CreateScheduleSchema } } } },
108
+ responses: {
109
+ 201: {
110
+ description: "Created schedule",
111
+ content: {
112
+ "application/json": {
113
+ schema: import_zod_openapi.z.object({ schedule: import_responses.ScheduleSchema }).strict()
114
+ }
115
+ }
116
+ },
117
+ 400: {
118
+ description: "Validation error",
119
+ content: {
120
+ "application/json": {
121
+ schema: import_responses.ErrorResponseSchema
122
+ }
123
+ }
124
+ },
125
+ 429: {
126
+ description: "Schedule limit reached",
127
+ content: {
128
+ "application/json": {
129
+ schema: import_responses.ErrorResponseSchema
130
+ }
131
+ }
132
+ },
133
+ 500: {
134
+ description: "Failed to create schedule",
135
+ content: {
136
+ "application/json": {
137
+ schema: import_responses.ErrorResponseSchema
138
+ }
139
+ }
140
+ },
141
+ 503: {
142
+ description: "Scheduler tools are not enabled",
143
+ content: {
144
+ "application/json": {
145
+ schema: import_responses.ErrorResponseSchema
146
+ }
147
+ }
148
+ }
149
+ }
150
+ });
151
+ const updateRoute = (0, import_zod_openapi.createRoute)({
152
+ method: "patch",
153
+ path: "/schedules/{scheduleId}",
154
+ summary: "Update Schedule",
155
+ description: "Updates an existing schedule",
156
+ tags: ["schedules"],
157
+ request: {
158
+ params: import_zod_openapi.z.object({
159
+ scheduleId: import_zod_openapi.z.string().min(1).describe("Schedule ID")
160
+ }).strict().describe("Schedule identifier params"),
161
+ body: { content: { "application/json": { schema: UpdateScheduleSchema } } }
162
+ },
163
+ responses: {
164
+ 200: {
165
+ description: "Updated schedule",
166
+ content: {
167
+ "application/json": {
168
+ schema: import_zod_openapi.z.object({ schedule: import_responses.ScheduleSchema }).strict()
169
+ }
170
+ }
171
+ },
172
+ 400: {
173
+ description: "Validation error",
174
+ content: {
175
+ "application/json": {
176
+ schema: import_responses.ErrorResponseSchema
177
+ }
178
+ }
179
+ },
180
+ 404: {
181
+ description: "Schedule not found",
182
+ content: {
183
+ "application/json": {
184
+ schema: import_responses.ErrorResponseSchema
185
+ }
186
+ }
187
+ },
188
+ 500: {
189
+ description: "Failed to update schedule",
190
+ content: {
191
+ "application/json": {
192
+ schema: import_responses.ErrorResponseSchema
193
+ }
194
+ }
195
+ },
196
+ 503: {
197
+ description: "Scheduler tools are not enabled",
198
+ content: {
199
+ "application/json": {
200
+ schema: import_responses.ErrorResponseSchema
201
+ }
202
+ }
203
+ }
204
+ }
205
+ });
206
+ const deleteRoute = (0, import_zod_openapi.createRoute)({
207
+ method: "delete",
208
+ path: "/schedules/{scheduleId}",
209
+ summary: "Delete Schedule",
210
+ description: "Deletes an automation schedule",
211
+ tags: ["schedules"],
212
+ request: {
213
+ params: import_zod_openapi.z.object({
214
+ scheduleId: import_zod_openapi.z.string().min(1).describe("Schedule ID")
215
+ }).strict().describe("Schedule identifier params")
216
+ },
217
+ responses: {
218
+ 200: {
219
+ description: "Schedule deleted",
220
+ content: {
221
+ "application/json": {
222
+ schema: import_zod_openapi.z.object({
223
+ deleted: import_zod_openapi.z.boolean().describe("Whether the schedule was deleted")
224
+ }).strict().describe("Delete schedule response")
225
+ }
226
+ }
227
+ },
228
+ 404: {
229
+ description: "Schedule not found",
230
+ content: {
231
+ "application/json": {
232
+ schema: import_responses.ErrorResponseSchema
233
+ }
234
+ }
235
+ },
236
+ 500: {
237
+ description: "Failed to delete schedule",
238
+ content: {
239
+ "application/json": {
240
+ schema: import_responses.ErrorResponseSchema
241
+ }
242
+ }
243
+ },
244
+ 503: {
245
+ description: "Scheduler tools are not enabled",
246
+ content: {
247
+ "application/json": {
248
+ schema: import_responses.ErrorResponseSchema
249
+ }
250
+ }
251
+ }
252
+ }
253
+ });
254
+ const triggerRoute = (0, import_zod_openapi.createRoute)({
255
+ method: "post",
256
+ path: "/schedules/{scheduleId}/trigger",
257
+ summary: "Trigger Schedule",
258
+ description: "Runs a schedule immediately and waits for execution to complete (bounded by executionTimeout, default 5 minutes). Clients should set timeouts accordingly.",
259
+ tags: ["schedules"],
260
+ request: {
261
+ params: import_zod_openapi.z.object({
262
+ scheduleId: import_zod_openapi.z.string().min(1).describe("Schedule ID")
263
+ }).strict().describe("Schedule identifier params")
264
+ },
265
+ responses: {
266
+ 200: {
267
+ description: "Schedule triggered",
268
+ content: {
269
+ "application/json": {
270
+ schema: import_zod_openapi.z.object({
271
+ scheduled: import_zod_openapi.z.boolean().describe(
272
+ "Whether the schedule was queued. Execution is omitted when false."
273
+ ),
274
+ execution: import_responses.ExecutionLogSchema.optional().describe(
275
+ "Execution log (present when scheduled is true)"
276
+ )
277
+ }).strict().describe("Trigger schedule response")
278
+ }
279
+ }
280
+ },
281
+ 404: {
282
+ description: "Schedule not found",
283
+ content: {
284
+ "application/json": {
285
+ schema: import_responses.ErrorResponseSchema
286
+ }
287
+ }
288
+ },
289
+ 500: {
290
+ description: "Failed to trigger schedule",
291
+ content: {
292
+ "application/json": {
293
+ schema: import_responses.ErrorResponseSchema
294
+ }
295
+ }
296
+ },
297
+ 503: {
298
+ description: "Scheduler tools are not enabled",
299
+ content: {
300
+ "application/json": {
301
+ schema: import_responses.ErrorResponseSchema
302
+ }
303
+ }
304
+ }
305
+ }
306
+ });
307
+ return app.openapi(listRoute, async (ctx) => {
308
+ const { scheduler, agent } = await resolveScheduler(ctx);
309
+ if (!scheduler) {
310
+ return ctx.json(
311
+ toErrorResponse("Scheduler tools are not enabled for this agent."),
312
+ 503
313
+ );
314
+ }
315
+ try {
316
+ const schedules = await scheduler.listSchedules();
317
+ return ctx.json({ schedules }, 200);
318
+ } catch (error) {
319
+ const message = error instanceof Error ? error.message : String(error ?? "Unknown error");
320
+ logSchedulerError(agent, "Failed to list schedules", error);
321
+ if (error instanceof import_core.DextoRuntimeError) {
322
+ return ctx.json(toErrorResponse(message, String(error.code)), 500);
323
+ }
324
+ return ctx.json(toErrorResponse("Failed to list schedules"), 500);
325
+ }
326
+ }).openapi(createRouteDef, async (ctx) => {
327
+ const { scheduler, agent } = await resolveScheduler(ctx);
328
+ if (!scheduler) {
329
+ return ctx.json(
330
+ toErrorResponse("Scheduler tools are not enabled for this agent."),
331
+ 503
332
+ );
333
+ }
334
+ const input = ctx.req.valid("json");
335
+ const createPayload = {
336
+ name: input.name,
337
+ instruction: input.instruction,
338
+ cronExpression: input.cronExpression,
339
+ ...input.timezone !== void 0 ? { timezone: input.timezone } : {},
340
+ enabled: input.enabled ?? true,
341
+ ...input.workspacePath !== void 0 ? { workspacePath: input.workspacePath } : {},
342
+ sessionMode: "dedicated"
343
+ };
344
+ try {
345
+ const schedule = await scheduler.createSchedule(createPayload);
346
+ return ctx.json({ schedule }, 201);
347
+ } catch (error) {
348
+ if (error instanceof import_core.DextoRuntimeError && error.code === import_tools_scheduler.SchedulerErrorCode.SCHEDULE_INVALID_CRON) {
349
+ return ctx.json(toErrorResponse(error.message, String(error.code)), 400);
350
+ }
351
+ if (error instanceof import_core.DextoRuntimeError && error.code === import_tools_scheduler.SchedulerErrorCode.SCHEDULE_INVALID_INPUT) {
352
+ return ctx.json(toErrorResponse(error.message, String(error.code)), 400);
353
+ }
354
+ if (error instanceof import_core.DextoRuntimeError && error.code === import_tools_scheduler.SchedulerErrorCode.SCHEDULE_LIMIT_REACHED) {
355
+ return ctx.json(toErrorResponse(error.message, String(error.code)), 429);
356
+ }
357
+ logSchedulerError(agent, "Failed to create schedule", error);
358
+ return ctx.json(toErrorResponse("Failed to create schedule"), 500);
359
+ }
360
+ }).openapi(updateRoute, async (ctx) => {
361
+ const { scheduler, agent } = await resolveScheduler(ctx);
362
+ if (!scheduler) {
363
+ return ctx.json(
364
+ toErrorResponse("Scheduler tools are not enabled for this agent."),
365
+ 503
366
+ );
367
+ }
368
+ const { scheduleId } = ctx.req.valid("param");
369
+ const input = ctx.req.valid("json");
370
+ const updatePayload = {
371
+ ...input.name !== void 0 ? { name: input.name } : {},
372
+ ...input.instruction !== void 0 ? { instruction: input.instruction } : {},
373
+ ...input.cronExpression !== void 0 ? { cronExpression: input.cronExpression } : {},
374
+ ...input.timezone !== void 0 ? { timezone: input.timezone } : {},
375
+ ...input.enabled !== void 0 ? { enabled: input.enabled } : {},
376
+ ...input.workspacePath !== void 0 ? { workspacePath: input.workspacePath } : {}
377
+ };
378
+ try {
379
+ const schedule = await scheduler.updateSchedule(scheduleId, updatePayload);
380
+ return ctx.json({ schedule }, 200);
381
+ } catch (error) {
382
+ if (isScheduleNotFoundError(error)) {
383
+ return ctx.json(
384
+ toErrorResponse(
385
+ "Schedule not found",
386
+ import_tools_scheduler.SchedulerErrorCode.SCHEDULE_NOT_FOUND
387
+ ),
388
+ 404
389
+ );
390
+ }
391
+ if (error instanceof import_core.DextoRuntimeError && error.code === import_tools_scheduler.SchedulerErrorCode.SCHEDULE_INVALID_CRON) {
392
+ return ctx.json(toErrorResponse(error.message, String(error.code)), 400);
393
+ }
394
+ if (error instanceof import_core.DextoRuntimeError && error.code === import_tools_scheduler.SchedulerErrorCode.SCHEDULE_INVALID_INPUT) {
395
+ return ctx.json(toErrorResponse(error.message, String(error.code)), 400);
396
+ }
397
+ logSchedulerError(agent, "Failed to update schedule", error);
398
+ return ctx.json(toErrorResponse("Failed to update schedule"), 500);
399
+ }
400
+ }).openapi(deleteRoute, async (ctx) => {
401
+ const { scheduler, agent } = await resolveScheduler(ctx);
402
+ if (!scheduler) {
403
+ return ctx.json(
404
+ toErrorResponse("Scheduler tools are not enabled for this agent."),
405
+ 503
406
+ );
407
+ }
408
+ const { scheduleId } = ctx.req.valid("param");
409
+ try {
410
+ await scheduler.deleteSchedule(scheduleId);
411
+ return ctx.json({ deleted: true }, 200);
412
+ } catch (error) {
413
+ if (isScheduleNotFoundError(error)) {
414
+ return ctx.json(
415
+ toErrorResponse(
416
+ "Schedule not found",
417
+ import_tools_scheduler.SchedulerErrorCode.SCHEDULE_NOT_FOUND
418
+ ),
419
+ 404
420
+ );
421
+ }
422
+ logSchedulerError(agent, "Failed to delete schedule", error);
423
+ return ctx.json(toErrorResponse("Failed to delete schedule"), 500);
424
+ }
425
+ }).openapi(triggerRoute, async (ctx) => {
426
+ const { scheduler, agent } = await resolveScheduler(ctx);
427
+ if (!scheduler) {
428
+ return ctx.json(
429
+ toErrorResponse("Scheduler tools are not enabled for this agent."),
430
+ 503
431
+ );
432
+ }
433
+ const { scheduleId } = ctx.req.valid("param");
434
+ try {
435
+ const execution = await scheduler.triggerScheduleNow(scheduleId);
436
+ return ctx.json({ scheduled: true, execution }, 200);
437
+ } catch (error) {
438
+ if (isScheduleNotFoundError(error)) {
439
+ return ctx.json(
440
+ toErrorResponse(
441
+ "Schedule not found",
442
+ import_tools_scheduler.SchedulerErrorCode.SCHEDULE_NOT_FOUND
443
+ ),
444
+ 404
445
+ );
446
+ }
447
+ logSchedulerError(agent, "Failed to trigger schedule", error);
448
+ return ctx.json(toErrorResponse("Failed to trigger schedule"), 500);
449
+ }
450
+ });
451
+ }
452
+ // Annotate the CommonJS export names for ESM import in node:
453
+ 0 && (module.exports = {
454
+ createSchedulesRouter
455
+ });