@dexto/server 1.3.0 → 1.5.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 (109) hide show
  1. package/dist/approval/manual-approval-handler.cjs +23 -15
  2. package/dist/approval/manual-approval-handler.d.ts.map +1 -1
  3. package/dist/approval/manual-approval-handler.js +23 -15
  4. package/dist/events/webhook-subscriber.cjs +1 -1
  5. package/dist/events/webhook-subscriber.d.ts.map +1 -1
  6. package/dist/events/webhook-subscriber.js +1 -1
  7. package/dist/hono/__tests__/test-fixtures.cjs +3 -3
  8. package/dist/hono/__tests__/test-fixtures.d.ts.map +1 -1
  9. package/dist/hono/__tests__/test-fixtures.js +3 -3
  10. package/dist/hono/index.cjs +46 -5
  11. package/dist/hono/index.d.ts +928 -584
  12. package/dist/hono/index.d.ts.map +1 -1
  13. package/dist/hono/index.js +46 -5
  14. package/dist/hono/middleware/error.d.ts.map +1 -1
  15. package/dist/hono/routes/a2a-jsonrpc.cjs +3 -3
  16. package/dist/hono/routes/a2a-jsonrpc.d.ts +4 -1
  17. package/dist/hono/routes/a2a-jsonrpc.d.ts.map +1 -1
  18. package/dist/hono/routes/a2a-jsonrpc.js +3 -3
  19. package/dist/hono/routes/a2a-tasks.cjs +5 -5
  20. package/dist/hono/routes/a2a-tasks.d.ts +13 -10
  21. package/dist/hono/routes/a2a-tasks.d.ts.map +1 -1
  22. package/dist/hono/routes/a2a-tasks.js +5 -5
  23. package/dist/hono/routes/agents.cjs +30 -42
  24. package/dist/hono/routes/agents.d.ts +7 -401
  25. package/dist/hono/routes/agents.d.ts.map +1 -1
  26. package/dist/hono/routes/agents.js +32 -42
  27. package/dist/hono/routes/approvals.cjs +53 -2
  28. package/dist/hono/routes/approvals.d.ts +29 -1
  29. package/dist/hono/routes/approvals.d.ts.map +1 -1
  30. package/dist/hono/routes/approvals.js +53 -2
  31. package/dist/hono/routes/discovery.cjs +67 -0
  32. package/dist/hono/routes/discovery.d.ts +44 -0
  33. package/dist/hono/routes/discovery.d.ts.map +1 -0
  34. package/dist/hono/routes/discovery.js +43 -0
  35. package/dist/hono/routes/greeting.cjs +2 -2
  36. package/dist/hono/routes/greeting.d.ts +2 -2
  37. package/dist/hono/routes/greeting.d.ts.map +1 -1
  38. package/dist/hono/routes/greeting.js +2 -2
  39. package/dist/hono/routes/health.d.ts +2 -2
  40. package/dist/hono/routes/health.d.ts.map +1 -1
  41. package/dist/hono/routes/key.cjs +110 -0
  42. package/dist/hono/routes/key.d.ts +48 -0
  43. package/dist/hono/routes/key.d.ts.map +1 -0
  44. package/dist/hono/routes/key.js +90 -0
  45. package/dist/hono/routes/llm.cjs +119 -62
  46. package/dist/hono/routes/llm.d.ts +242 -42
  47. package/dist/hono/routes/llm.d.ts.map +1 -1
  48. package/dist/hono/routes/llm.js +118 -58
  49. package/dist/hono/routes/mcp.cjs +16 -12
  50. package/dist/hono/routes/mcp.d.ts +6 -3
  51. package/dist/hono/routes/mcp.d.ts.map +1 -1
  52. package/dist/hono/routes/mcp.js +17 -13
  53. package/dist/hono/routes/memory.cjs +5 -5
  54. package/dist/hono/routes/memory.d.ts +5 -2
  55. package/dist/hono/routes/memory.d.ts.map +1 -1
  56. package/dist/hono/routes/memory.js +5 -5
  57. package/dist/hono/routes/messages.cjs +58 -66
  58. package/dist/hono/routes/messages.d.ts +99 -55
  59. package/dist/hono/routes/messages.d.ts.map +1 -1
  60. package/dist/hono/routes/messages.js +59 -67
  61. package/dist/hono/routes/models.cjs +319 -0
  62. package/dist/hono/routes/models.d.ts +107 -0
  63. package/dist/hono/routes/models.d.ts.map +1 -0
  64. package/dist/hono/routes/models.js +305 -0
  65. package/dist/hono/routes/openrouter.cjs +153 -0
  66. package/dist/hono/routes/openrouter.d.ts +54 -0
  67. package/dist/hono/routes/openrouter.d.ts.map +1 -0
  68. package/dist/hono/routes/openrouter.js +134 -0
  69. package/dist/hono/routes/prompts.cjs +5 -5
  70. package/dist/hono/routes/prompts.d.ts +10 -7
  71. package/dist/hono/routes/prompts.d.ts.map +1 -1
  72. package/dist/hono/routes/prompts.js +5 -5
  73. package/dist/hono/routes/queue.cjs +202 -0
  74. package/dist/hono/routes/queue.d.ts +174 -0
  75. package/dist/hono/routes/queue.d.ts.map +1 -0
  76. package/dist/hono/routes/queue.js +178 -0
  77. package/dist/hono/routes/resources.cjs +3 -3
  78. package/dist/hono/routes/resources.d.ts +3 -3
  79. package/dist/hono/routes/resources.d.ts.map +1 -1
  80. package/dist/hono/routes/resources.js +3 -3
  81. package/dist/hono/routes/search.cjs +2 -2
  82. package/dist/hono/routes/search.d.ts +39 -10
  83. package/dist/hono/routes/search.d.ts.map +1 -1
  84. package/dist/hono/routes/search.js +2 -2
  85. package/dist/hono/routes/sessions.cjs +74 -20
  86. package/dist/hono/routes/sessions.d.ts +25 -4
  87. package/dist/hono/routes/sessions.d.ts.map +1 -1
  88. package/dist/hono/routes/sessions.js +74 -20
  89. package/dist/hono/routes/tools.cjs +126 -0
  90. package/dist/hono/routes/tools.d.ts +42 -0
  91. package/dist/hono/routes/tools.d.ts.map +1 -0
  92. package/dist/hono/routes/tools.js +102 -0
  93. package/dist/hono/routes/webhooks.cjs +4 -4
  94. package/dist/hono/routes/webhooks.d.ts +4 -1
  95. package/dist/hono/routes/webhooks.d.ts.map +1 -1
  96. package/dist/hono/routes/webhooks.js +4 -4
  97. package/dist/hono/schemas/responses.cjs +24 -5
  98. package/dist/hono/schemas/responses.d.ts +838 -120
  99. package/dist/hono/schemas/responses.d.ts.map +1 -1
  100. package/dist/hono/schemas/responses.js +24 -10
  101. package/dist/hono/start-server.cjs +102 -0
  102. package/dist/hono/start-server.d.ts +61 -0
  103. package/dist/hono/start-server.d.ts.map +1 -0
  104. package/dist/hono/start-server.js +78 -0
  105. package/dist/index.cjs +2 -0
  106. package/dist/index.d.ts +1 -0
  107. package/dist/index.d.ts.map +1 -1
  108. package/dist/index.js +1 -0
  109. package/package.json +5 -4
@@ -1,15 +1,19 @@
1
1
  import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
2
+ import { DextoRuntimeError, ErrorScope, ErrorType } from "@dexto/core";
2
3
  import {
3
4
  LLM_REGISTRY,
4
5
  LLM_PROVIDERS,
5
- LLM_ROUTERS,
6
6
  SUPPORTED_FILE_TYPES,
7
- getSupportedRoutersForProvider,
8
7
  supportsBaseURL,
9
- isRouterSupportedForModel,
10
8
  LLMUpdatesSchema
11
9
  } from "@dexto/core";
12
- import { getProviderKeyStatus, saveProviderApiKey } from "@dexto/agent-management";
10
+ import {
11
+ getProviderKeyStatus,
12
+ loadCustomModels,
13
+ saveCustomModel,
14
+ deleteCustomModel,
15
+ CustomModelSchema
16
+ } from "@dexto/agent-management";
13
17
  import {
14
18
  ProviderCatalogSchema,
15
19
  ModelFlatSchema,
@@ -25,17 +29,12 @@ const CatalogQuerySchema = z.object({
25
29
  hasKey: z.union([z.literal("true"), z.literal("false"), z.literal("1"), z.literal("0")]).optional().transform(
26
30
  (raw) => raw === "true" || raw === "1" ? true : raw === "false" || raw === "0" ? false : void 0
27
31
  ).describe("Filter by API key presence (true or false)"),
28
- router: z.enum(LLM_ROUTERS).optional().describe("Filter by router type (vercel or in-built)"),
29
32
  fileType: z.enum(SUPPORTED_FILE_TYPES).optional().describe("Filter by supported file type (audio, pdf, or image)"),
30
33
  defaultOnly: z.union([z.literal("true"), z.literal("false"), z.literal("1"), z.literal("0")]).optional().transform(
31
34
  (raw) => raw === "true" || raw === "1" ? true : raw === "false" || raw === "0" ? false : void 0
32
35
  ).describe("Include only default models (true or false)"),
33
36
  mode: z.enum(["grouped", "flat"]).default("grouped").describe("Response format mode (grouped by provider or flat list)")
34
37
  }).describe("Query parameters for filtering and formatting the LLM catalog");
35
- const SaveKeySchema = z.object({
36
- provider: z.enum(LLM_PROVIDERS).describe("LLM provider identifier (e.g., openai, anthropic)"),
37
- apiKey: z.string().min(1, "API key is required").describe("API key for the provider (writeOnly - never returned in responses)").openapi({ writeOnly: true })
38
- }).describe("Request body for saving a provider API key");
39
38
  const SwitchLLMBodySchema = LLMUpdatesSchema.and(
40
39
  z.object({
41
40
  sessionId: z.string().optional().describe("Session identifier for session-specific LLM configuration")
@@ -57,8 +56,7 @@ function createLlmRouter(getAgent) {
57
56
  "application/json": {
58
57
  schema: z.object({
59
58
  config: LLMConfigResponseSchema.partial({
60
- maxIterations: true,
61
- router: true
59
+ maxIterations: true
62
60
  }).extend({
63
61
  displayName: z.string().optional().describe("Human-readable model display name")
64
62
  })
@@ -99,28 +97,6 @@ function createLlmRouter(getAgent) {
99
97
  }
100
98
  }
101
99
  });
102
- const saveKeyRoute = createRoute({
103
- method: "post",
104
- path: "/llm/key",
105
- summary: "Save Provider API Key",
106
- description: "Stores an API key for a provider in .env and makes it available immediately",
107
- tags: ["llm"],
108
- request: { body: { content: { "application/json": { schema: SaveKeySchema } } } },
109
- responses: {
110
- 200: {
111
- description: "API key saved",
112
- content: {
113
- "application/json": {
114
- schema: z.object({
115
- ok: z.literal(true).describe("Operation success indicator"),
116
- provider: z.enum(LLM_PROVIDERS).describe("Provider for which the key was saved"),
117
- envVar: z.string().describe("Environment variable name where key was stored")
118
- }).strict().describe("API key save response")
119
- }
120
- }
121
- }
122
- }
123
- });
124
100
  const switchRoute = createRoute({
125
101
  method: "post",
126
102
  path: "/llm/switch",
@@ -152,8 +128,86 @@ function createLlmRouter(getAgent) {
152
128
  }
153
129
  }
154
130
  });
155
- return app.openapi(currentRoute, (ctx) => {
156
- const agent = getAgent();
131
+ const listCustomModelsRoute = createRoute({
132
+ method: "get",
133
+ path: "/llm/custom-models",
134
+ summary: "List Custom Models",
135
+ description: "Returns all saved custom openai-compatible model configurations",
136
+ tags: ["llm"],
137
+ responses: {
138
+ 200: {
139
+ description: "List of custom models",
140
+ content: {
141
+ "application/json": {
142
+ schema: z.object({
143
+ models: z.array(CustomModelSchema).describe("List of custom models")
144
+ })
145
+ }
146
+ }
147
+ }
148
+ }
149
+ });
150
+ const createCustomModelRoute = createRoute({
151
+ method: "post",
152
+ path: "/llm/custom-models",
153
+ summary: "Create Custom Model",
154
+ description: "Saves a new custom openai-compatible model configuration",
155
+ tags: ["llm"],
156
+ request: {
157
+ body: { content: { "application/json": { schema: CustomModelSchema } } }
158
+ },
159
+ responses: {
160
+ 200: {
161
+ description: "Custom model saved",
162
+ content: {
163
+ "application/json": {
164
+ schema: z.object({
165
+ ok: z.literal(true).describe("Success indicator"),
166
+ model: CustomModelSchema
167
+ })
168
+ }
169
+ }
170
+ }
171
+ }
172
+ });
173
+ const deleteCustomModelRoute = createRoute({
174
+ method: "delete",
175
+ path: "/llm/custom-models/{name}",
176
+ summary: "Delete Custom Model",
177
+ description: "Deletes a custom model by name",
178
+ tags: ["llm"],
179
+ request: {
180
+ params: z.object({
181
+ name: z.string().min(1).describe("Model name to delete")
182
+ })
183
+ },
184
+ responses: {
185
+ 200: {
186
+ description: "Custom model deleted",
187
+ content: {
188
+ "application/json": {
189
+ schema: z.object({
190
+ ok: z.literal(true).describe("Success indicator"),
191
+ deleted: z.string().describe("Name of the deleted model")
192
+ })
193
+ }
194
+ }
195
+ },
196
+ 404: {
197
+ description: "Custom model not found",
198
+ content: {
199
+ "application/json": {
200
+ schema: z.object({
201
+ ok: z.literal(false).describe("Failure indicator"),
202
+ error: z.string().describe("Error message")
203
+ })
204
+ }
205
+ }
206
+ }
207
+ }
208
+ });
209
+ return app.openapi(currentRoute, async (ctx) => {
210
+ const agent = await getAgent(ctx);
157
211
  const { sessionId } = ctx.req.valid("query");
158
212
  const currentConfig = sessionId ? agent.getEffectiveConfig(sessionId).llm : agent.getCurrentLLMConfig();
159
213
  let displayName;
@@ -162,6 +216,13 @@ function createLlmRouter(getAgent) {
162
216
  (m) => m.name.toLowerCase() === String(currentConfig.model).toLowerCase()
163
217
  );
164
218
  displayName = model?.displayName || void 0;
219
+ if (!displayName) {
220
+ const customModels = await loadCustomModels();
221
+ const customModel = customModels.find(
222
+ (cm) => cm.name.toLowerCase() === String(currentConfig.model).toLowerCase()
223
+ );
224
+ displayName = customModel?.displayName || void 0;
225
+ }
165
226
  } catch {
166
227
  }
167
228
  const { apiKey, ...configWithoutKey } = currentConfig;
@@ -183,7 +244,6 @@ function createLlmRouter(getAgent) {
183
244
  name: displayName,
184
245
  hasApiKey: keyStatus.hasApiKey,
185
246
  primaryEnvVar: keyStatus.envVar,
186
- supportedRouters: getSupportedRoutersForProvider(provider),
187
247
  supportsBaseURL: supportsBaseURL(provider),
188
248
  models: info.models,
189
249
  supportedFileTypes: info.supportedFileTypes
@@ -213,23 +273,6 @@ function createLlmRouter(getAgent) {
213
273
  }
214
274
  filtered = byKey;
215
275
  }
216
- if (queryParams.router) {
217
- const byRouter = {};
218
- for (const [id, catalog] of Object.entries(filtered)) {
219
- if (!catalog.supportedRouters.includes(queryParams.router)) continue;
220
- const models = catalog.models.filter(
221
- (model) => isRouterSupportedForModel(
222
- id,
223
- model.name,
224
- queryParams.router
225
- )
226
- );
227
- if (models.length > 0) {
228
- byRouter[id] = { ...catalog, models };
229
- }
230
- }
231
- filtered = byRouter;
232
- }
233
276
  if (queryParams.fileType) {
234
277
  const byFileType = {};
235
278
  for (const [id, catalog] of Object.entries(filtered)) {
@@ -263,12 +306,8 @@ function createLlmRouter(getAgent) {
263
306
  return ctx.json({ models: flat });
264
307
  }
265
308
  return ctx.json({ providers: filtered });
266
- }).openapi(saveKeyRoute, async (ctx) => {
267
- const { provider, apiKey } = ctx.req.valid("json");
268
- const meta = await saveProviderApiKey(provider, apiKey, process.cwd());
269
- return ctx.json({ ok: true, provider, envVar: meta.envVar });
270
309
  }).openapi(switchRoute, async (ctx) => {
271
- const agent = getAgent();
310
+ const agent = await getAgent(ctx);
272
311
  const raw = ctx.req.valid("json");
273
312
  const { sessionId, ...llmUpdates } = raw;
274
313
  const config = await agent.switchLLM(llmUpdates, sessionId);
@@ -280,6 +319,27 @@ function createLlmRouter(getAgent) {
280
319
  },
281
320
  sessionId
282
321
  });
322
+ }).openapi(listCustomModelsRoute, async (ctx) => {
323
+ const models = await loadCustomModels();
324
+ return ctx.json({ models });
325
+ }).openapi(createCustomModelRoute, async (ctx) => {
326
+ const model = ctx.req.valid("json");
327
+ await saveCustomModel(model);
328
+ return ctx.json({ ok: true, model });
329
+ }).openapi(deleteCustomModelRoute, async (ctx) => {
330
+ const { name: encodedName } = ctx.req.valid("param");
331
+ const name = decodeURIComponent(encodedName);
332
+ const deleted = await deleteCustomModel(name);
333
+ if (!deleted) {
334
+ throw new DextoRuntimeError(
335
+ "custom_model_not_found",
336
+ ErrorScope.LLM,
337
+ ErrorType.NOT_FOUND,
338
+ `Custom model '${name}' not found`,
339
+ { modelName: name }
340
+ );
341
+ }
342
+ return ctx.json({ ok: true, deleted: name }, 200);
283
343
  });
284
344
  }
285
345
  export {
@@ -40,7 +40,7 @@ const ServerStatusResponseSchema = import_zod_openapi.z.object({
40
40
  const ServerInfoSchema = import_zod_openapi.z.object({
41
41
  id: import_zod_openapi.z.string().describe("Server identifier"),
42
42
  name: import_zod_openapi.z.string().describe("Server name"),
43
- status: import_zod_openapi.z.enum(["connected", "error", "disconnected"]).describe("Server status")
43
+ status: import_zod_openapi.z.enum(import_core.MCP_CONNECTION_STATUSES).describe("Server status")
44
44
  }).strict().describe("MCP server information");
45
45
  const ServersListResponseSchema = import_zod_openapi.z.object({
46
46
  servers: import_zod_openapi.z.array(ServerInfoSchema).describe("Array of server information")
@@ -228,10 +228,13 @@ function createMcpRouter(getAgent) {
228
228
  }
229
229
  });
230
230
  return app.openapi(addServerRoute, async (ctx) => {
231
- const agent = getAgent();
231
+ const agent = await getAgent(ctx);
232
232
  const { name, config, persistToAgent } = ctx.req.valid("json");
233
- await agent.connectMcpServer(name, config);
234
- import_core.logger.info(`Successfully connected to new server '${name}' via API request.`);
233
+ await agent.addMcpServer(name, config);
234
+ const isConnected = config.enabled !== false;
235
+ import_core.logger.info(
236
+ isConnected ? `Successfully connected to new server '${name}' via API request.` : `Registered server '${name}' (disabled) via API request.`
237
+ );
235
238
  if (persistToAgent === true) {
236
239
  try {
237
240
  const currentConfig = agent.getEffectiveConfig();
@@ -262,9 +265,10 @@ function createMcpRouter(getAgent) {
262
265
  );
263
266
  }
264
267
  }
265
- return ctx.json({ status: "connected", name }, 200);
268
+ const status = isConnected ? "connected" : "registered";
269
+ return ctx.json({ status, name }, 200);
266
270
  }).openapi(listServersRoute, async (ctx) => {
267
- const agent = getAgent();
271
+ const agent = await getAgent(ctx);
268
272
  const clientsMap = agent.getMcpClients();
269
273
  const failedConnections = agent.getMcpFailedConnections();
270
274
  const servers = [];
@@ -276,7 +280,7 @@ function createMcpRouter(getAgent) {
276
280
  }
277
281
  return ctx.json({ servers });
278
282
  }).openapi(toolsRoute, async (ctx) => {
279
- const agent = getAgent();
283
+ const agent = await getAgent(ctx);
280
284
  const { serverId } = ctx.req.valid("param");
281
285
  const client = agent.getMcpClients().get(serverId);
282
286
  if (!client) {
@@ -291,7 +295,7 @@ function createMcpRouter(getAgent) {
291
295
  }));
292
296
  return ctx.json({ tools });
293
297
  }).openapi(deleteServerRoute, async (ctx) => {
294
- const agent = getAgent();
298
+ const agent = await getAgent(ctx);
295
299
  const { serverId } = ctx.req.valid("param");
296
300
  const clientExists = agent.getMcpClients().has(serverId) || agent.getMcpFailedConnections()[serverId];
297
301
  if (!clientExists) {
@@ -300,7 +304,7 @@ function createMcpRouter(getAgent) {
300
304
  await agent.removeMcpServer(serverId);
301
305
  return ctx.json({ status: "disconnected", id: serverId });
302
306
  }).openapi(restartServerRoute, async (ctx) => {
303
- const agent = getAgent();
307
+ const agent = await getAgent(ctx);
304
308
  const { serverId } = ctx.req.valid("param");
305
309
  import_core.logger.info(`Received request to POST /api/mcp/servers/${serverId}/restart`);
306
310
  const clientExists = agent.getMcpClients().has(serverId);
@@ -311,7 +315,7 @@ function createMcpRouter(getAgent) {
311
315
  await agent.restartMcpServer(serverId);
312
316
  return ctx.json({ status: "restarted", id: serverId });
313
317
  }).openapi(execToolRoute, async (ctx) => {
314
- const agent = getAgent();
318
+ const agent = await getAgent(ctx);
315
319
  const { serverId, toolName } = ctx.req.valid("param");
316
320
  const body = ctx.req.valid("json");
317
321
  const client = agent.getMcpClients().get(serverId);
@@ -330,7 +334,7 @@ function createMcpRouter(getAgent) {
330
334
  return ctx.json({ success: false, error: errorMessage }, 200);
331
335
  }
332
336
  }).openapi(listResourcesRoute, async (ctx) => {
333
- const agent = getAgent();
337
+ const agent = await getAgent(ctx);
334
338
  const { serverId } = ctx.req.valid("param");
335
339
  const client = agent.getMcpClients().get(serverId);
336
340
  if (!client) {
@@ -339,7 +343,7 @@ function createMcpRouter(getAgent) {
339
343
  const resources = await agent.listResourcesForServer(serverId);
340
344
  return ctx.json({ success: true, resources });
341
345
  }).openapi(getResourceContentRoute, async (ctx) => {
342
- const agent = getAgent();
346
+ const agent = await getAgent(ctx);
343
347
  const { serverId, resourceId } = ctx.req.valid("param");
344
348
  const client = agent.getMcpClients().get(serverId);
345
349
  if (!client) {
@@ -1,6 +1,6 @@
1
1
  import { OpenAPIHono } from '@hono/zod-openapi';
2
- import type { DextoAgent } from '@dexto/core';
3
- export declare function createMcpRouter(getAgent: () => DextoAgent): OpenAPIHono<import("hono").Env, {
2
+ import type { GetAgentFn } from '../index.js';
3
+ export declare function createMcpRouter(getAgent: GetAgentFn): OpenAPIHono<import("hono").Env, {
4
4
  "/mcp/servers": {
5
5
  $post: {
6
6
  input: {
@@ -9,6 +9,7 @@ export declare function createMcpRouter(getAgent: () => DextoAgent): OpenAPIHono
9
9
  type: "stdio";
10
10
  command: string;
11
11
  timeout?: number | undefined;
12
+ enabled?: boolean | undefined;
12
13
  args?: string[] | undefined;
13
14
  env?: Record<string, string> | undefined;
14
15
  connectionMode?: "strict" | "lenient" | undefined;
@@ -16,12 +17,14 @@ export declare function createMcpRouter(getAgent: () => DextoAgent): OpenAPIHono
16
17
  type: "sse";
17
18
  url: string;
18
19
  timeout?: number | undefined;
20
+ enabled?: boolean | undefined;
19
21
  connectionMode?: "strict" | "lenient" | undefined;
20
22
  headers?: Record<string, string> | undefined;
21
23
  } | {
22
24
  type: "http";
23
25
  url: string;
24
26
  timeout?: number | undefined;
27
+ enabled?: boolean | undefined;
25
28
  connectionMode?: "strict" | "lenient" | undefined;
26
29
  headers?: Record<string, string> | undefined;
27
30
  };
@@ -200,10 +203,10 @@ export declare function createMcpRouter(getAgent: () => DextoAgent): OpenAPIHono
200
203
  source: "mcp" | "internal";
201
204
  description?: string | undefined;
202
205
  mimeType?: string | undefined;
203
- name?: string | undefined;
204
206
  metadata?: {
205
207
  [x: string]: import("hono/utils/types").JSONValue;
206
208
  } | undefined;
209
+ name?: string | undefined;
207
210
  serverName?: string | undefined;
208
211
  size?: number | undefined;
209
212
  lastModified?: string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA0I9C,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA4SzD"}
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAIhE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAuI9C,wBAAgB,eAAe,CAAC,QAAQ,EAAE,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAkTnD"}
@@ -1,5 +1,5 @@
1
1
  import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
2
- import { logger, McpServerConfigSchema } from "@dexto/core";
2
+ import { 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({
@@ -17,7 +17,7 @@ const ServerStatusResponseSchema = z.object({
17
17
  const ServerInfoSchema = z.object({
18
18
  id: z.string().describe("Server identifier"),
19
19
  name: z.string().describe("Server name"),
20
- status: z.enum(["connected", "error", "disconnected"]).describe("Server status")
20
+ status: z.enum(MCP_CONNECTION_STATUSES).describe("Server status")
21
21
  }).strict().describe("MCP server information");
22
22
  const ServersListResponseSchema = z.object({
23
23
  servers: z.array(ServerInfoSchema).describe("Array of server information")
@@ -205,10 +205,13 @@ function createMcpRouter(getAgent) {
205
205
  }
206
206
  });
207
207
  return app.openapi(addServerRoute, async (ctx) => {
208
- const agent = getAgent();
208
+ const agent = await getAgent(ctx);
209
209
  const { name, config, persistToAgent } = ctx.req.valid("json");
210
- await agent.connectMcpServer(name, config);
211
- logger.info(`Successfully connected to new server '${name}' via API request.`);
210
+ await agent.addMcpServer(name, config);
211
+ const isConnected = config.enabled !== false;
212
+ logger.info(
213
+ isConnected ? `Successfully connected to new server '${name}' via API request.` : `Registered server '${name}' (disabled) via API request.`
214
+ );
212
215
  if (persistToAgent === true) {
213
216
  try {
214
217
  const currentConfig = agent.getEffectiveConfig();
@@ -239,9 +242,10 @@ function createMcpRouter(getAgent) {
239
242
  );
240
243
  }
241
244
  }
242
- return ctx.json({ status: "connected", name }, 200);
245
+ const status = isConnected ? "connected" : "registered";
246
+ return ctx.json({ status, name }, 200);
243
247
  }).openapi(listServersRoute, async (ctx) => {
244
- const agent = getAgent();
248
+ const agent = await getAgent(ctx);
245
249
  const clientsMap = agent.getMcpClients();
246
250
  const failedConnections = agent.getMcpFailedConnections();
247
251
  const servers = [];
@@ -253,7 +257,7 @@ function createMcpRouter(getAgent) {
253
257
  }
254
258
  return ctx.json({ servers });
255
259
  }).openapi(toolsRoute, async (ctx) => {
256
- const agent = getAgent();
260
+ const agent = await getAgent(ctx);
257
261
  const { serverId } = ctx.req.valid("param");
258
262
  const client = agent.getMcpClients().get(serverId);
259
263
  if (!client) {
@@ -268,7 +272,7 @@ function createMcpRouter(getAgent) {
268
272
  }));
269
273
  return ctx.json({ tools });
270
274
  }).openapi(deleteServerRoute, async (ctx) => {
271
- const agent = getAgent();
275
+ const agent = await getAgent(ctx);
272
276
  const { serverId } = ctx.req.valid("param");
273
277
  const clientExists = agent.getMcpClients().has(serverId) || agent.getMcpFailedConnections()[serverId];
274
278
  if (!clientExists) {
@@ -277,7 +281,7 @@ function createMcpRouter(getAgent) {
277
281
  await agent.removeMcpServer(serverId);
278
282
  return ctx.json({ status: "disconnected", id: serverId });
279
283
  }).openapi(restartServerRoute, async (ctx) => {
280
- const agent = getAgent();
284
+ const agent = await getAgent(ctx);
281
285
  const { serverId } = ctx.req.valid("param");
282
286
  logger.info(`Received request to POST /api/mcp/servers/${serverId}/restart`);
283
287
  const clientExists = agent.getMcpClients().has(serverId);
@@ -288,7 +292,7 @@ function createMcpRouter(getAgent) {
288
292
  await agent.restartMcpServer(serverId);
289
293
  return ctx.json({ status: "restarted", id: serverId });
290
294
  }).openapi(execToolRoute, async (ctx) => {
291
- const agent = getAgent();
295
+ const agent = await getAgent(ctx);
292
296
  const { serverId, toolName } = ctx.req.valid("param");
293
297
  const body = ctx.req.valid("json");
294
298
  const client = agent.getMcpClients().get(serverId);
@@ -307,7 +311,7 @@ function createMcpRouter(getAgent) {
307
311
  return ctx.json({ success: false, error: errorMessage }, 200);
308
312
  }
309
313
  }).openapi(listResourcesRoute, async (ctx) => {
310
- const agent = getAgent();
314
+ const agent = await getAgent(ctx);
311
315
  const { serverId } = ctx.req.valid("param");
312
316
  const client = agent.getMcpClients().get(serverId);
313
317
  if (!client) {
@@ -316,7 +320,7 @@ function createMcpRouter(getAgent) {
316
320
  const resources = await agent.listResourcesForServer(serverId);
317
321
  return ctx.json({ success: true, resources });
318
322
  }).openapi(getResourceContentRoute, async (ctx) => {
319
- const agent = getAgent();
323
+ const agent = await getAgent(ctx);
320
324
  const { serverId, resourceId } = ctx.req.valid("param");
321
325
  const client = agent.getMcpClients().get(serverId);
322
326
  if (!client) {
@@ -150,7 +150,7 @@ function createMemoryRouter(getAgent) {
150
150
  if (input.metadata !== void 0) {
151
151
  createInput.metadata = input.metadata;
152
152
  }
153
- const agent = getAgent();
153
+ const agent = await getAgent(ctx);
154
154
  const memory = await agent.memoryManager.create(createInput);
155
155
  return ctx.json({ ok: true, memory }, 201);
156
156
  }).openapi(listRoute, async (ctx) => {
@@ -161,12 +161,12 @@ function createMemoryRouter(getAgent) {
161
161
  if (query.pinned !== void 0) options.pinned = query.pinned;
162
162
  if (query.limit !== void 0) options.limit = query.limit;
163
163
  if (query.offset !== void 0) options.offset = query.offset;
164
- const agent = getAgent();
164
+ const agent = await getAgent(ctx);
165
165
  const memories = await agent.memoryManager.list(options);
166
166
  return ctx.json({ ok: true, memories });
167
167
  }).openapi(getRoute, async (ctx) => {
168
168
  const { id } = ctx.req.valid("param");
169
- const agent = getAgent();
169
+ const agent = await getAgent(ctx);
170
170
  const memory = await agent.memoryManager.get(id);
171
171
  return ctx.json({ ok: true, memory });
172
172
  }).openapi(updateRoute, async (ctx) => {
@@ -176,12 +176,12 @@ function createMemoryRouter(getAgent) {
176
176
  if (updatesRaw.content !== void 0) updates.content = updatesRaw.content;
177
177
  if (updatesRaw.metadata !== void 0) updates.metadata = updatesRaw.metadata;
178
178
  if (updatesRaw.tags !== void 0) updates.tags = updatesRaw.tags;
179
- const agent = getAgent();
179
+ const agent = await getAgent(ctx);
180
180
  const memory = await agent.memoryManager.update(id, updates);
181
181
  return ctx.json({ ok: true, memory });
182
182
  }).openapi(deleteRoute, async (ctx) => {
183
183
  const { id } = ctx.req.valid("param");
184
- const agent = getAgent();
184
+ const agent = await getAgent(ctx);
185
185
  await agent.memoryManager.delete(id);
186
186
  return ctx.json({ ok: true, message: "Memory deleted successfully" });
187
187
  });
@@ -1,6 +1,8 @@
1
1
  import { OpenAPIHono, z } from '@hono/zod-openapi';
2
2
  import type { DextoAgent } from '@dexto/core';
3
- export declare function createMemoryRouter(getAgent: () => DextoAgent): OpenAPIHono<import("hono").Env, {
3
+ import type { Context } from 'hono';
4
+ type GetAgentFn = (ctx: Context) => DextoAgent | Promise<DextoAgent>;
5
+ export declare function createMemoryRouter(getAgent: GetAgentFn): OpenAPIHono<import("hono").Env, {
4
6
  "/memory": {
5
7
  $post: {
6
8
  input: {
@@ -99,11 +101,11 @@ export declare function createMemoryRouter(getAgent: () => DextoAgent): OpenAPIH
99
101
  };
100
102
  } & {
101
103
  json: {
104
+ content?: string | undefined;
102
105
  metadata?: z.objectInputType<{
103
106
  source: z.ZodOptional<z.ZodEnum<["user", "system"]>>;
104
107
  pinned: z.ZodOptional<z.ZodBoolean>;
105
108
  }, z.ZodTypeAny, "passthrough"> | undefined;
106
- content?: string | undefined;
107
109
  tags?: string[] | undefined;
108
110
  };
109
111
  };
@@ -143,4 +145,5 @@ export declare function createMemoryRouter(getAgent: () => DextoAgent): OpenAPIH
143
145
  };
144
146
  };
145
147
  }, "/">;
148
+ export {};
146
149
  //# sourceMappingURL=memory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/memory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAe,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA6D9C,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAwK5D"}
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/memory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAe,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AA2DrE,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAwKtD"}
@@ -127,7 +127,7 @@ function createMemoryRouter(getAgent) {
127
127
  if (input.metadata !== void 0) {
128
128
  createInput.metadata = input.metadata;
129
129
  }
130
- const agent = getAgent();
130
+ const agent = await getAgent(ctx);
131
131
  const memory = await agent.memoryManager.create(createInput);
132
132
  return ctx.json({ ok: true, memory }, 201);
133
133
  }).openapi(listRoute, async (ctx) => {
@@ -138,12 +138,12 @@ function createMemoryRouter(getAgent) {
138
138
  if (query.pinned !== void 0) options.pinned = query.pinned;
139
139
  if (query.limit !== void 0) options.limit = query.limit;
140
140
  if (query.offset !== void 0) options.offset = query.offset;
141
- const agent = getAgent();
141
+ const agent = await getAgent(ctx);
142
142
  const memories = await agent.memoryManager.list(options);
143
143
  return ctx.json({ ok: true, memories });
144
144
  }).openapi(getRoute, async (ctx) => {
145
145
  const { id } = ctx.req.valid("param");
146
- const agent = getAgent();
146
+ const agent = await getAgent(ctx);
147
147
  const memory = await agent.memoryManager.get(id);
148
148
  return ctx.json({ ok: true, memory });
149
149
  }).openapi(updateRoute, async (ctx) => {
@@ -153,12 +153,12 @@ function createMemoryRouter(getAgent) {
153
153
  if (updatesRaw.content !== void 0) updates.content = updatesRaw.content;
154
154
  if (updatesRaw.metadata !== void 0) updates.metadata = updatesRaw.metadata;
155
155
  if (updatesRaw.tags !== void 0) updates.tags = updatesRaw.tags;
156
- const agent = getAgent();
156
+ const agent = await getAgent(ctx);
157
157
  const memory = await agent.memoryManager.update(id, updates);
158
158
  return ctx.json({ ok: true, memory });
159
159
  }).openapi(deleteRoute, async (ctx) => {
160
160
  const { id } = ctx.req.valid("param");
161
- const agent = getAgent();
161
+ const agent = await getAgent(ctx);
162
162
  await agent.memoryManager.delete(id);
163
163
  return ctx.json({ ok: true, message: "Memory deleted successfully" });
164
164
  });