@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.
- package/dist/approval/manual-approval-handler.cjs +23 -15
- package/dist/approval/manual-approval-handler.d.ts.map +1 -1
- package/dist/approval/manual-approval-handler.js +23 -15
- package/dist/events/webhook-subscriber.cjs +1 -1
- package/dist/events/webhook-subscriber.d.ts.map +1 -1
- package/dist/events/webhook-subscriber.js +1 -1
- package/dist/hono/__tests__/test-fixtures.cjs +3 -3
- package/dist/hono/__tests__/test-fixtures.d.ts.map +1 -1
- package/dist/hono/__tests__/test-fixtures.js +3 -3
- package/dist/hono/index.cjs +46 -5
- package/dist/hono/index.d.ts +928 -584
- package/dist/hono/index.d.ts.map +1 -1
- package/dist/hono/index.js +46 -5
- package/dist/hono/middleware/error.d.ts.map +1 -1
- package/dist/hono/routes/a2a-jsonrpc.cjs +3 -3
- package/dist/hono/routes/a2a-jsonrpc.d.ts +4 -1
- package/dist/hono/routes/a2a-jsonrpc.d.ts.map +1 -1
- package/dist/hono/routes/a2a-jsonrpc.js +3 -3
- package/dist/hono/routes/a2a-tasks.cjs +5 -5
- package/dist/hono/routes/a2a-tasks.d.ts +13 -10
- package/dist/hono/routes/a2a-tasks.d.ts.map +1 -1
- package/dist/hono/routes/a2a-tasks.js +5 -5
- package/dist/hono/routes/agents.cjs +30 -42
- package/dist/hono/routes/agents.d.ts +7 -401
- package/dist/hono/routes/agents.d.ts.map +1 -1
- package/dist/hono/routes/agents.js +32 -42
- package/dist/hono/routes/approvals.cjs +53 -2
- package/dist/hono/routes/approvals.d.ts +29 -1
- package/dist/hono/routes/approvals.d.ts.map +1 -1
- package/dist/hono/routes/approvals.js +53 -2
- package/dist/hono/routes/discovery.cjs +67 -0
- package/dist/hono/routes/discovery.d.ts +44 -0
- package/dist/hono/routes/discovery.d.ts.map +1 -0
- package/dist/hono/routes/discovery.js +43 -0
- package/dist/hono/routes/greeting.cjs +2 -2
- package/dist/hono/routes/greeting.d.ts +2 -2
- package/dist/hono/routes/greeting.d.ts.map +1 -1
- package/dist/hono/routes/greeting.js +2 -2
- package/dist/hono/routes/health.d.ts +2 -2
- package/dist/hono/routes/health.d.ts.map +1 -1
- package/dist/hono/routes/key.cjs +110 -0
- package/dist/hono/routes/key.d.ts +48 -0
- package/dist/hono/routes/key.d.ts.map +1 -0
- package/dist/hono/routes/key.js +90 -0
- package/dist/hono/routes/llm.cjs +119 -62
- package/dist/hono/routes/llm.d.ts +242 -42
- package/dist/hono/routes/llm.d.ts.map +1 -1
- package/dist/hono/routes/llm.js +118 -58
- package/dist/hono/routes/mcp.cjs +16 -12
- package/dist/hono/routes/mcp.d.ts +6 -3
- package/dist/hono/routes/mcp.d.ts.map +1 -1
- package/dist/hono/routes/mcp.js +17 -13
- package/dist/hono/routes/memory.cjs +5 -5
- package/dist/hono/routes/memory.d.ts +5 -2
- package/dist/hono/routes/memory.d.ts.map +1 -1
- package/dist/hono/routes/memory.js +5 -5
- package/dist/hono/routes/messages.cjs +58 -66
- package/dist/hono/routes/messages.d.ts +99 -55
- package/dist/hono/routes/messages.d.ts.map +1 -1
- package/dist/hono/routes/messages.js +59 -67
- package/dist/hono/routes/models.cjs +319 -0
- package/dist/hono/routes/models.d.ts +107 -0
- package/dist/hono/routes/models.d.ts.map +1 -0
- package/dist/hono/routes/models.js +305 -0
- package/dist/hono/routes/openrouter.cjs +153 -0
- package/dist/hono/routes/openrouter.d.ts +54 -0
- package/dist/hono/routes/openrouter.d.ts.map +1 -0
- package/dist/hono/routes/openrouter.js +134 -0
- package/dist/hono/routes/prompts.cjs +5 -5
- package/dist/hono/routes/prompts.d.ts +10 -7
- package/dist/hono/routes/prompts.d.ts.map +1 -1
- package/dist/hono/routes/prompts.js +5 -5
- package/dist/hono/routes/queue.cjs +202 -0
- package/dist/hono/routes/queue.d.ts +174 -0
- package/dist/hono/routes/queue.d.ts.map +1 -0
- package/dist/hono/routes/queue.js +178 -0
- package/dist/hono/routes/resources.cjs +3 -3
- package/dist/hono/routes/resources.d.ts +3 -3
- package/dist/hono/routes/resources.d.ts.map +1 -1
- package/dist/hono/routes/resources.js +3 -3
- package/dist/hono/routes/search.cjs +2 -2
- package/dist/hono/routes/search.d.ts +39 -10
- package/dist/hono/routes/search.d.ts.map +1 -1
- package/dist/hono/routes/search.js +2 -2
- package/dist/hono/routes/sessions.cjs +74 -20
- package/dist/hono/routes/sessions.d.ts +25 -4
- package/dist/hono/routes/sessions.d.ts.map +1 -1
- package/dist/hono/routes/sessions.js +74 -20
- package/dist/hono/routes/tools.cjs +126 -0
- package/dist/hono/routes/tools.d.ts +42 -0
- package/dist/hono/routes/tools.d.ts.map +1 -0
- package/dist/hono/routes/tools.js +102 -0
- package/dist/hono/routes/webhooks.cjs +4 -4
- package/dist/hono/routes/webhooks.d.ts +4 -1
- package/dist/hono/routes/webhooks.d.ts.map +1 -1
- package/dist/hono/routes/webhooks.js +4 -4
- package/dist/hono/schemas/responses.cjs +24 -5
- package/dist/hono/schemas/responses.d.ts +838 -120
- package/dist/hono/schemas/responses.d.ts.map +1 -1
- package/dist/hono/schemas/responses.js +24 -10
- package/dist/hono/start-server.cjs +102 -0
- package/dist/hono/start-server.d.ts +61 -0
- package/dist/hono/start-server.d.ts.map +1 -0
- package/dist/hono/start-server.js +78 -0
- package/dist/index.cjs +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/package.json +5 -4
package/dist/hono/routes/llm.js
CHANGED
|
@@ -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 {
|
|
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
|
-
|
|
156
|
-
|
|
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 {
|
package/dist/hono/routes/mcp.cjs
CHANGED
|
@@ -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(
|
|
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.
|
|
234
|
-
|
|
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
|
-
|
|
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 {
|
|
3
|
-
export declare function createMcpRouter(getAgent:
|
|
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;
|
|
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"}
|
package/dist/hono/routes/mcp.js
CHANGED
|
@@ -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(
|
|
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.
|
|
211
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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;
|
|
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
|
});
|