@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
|
@@ -72,7 +72,7 @@ function createSessionsRouter(getAgent) {
|
|
|
72
72
|
method: "get",
|
|
73
73
|
path: "/sessions/{sessionId}/history",
|
|
74
74
|
summary: "Get Session History",
|
|
75
|
-
description: "Retrieves the conversation history for a session",
|
|
75
|
+
description: "Retrieves the conversation history for a session along with processing status",
|
|
76
76
|
tags: ["sessions"],
|
|
77
77
|
request: { params: z.object({ sessionId: z.string().describe("Session identifier") }) },
|
|
78
78
|
responses: {
|
|
@@ -81,7 +81,10 @@ function createSessionsRouter(getAgent) {
|
|
|
81
81
|
content: {
|
|
82
82
|
"application/json": {
|
|
83
83
|
schema: z.object({
|
|
84
|
-
history: z.array(InternalMessageSchema).describe("Array of messages in conversation history")
|
|
84
|
+
history: z.array(InternalMessageSchema).describe("Array of messages in conversation history"),
|
|
85
|
+
isBusy: z.boolean().describe(
|
|
86
|
+
"Whether the session is currently processing a message"
|
|
87
|
+
)
|
|
85
88
|
}).strict()
|
|
86
89
|
}
|
|
87
90
|
}
|
|
@@ -113,9 +116,23 @@ function createSessionsRouter(getAgent) {
|
|
|
113
116
|
method: "post",
|
|
114
117
|
path: "/sessions/{sessionId}/cancel",
|
|
115
118
|
summary: "Cancel Session Run",
|
|
116
|
-
description: "Cancels an in-flight agent run for the specified session",
|
|
119
|
+
description: "Cancels an in-flight agent run for the specified session. By default (soft cancel), only the current LLM call is cancelled and queued messages continue processing. Set clearQueue=true for hard cancel to also clear any queued messages.",
|
|
117
120
|
tags: ["sessions"],
|
|
118
|
-
request: {
|
|
121
|
+
request: {
|
|
122
|
+
params: z.object({ sessionId: z.string().describe("Session identifier") }),
|
|
123
|
+
body: {
|
|
124
|
+
content: {
|
|
125
|
+
"application/json": {
|
|
126
|
+
schema: z.object({
|
|
127
|
+
clearQueue: z.boolean().optional().default(false).describe(
|
|
128
|
+
"If true (hard cancel), clears queued messages. If false (soft cancel, default), queued messages continue processing."
|
|
129
|
+
)
|
|
130
|
+
}).strict()
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
required: false
|
|
134
|
+
}
|
|
135
|
+
},
|
|
119
136
|
responses: {
|
|
120
137
|
200: {
|
|
121
138
|
description: "Cancel operation result",
|
|
@@ -123,7 +140,11 @@ function createSessionsRouter(getAgent) {
|
|
|
123
140
|
"application/json": {
|
|
124
141
|
schema: z.object({
|
|
125
142
|
cancelled: z.boolean().describe("Whether a run was cancelled"),
|
|
126
|
-
sessionId: z.string().describe("Session ID")
|
|
143
|
+
sessionId: z.string().describe("Session ID"),
|
|
144
|
+
queueCleared: z.boolean().describe("Whether queued messages were cleared"),
|
|
145
|
+
clearedCount: z.number().describe(
|
|
146
|
+
"Number of queued messages cleared (0 if soft cancel)"
|
|
147
|
+
)
|
|
127
148
|
}).strict()
|
|
128
149
|
}
|
|
129
150
|
}
|
|
@@ -134,7 +155,7 @@ function createSessionsRouter(getAgent) {
|
|
|
134
155
|
method: "get",
|
|
135
156
|
path: "/sessions/{sessionId}/load",
|
|
136
157
|
summary: "Load Session",
|
|
137
|
-
description: "Validates and retrieves session information. The client should track the active session.",
|
|
158
|
+
description: "Validates and retrieves session information including processing status. The client should track the active session.",
|
|
138
159
|
tags: ["sessions"],
|
|
139
160
|
request: {
|
|
140
161
|
params: z.object({ sessionId: z.string().describe("Session identifier") })
|
|
@@ -145,7 +166,11 @@ function createSessionsRouter(getAgent) {
|
|
|
145
166
|
content: {
|
|
146
167
|
"application/json": {
|
|
147
168
|
schema: z.object({
|
|
148
|
-
session: SessionMetadataSchema.
|
|
169
|
+
session: SessionMetadataSchema.extend({
|
|
170
|
+
isBusy: z.boolean().describe(
|
|
171
|
+
"Whether the session is currently processing a message"
|
|
172
|
+
)
|
|
173
|
+
}).describe("Session metadata with processing status")
|
|
149
174
|
}).strict()
|
|
150
175
|
}
|
|
151
176
|
}
|
|
@@ -220,7 +245,7 @@ function createSessionsRouter(getAgent) {
|
|
|
220
245
|
}
|
|
221
246
|
});
|
|
222
247
|
return app.openapi(listRoute, async (ctx) => {
|
|
223
|
-
const agent = getAgent();
|
|
248
|
+
const agent = await getAgent(ctx);
|
|
224
249
|
const sessionIds = await agent.listSessions();
|
|
225
250
|
const sessions = await Promise.all(
|
|
226
251
|
sessionIds.map(async (id) => {
|
|
@@ -246,7 +271,7 @@ function createSessionsRouter(getAgent) {
|
|
|
246
271
|
);
|
|
247
272
|
return ctx.json({ sessions });
|
|
248
273
|
}).openapi(createRouteDef, async (ctx) => {
|
|
249
|
-
const agent = getAgent();
|
|
274
|
+
const agent = await getAgent(ctx);
|
|
250
275
|
const { sessionId } = ctx.req.valid("json");
|
|
251
276
|
const session = await agent.createSession(sessionId);
|
|
252
277
|
const metadata = await agent.getSessionMetadata(session.id);
|
|
@@ -263,7 +288,7 @@ function createSessionsRouter(getAgent) {
|
|
|
263
288
|
201
|
|
264
289
|
);
|
|
265
290
|
}).openapi(getRoute, async (ctx) => {
|
|
266
|
-
const agent = getAgent();
|
|
291
|
+
const agent = await getAgent(ctx);
|
|
267
292
|
const { sessionId } = ctx.req.param();
|
|
268
293
|
const metadata = await agent.getSessionMetadata(sessionId);
|
|
269
294
|
const history = await agent.getSessionHistory(sessionId);
|
|
@@ -278,31 +303,59 @@ function createSessionsRouter(getAgent) {
|
|
|
278
303
|
}
|
|
279
304
|
});
|
|
280
305
|
}).openapi(historyRoute, async (ctx) => {
|
|
281
|
-
const agent = getAgent();
|
|
306
|
+
const agent = await getAgent(ctx);
|
|
282
307
|
const { sessionId } = ctx.req.param();
|
|
283
|
-
const history = await
|
|
284
|
-
|
|
308
|
+
const [history, isBusy] = await Promise.all([
|
|
309
|
+
agent.getSessionHistory(sessionId),
|
|
310
|
+
agent.isSessionBusy(sessionId)
|
|
311
|
+
]);
|
|
312
|
+
return ctx.json({
|
|
313
|
+
history,
|
|
314
|
+
isBusy
|
|
315
|
+
});
|
|
285
316
|
}).openapi(deleteRoute, async (ctx) => {
|
|
286
|
-
const agent = getAgent();
|
|
317
|
+
const agent = await getAgent(ctx);
|
|
287
318
|
const { sessionId } = ctx.req.param();
|
|
288
319
|
await agent.deleteSession(sessionId);
|
|
289
320
|
return ctx.json({ status: "deleted", sessionId });
|
|
290
321
|
}).openapi(cancelRoute, async (ctx) => {
|
|
291
|
-
const agent = getAgent();
|
|
322
|
+
const agent = await getAgent(ctx);
|
|
292
323
|
const { sessionId } = ctx.req.valid("param");
|
|
324
|
+
let clearQueue = false;
|
|
325
|
+
try {
|
|
326
|
+
const body = ctx.req.valid("json");
|
|
327
|
+
clearQueue = body?.clearQueue ?? false;
|
|
328
|
+
} catch {
|
|
329
|
+
}
|
|
330
|
+
let clearedCount = 0;
|
|
331
|
+
if (clearQueue) {
|
|
332
|
+
try {
|
|
333
|
+
clearedCount = await agent.clearMessageQueue(sessionId);
|
|
334
|
+
agent.logger.debug(
|
|
335
|
+
`Hard cancel: cleared ${clearedCount} queued message(s) for session: ${sessionId}`
|
|
336
|
+
);
|
|
337
|
+
} catch {
|
|
338
|
+
}
|
|
339
|
+
}
|
|
293
340
|
const cancelled = await agent.cancel(sessionId);
|
|
294
341
|
if (!cancelled) {
|
|
295
342
|
agent.logger.debug(`No in-flight run to cancel for session: ${sessionId}`);
|
|
296
343
|
}
|
|
297
|
-
return ctx.json({
|
|
344
|
+
return ctx.json({
|
|
345
|
+
cancelled,
|
|
346
|
+
sessionId,
|
|
347
|
+
queueCleared: clearQueue,
|
|
348
|
+
clearedCount
|
|
349
|
+
});
|
|
298
350
|
}).openapi(loadRoute, async (ctx) => {
|
|
299
|
-
const agent = getAgent();
|
|
351
|
+
const agent = await getAgent(ctx);
|
|
300
352
|
const { sessionId } = ctx.req.valid("param");
|
|
301
353
|
const sessionIds = await agent.listSessions();
|
|
302
354
|
if (!sessionIds.includes(sessionId)) {
|
|
303
355
|
return ctx.json({ error: `Session not found: ${sessionId}` }, 404);
|
|
304
356
|
}
|
|
305
357
|
const metadata = await agent.getSessionMetadata(sessionId);
|
|
358
|
+
const isBusy = await agent.isSessionBusy(sessionId);
|
|
306
359
|
return ctx.json(
|
|
307
360
|
{
|
|
308
361
|
session: {
|
|
@@ -310,13 +363,14 @@ function createSessionsRouter(getAgent) {
|
|
|
310
363
|
createdAt: metadata?.createdAt || null,
|
|
311
364
|
lastActivity: metadata?.lastActivity || null,
|
|
312
365
|
messageCount: metadata?.messageCount || 0,
|
|
313
|
-
title: metadata?.title || null
|
|
366
|
+
title: metadata?.title || null,
|
|
367
|
+
isBusy
|
|
314
368
|
}
|
|
315
369
|
},
|
|
316
370
|
200
|
|
317
371
|
);
|
|
318
372
|
}).openapi(patchRoute, async (ctx) => {
|
|
319
|
-
const agent = getAgent();
|
|
373
|
+
const agent = await getAgent(ctx);
|
|
320
374
|
const { sessionId } = ctx.req.valid("param");
|
|
321
375
|
const { title } = ctx.req.valid("json");
|
|
322
376
|
await agent.setSessionTitle(sessionId, title);
|
|
@@ -331,7 +385,7 @@ function createSessionsRouter(getAgent) {
|
|
|
331
385
|
}
|
|
332
386
|
});
|
|
333
387
|
}).openapi(generateTitleRoute, async (ctx) => {
|
|
334
|
-
const agent = getAgent();
|
|
388
|
+
const agent = await getAgent(ctx);
|
|
335
389
|
const { sessionId } = ctx.req.valid("param");
|
|
336
390
|
const title = await agent.generateSessionTitle(sessionId);
|
|
337
391
|
return ctx.json({ title, sessionId });
|
|
@@ -0,0 +1,126 @@
|
|
|
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 tools_exports = {};
|
|
20
|
+
__export(tools_exports, {
|
|
21
|
+
createToolsRouter: () => createToolsRouter
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(tools_exports);
|
|
24
|
+
var import_zod_openapi = require("@hono/zod-openapi");
|
|
25
|
+
const JsonSchemaProperty = import_zod_openapi.z.object({
|
|
26
|
+
type: import_zod_openapi.z.enum(["string", "number", "integer", "boolean", "object", "array"]).optional().describe("Property type"),
|
|
27
|
+
description: import_zod_openapi.z.string().optional().describe("Property description"),
|
|
28
|
+
enum: import_zod_openapi.z.array(import_zod_openapi.z.union([import_zod_openapi.z.string(), import_zod_openapi.z.number(), import_zod_openapi.z.boolean()])).optional().describe("Enum values"),
|
|
29
|
+
default: import_zod_openapi.z.any().optional().describe("Default value")
|
|
30
|
+
}).passthrough().describe("JSON Schema property definition");
|
|
31
|
+
const ToolInputSchema = import_zod_openapi.z.object({
|
|
32
|
+
type: import_zod_openapi.z.literal("object").optional().describe('Schema type, always "object" when present'),
|
|
33
|
+
properties: import_zod_openapi.z.record(JsonSchemaProperty).optional().describe("Property definitions"),
|
|
34
|
+
required: import_zod_openapi.z.array(import_zod_openapi.z.string()).optional().describe("Required property names")
|
|
35
|
+
}).passthrough().describe("JSON Schema for tool input parameters");
|
|
36
|
+
const ToolInfoSchema = import_zod_openapi.z.object({
|
|
37
|
+
id: import_zod_openapi.z.string().describe("Tool identifier"),
|
|
38
|
+
name: import_zod_openapi.z.string().describe("Tool name"),
|
|
39
|
+
description: import_zod_openapi.z.string().describe("Tool description"),
|
|
40
|
+
source: import_zod_openapi.z.enum(["internal", "custom", "mcp"]).describe("Source of the tool (internal, custom, or mcp)"),
|
|
41
|
+
serverName: import_zod_openapi.z.string().optional().describe("MCP server name (if source is mcp)"),
|
|
42
|
+
inputSchema: ToolInputSchema.optional().describe("JSON Schema for tool input parameters")
|
|
43
|
+
}).strict().describe("Tool information");
|
|
44
|
+
const AllToolsResponseSchema = import_zod_openapi.z.object({
|
|
45
|
+
tools: import_zod_openapi.z.array(ToolInfoSchema).describe("Array of all available tools"),
|
|
46
|
+
totalCount: import_zod_openapi.z.number().describe("Total number of tools"),
|
|
47
|
+
internalCount: import_zod_openapi.z.number().describe("Number of internal tools"),
|
|
48
|
+
customCount: import_zod_openapi.z.number().describe("Number of custom tools"),
|
|
49
|
+
mcpCount: import_zod_openapi.z.number().describe("Number of MCP tools")
|
|
50
|
+
}).strict().describe("All available tools from all sources");
|
|
51
|
+
function createToolsRouter(getAgent) {
|
|
52
|
+
const app = new import_zod_openapi.OpenAPIHono();
|
|
53
|
+
const allToolsRoute = (0, import_zod_openapi.createRoute)({
|
|
54
|
+
method: "get",
|
|
55
|
+
path: "/tools",
|
|
56
|
+
summary: "List All Tools",
|
|
57
|
+
description: "Retrieves all available tools from all sources (internal, custom, and MCP servers)",
|
|
58
|
+
tags: ["tools"],
|
|
59
|
+
responses: {
|
|
60
|
+
200: {
|
|
61
|
+
description: "All tools",
|
|
62
|
+
content: { "application/json": { schema: AllToolsResponseSchema } }
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
return app.openapi(allToolsRoute, async (ctx) => {
|
|
67
|
+
const agent = await getAgent(ctx);
|
|
68
|
+
const allTools = await agent.getAllTools();
|
|
69
|
+
const mcpToolsWithServerInfo = agent.getAllMcpToolsWithServerInfo();
|
|
70
|
+
const toolList = [];
|
|
71
|
+
let internalCount = 0;
|
|
72
|
+
let customCount = 0;
|
|
73
|
+
let mcpCount = 0;
|
|
74
|
+
for (const [toolName, toolInfo] of Object.entries(allTools)) {
|
|
75
|
+
let source;
|
|
76
|
+
let serverName;
|
|
77
|
+
if (toolName.startsWith("mcp--")) {
|
|
78
|
+
const mcpToolName = toolName.substring(5);
|
|
79
|
+
const mcpToolInfo = mcpToolsWithServerInfo.get(mcpToolName);
|
|
80
|
+
if (mcpToolInfo) {
|
|
81
|
+
source = "mcp";
|
|
82
|
+
serverName = mcpToolInfo.serverName;
|
|
83
|
+
mcpCount++;
|
|
84
|
+
} else {
|
|
85
|
+
source = "mcp";
|
|
86
|
+
mcpCount++;
|
|
87
|
+
}
|
|
88
|
+
} else if (toolName.startsWith("internal--")) {
|
|
89
|
+
source = "internal";
|
|
90
|
+
internalCount++;
|
|
91
|
+
} else if (toolName.startsWith("custom--")) {
|
|
92
|
+
source = "custom";
|
|
93
|
+
customCount++;
|
|
94
|
+
} else {
|
|
95
|
+
source = "internal";
|
|
96
|
+
internalCount++;
|
|
97
|
+
}
|
|
98
|
+
toolList.push({
|
|
99
|
+
id: toolName,
|
|
100
|
+
name: toolName,
|
|
101
|
+
description: toolInfo.description || "No description available",
|
|
102
|
+
source,
|
|
103
|
+
serverName,
|
|
104
|
+
inputSchema: toolInfo.parameters
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
toolList.sort((a, b) => {
|
|
108
|
+
const sourceOrder = { internal: 0, custom: 1, mcp: 2 };
|
|
109
|
+
if (a.source !== b.source) {
|
|
110
|
+
return sourceOrder[a.source] - sourceOrder[b.source];
|
|
111
|
+
}
|
|
112
|
+
return a.name.localeCompare(b.name);
|
|
113
|
+
});
|
|
114
|
+
return ctx.json({
|
|
115
|
+
tools: toolList,
|
|
116
|
+
totalCount: toolList.length,
|
|
117
|
+
internalCount,
|
|
118
|
+
customCount,
|
|
119
|
+
mcpCount
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
124
|
+
0 && (module.exports = {
|
|
125
|
+
createToolsRouter
|
|
126
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { OpenAPIHono } from '@hono/zod-openapi';
|
|
2
|
+
import type { DextoAgent } from '@dexto/core';
|
|
3
|
+
import type { Context } from 'hono';
|
|
4
|
+
type GetAgentFn = (ctx: Context) => DextoAgent | Promise<DextoAgent>;
|
|
5
|
+
export declare function createToolsRouter(getAgent: GetAgentFn): OpenAPIHono<import("hono").Env, {
|
|
6
|
+
"/tools": {
|
|
7
|
+
$get: {
|
|
8
|
+
input: {};
|
|
9
|
+
output: {
|
|
10
|
+
tools: {
|
|
11
|
+
description: string;
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
source: "custom" | "mcp" | "internal";
|
|
15
|
+
serverName?: string | undefined;
|
|
16
|
+
inputSchema?: {
|
|
17
|
+
[x: string]: import("hono/utils/types").JSONValue;
|
|
18
|
+
type?: "object" | undefined;
|
|
19
|
+
properties?: {
|
|
20
|
+
[x: string]: {
|
|
21
|
+
[x: string]: import("hono/utils/types").JSONValue;
|
|
22
|
+
description?: string | undefined;
|
|
23
|
+
default?: any;
|
|
24
|
+
type?: "string" | "number" | "boolean" | "object" | "integer" | "array" | undefined;
|
|
25
|
+
enum?: (string | number | boolean)[] | undefined;
|
|
26
|
+
};
|
|
27
|
+
} | undefined;
|
|
28
|
+
required?: string[] | undefined;
|
|
29
|
+
} | undefined;
|
|
30
|
+
}[];
|
|
31
|
+
totalCount: number;
|
|
32
|
+
internalCount: number;
|
|
33
|
+
customCount: number;
|
|
34
|
+
mcpCount: number;
|
|
35
|
+
};
|
|
36
|
+
outputFormat: "json";
|
|
37
|
+
status: 200;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
}, "/">;
|
|
41
|
+
export {};
|
|
42
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAqDrE,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA0FrD"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
|
|
2
|
+
const JsonSchemaProperty = z.object({
|
|
3
|
+
type: z.enum(["string", "number", "integer", "boolean", "object", "array"]).optional().describe("Property type"),
|
|
4
|
+
description: z.string().optional().describe("Property description"),
|
|
5
|
+
enum: z.array(z.union([z.string(), z.number(), z.boolean()])).optional().describe("Enum values"),
|
|
6
|
+
default: z.any().optional().describe("Default value")
|
|
7
|
+
}).passthrough().describe("JSON Schema property definition");
|
|
8
|
+
const ToolInputSchema = z.object({
|
|
9
|
+
type: z.literal("object").optional().describe('Schema type, always "object" when present'),
|
|
10
|
+
properties: z.record(JsonSchemaProperty).optional().describe("Property definitions"),
|
|
11
|
+
required: z.array(z.string()).optional().describe("Required property names")
|
|
12
|
+
}).passthrough().describe("JSON Schema for tool input parameters");
|
|
13
|
+
const ToolInfoSchema = z.object({
|
|
14
|
+
id: z.string().describe("Tool identifier"),
|
|
15
|
+
name: z.string().describe("Tool name"),
|
|
16
|
+
description: z.string().describe("Tool description"),
|
|
17
|
+
source: z.enum(["internal", "custom", "mcp"]).describe("Source of the tool (internal, custom, or mcp)"),
|
|
18
|
+
serverName: z.string().optional().describe("MCP server name (if source is mcp)"),
|
|
19
|
+
inputSchema: ToolInputSchema.optional().describe("JSON Schema for tool input parameters")
|
|
20
|
+
}).strict().describe("Tool information");
|
|
21
|
+
const AllToolsResponseSchema = z.object({
|
|
22
|
+
tools: z.array(ToolInfoSchema).describe("Array of all available tools"),
|
|
23
|
+
totalCount: z.number().describe("Total number of tools"),
|
|
24
|
+
internalCount: z.number().describe("Number of internal tools"),
|
|
25
|
+
customCount: z.number().describe("Number of custom tools"),
|
|
26
|
+
mcpCount: z.number().describe("Number of MCP tools")
|
|
27
|
+
}).strict().describe("All available tools from all sources");
|
|
28
|
+
function createToolsRouter(getAgent) {
|
|
29
|
+
const app = new OpenAPIHono();
|
|
30
|
+
const allToolsRoute = createRoute({
|
|
31
|
+
method: "get",
|
|
32
|
+
path: "/tools",
|
|
33
|
+
summary: "List All Tools",
|
|
34
|
+
description: "Retrieves all available tools from all sources (internal, custom, and MCP servers)",
|
|
35
|
+
tags: ["tools"],
|
|
36
|
+
responses: {
|
|
37
|
+
200: {
|
|
38
|
+
description: "All tools",
|
|
39
|
+
content: { "application/json": { schema: AllToolsResponseSchema } }
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
return app.openapi(allToolsRoute, async (ctx) => {
|
|
44
|
+
const agent = await getAgent(ctx);
|
|
45
|
+
const allTools = await agent.getAllTools();
|
|
46
|
+
const mcpToolsWithServerInfo = agent.getAllMcpToolsWithServerInfo();
|
|
47
|
+
const toolList = [];
|
|
48
|
+
let internalCount = 0;
|
|
49
|
+
let customCount = 0;
|
|
50
|
+
let mcpCount = 0;
|
|
51
|
+
for (const [toolName, toolInfo] of Object.entries(allTools)) {
|
|
52
|
+
let source;
|
|
53
|
+
let serverName;
|
|
54
|
+
if (toolName.startsWith("mcp--")) {
|
|
55
|
+
const mcpToolName = toolName.substring(5);
|
|
56
|
+
const mcpToolInfo = mcpToolsWithServerInfo.get(mcpToolName);
|
|
57
|
+
if (mcpToolInfo) {
|
|
58
|
+
source = "mcp";
|
|
59
|
+
serverName = mcpToolInfo.serverName;
|
|
60
|
+
mcpCount++;
|
|
61
|
+
} else {
|
|
62
|
+
source = "mcp";
|
|
63
|
+
mcpCount++;
|
|
64
|
+
}
|
|
65
|
+
} else if (toolName.startsWith("internal--")) {
|
|
66
|
+
source = "internal";
|
|
67
|
+
internalCount++;
|
|
68
|
+
} else if (toolName.startsWith("custom--")) {
|
|
69
|
+
source = "custom";
|
|
70
|
+
customCount++;
|
|
71
|
+
} else {
|
|
72
|
+
source = "internal";
|
|
73
|
+
internalCount++;
|
|
74
|
+
}
|
|
75
|
+
toolList.push({
|
|
76
|
+
id: toolName,
|
|
77
|
+
name: toolName,
|
|
78
|
+
description: toolInfo.description || "No description available",
|
|
79
|
+
source,
|
|
80
|
+
serverName,
|
|
81
|
+
inputSchema: toolInfo.parameters
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
toolList.sort((a, b) => {
|
|
85
|
+
const sourceOrder = { internal: 0, custom: 1, mcp: 2 };
|
|
86
|
+
if (a.source !== b.source) {
|
|
87
|
+
return sourceOrder[a.source] - sourceOrder[b.source];
|
|
88
|
+
}
|
|
89
|
+
return a.name.localeCompare(b.name);
|
|
90
|
+
});
|
|
91
|
+
return ctx.json({
|
|
92
|
+
tools: toolList,
|
|
93
|
+
totalCount: toolList.length,
|
|
94
|
+
internalCount,
|
|
95
|
+
customCount,
|
|
96
|
+
mcpCount
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
export {
|
|
101
|
+
createToolsRouter
|
|
102
|
+
};
|
|
@@ -148,7 +148,7 @@ function createWebhooksRouter(getAgent, webhookSubscriber) {
|
|
|
148
148
|
}
|
|
149
149
|
});
|
|
150
150
|
return app.openapi(registerRoute, async (ctx) => {
|
|
151
|
-
const agent = getAgent();
|
|
151
|
+
const agent = await getAgent(ctx);
|
|
152
152
|
const { url, secret, description } = ctx.req.valid("json");
|
|
153
153
|
const webhookId = `wh_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
|
|
154
154
|
const webhook = {
|
|
@@ -193,8 +193,8 @@ function createWebhooksRouter(getAgent, webhookSubscriber) {
|
|
|
193
193
|
createdAt: webhook.createdAt
|
|
194
194
|
}
|
|
195
195
|
});
|
|
196
|
-
}).openapi(deleteRoute, (ctx) => {
|
|
197
|
-
const agent = getAgent();
|
|
196
|
+
}).openapi(deleteRoute, async (ctx) => {
|
|
197
|
+
const agent = await getAgent(ctx);
|
|
198
198
|
const { webhookId } = ctx.req.valid("param");
|
|
199
199
|
const removed = webhookSubscriber.removeWebhook(webhookId);
|
|
200
200
|
if (!removed) {
|
|
@@ -203,7 +203,7 @@ function createWebhooksRouter(getAgent, webhookSubscriber) {
|
|
|
203
203
|
agent.logger.info(`Webhook removed: ${webhookId}`);
|
|
204
204
|
return ctx.json({ status: "removed", webhookId });
|
|
205
205
|
}).openapi(testRoute, async (ctx) => {
|
|
206
|
-
const agent = getAgent();
|
|
206
|
+
const agent = await getAgent(ctx);
|
|
207
207
|
const { webhookId } = ctx.req.valid("param");
|
|
208
208
|
const webhook = webhookSubscriber.getWebhook(webhookId);
|
|
209
209
|
if (!webhook) {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { OpenAPIHono } from '@hono/zod-openapi';
|
|
2
2
|
import type { DextoAgent } from '@dexto/core';
|
|
3
3
|
import { WebhookEventSubscriber } from '../../events/webhook-subscriber.js';
|
|
4
|
-
|
|
4
|
+
import type { Context } from 'hono';
|
|
5
|
+
type GetAgentFn = (ctx: Context) => DextoAgent | Promise<DextoAgent>;
|
|
6
|
+
export declare function createWebhooksRouter(getAgent: GetAgentFn, webhookSubscriber: WebhookEventSubscriber): OpenAPIHono<import("hono").Env, {
|
|
5
7
|
"/webhooks": {
|
|
6
8
|
$post: {
|
|
7
9
|
input: {
|
|
@@ -124,4 +126,5 @@ export declare function createWebhooksRouter(getAgent: () => DextoAgent, webhook
|
|
|
124
126
|
};
|
|
125
127
|
};
|
|
126
128
|
}, "/">;
|
|
129
|
+
export {};
|
|
127
130
|
//# sourceMappingURL=webhooks.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/webhooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/webhooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAE5E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACpC,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAkCrE,wBAAgB,oBAAoB,CAChC,QAAQ,EAAE,UAAU,EACpB,iBAAiB,EAAE,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA0N5C"}
|
|
@@ -125,7 +125,7 @@ function createWebhooksRouter(getAgent, webhookSubscriber) {
|
|
|
125
125
|
}
|
|
126
126
|
});
|
|
127
127
|
return app.openapi(registerRoute, async (ctx) => {
|
|
128
|
-
const agent = getAgent();
|
|
128
|
+
const agent = await getAgent(ctx);
|
|
129
129
|
const { url, secret, description } = ctx.req.valid("json");
|
|
130
130
|
const webhookId = `wh_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
|
|
131
131
|
const webhook = {
|
|
@@ -170,8 +170,8 @@ function createWebhooksRouter(getAgent, webhookSubscriber) {
|
|
|
170
170
|
createdAt: webhook.createdAt
|
|
171
171
|
}
|
|
172
172
|
});
|
|
173
|
-
}).openapi(deleteRoute, (ctx) => {
|
|
174
|
-
const agent = getAgent();
|
|
173
|
+
}).openapi(deleteRoute, async (ctx) => {
|
|
174
|
+
const agent = await getAgent(ctx);
|
|
175
175
|
const { webhookId } = ctx.req.valid("param");
|
|
176
176
|
const removed = webhookSubscriber.removeWebhook(webhookId);
|
|
177
177
|
if (!removed) {
|
|
@@ -180,7 +180,7 @@ function createWebhooksRouter(getAgent, webhookSubscriber) {
|
|
|
180
180
|
agent.logger.info(`Webhook removed: ${webhookId}`);
|
|
181
181
|
return ctx.json({ status: "removed", webhookId });
|
|
182
182
|
}).openapi(testRoute, async (ctx) => {
|
|
183
|
-
const agent = getAgent();
|
|
183
|
+
const agent = await getAgent(ctx);
|
|
184
184
|
const { webhookId } = ctx.req.valid("param");
|
|
185
185
|
const webhook = webhookSubscriber.getWebhook(webhookId);
|
|
186
186
|
if (!webhook) {
|
|
@@ -55,6 +55,7 @@ __export(responses_exports, {
|
|
|
55
55
|
ToolCallSchema: () => ToolCallSchema,
|
|
56
56
|
ToolConfirmationConfigSchema: () => import_core6.ToolConfirmationConfigSchema,
|
|
57
57
|
ToolSchema: () => ToolSchema,
|
|
58
|
+
UIResourcePartSchema: () => UIResourcePartSchema,
|
|
58
59
|
WebhookSchema: () => WebhookSchema
|
|
59
60
|
});
|
|
60
61
|
module.exports = __toCommonJS(responses_exports);
|
|
@@ -81,7 +82,26 @@ const FilePartSchema = import_zod.z.object({
|
|
|
81
82
|
mimeType: import_zod.z.string().describe("MIME type of the file"),
|
|
82
83
|
filename: import_zod.z.string().optional().describe("Optional filename")
|
|
83
84
|
}).strict().describe("File content part");
|
|
84
|
-
const
|
|
85
|
+
const UIResourcePartSchema = import_zod.z.object({
|
|
86
|
+
type: import_zod.z.literal("ui-resource").describe("Part type: ui-resource"),
|
|
87
|
+
uri: import_zod.z.string().describe("URI identifying the UI resource (must start with ui://)"),
|
|
88
|
+
mimeType: import_zod.z.string().describe("MIME type: text/html, text/uri-list, or application/vnd.mcp-ui.remote-dom"),
|
|
89
|
+
content: import_zod.z.string().optional().describe("Inline HTML content or URL"),
|
|
90
|
+
blob: import_zod.z.string().optional().describe("Base64-encoded content (alternative to content)"),
|
|
91
|
+
metadata: import_zod.z.object({
|
|
92
|
+
title: import_zod.z.string().optional().describe("Display title for the UI resource"),
|
|
93
|
+
preferredSize: import_zod.z.object({
|
|
94
|
+
width: import_zod.z.number().describe("Preferred width in pixels"),
|
|
95
|
+
height: import_zod.z.number().describe("Preferred height in pixels")
|
|
96
|
+
}).strict().optional().describe("Preferred rendering size")
|
|
97
|
+
}).strict().optional().describe("Optional metadata for the UI resource")
|
|
98
|
+
}).strict().describe("UI Resource content part for MCP-UI interactive components");
|
|
99
|
+
const ContentPartSchema = import_zod.z.discriminatedUnion("type", [
|
|
100
|
+
TextPartSchema,
|
|
101
|
+
ImagePartSchema,
|
|
102
|
+
FilePartSchema,
|
|
103
|
+
UIResourcePartSchema
|
|
104
|
+
]).describe("Message content part (text, image, file, or UI resource)");
|
|
85
105
|
const ToolCallSchema = import_zod.z.object({
|
|
86
106
|
id: import_zod.z.string().describe("Unique identifier for this tool call"),
|
|
87
107
|
type: import_zod.z.literal("function").describe("Tool call type (currently only function is supported)"),
|
|
@@ -105,10 +125,10 @@ const InternalMessageSchema = import_zod.z.object({
|
|
|
105
125
|
tokenUsage: TokenUsageSchema.optional().describe("Optional token usage accounting"),
|
|
106
126
|
model: import_zod.z.string().optional().describe("Model identifier for assistant messages"),
|
|
107
127
|
provider: import_zod.z.enum(import_core.LLM_PROVIDERS).optional().describe("Provider identifier for assistant messages"),
|
|
108
|
-
router: import_zod.z.enum(import_core.LLM_ROUTERS).optional().describe("Router metadata for assistant messages"),
|
|
109
128
|
toolCalls: import_zod.z.array(ToolCallSchema).optional().describe("Tool calls made by the assistant"),
|
|
110
129
|
toolCallId: import_zod.z.string().optional().describe("ID of the tool call this message responds to"),
|
|
111
|
-
name: import_zod.z.string().optional().describe("Name of the tool that produced this result")
|
|
130
|
+
name: import_zod.z.string().optional().describe("Name of the tool that produced this result"),
|
|
131
|
+
success: import_zod.z.boolean().optional().describe("Whether tool execution succeeded (present for role=tool messages)")
|
|
112
132
|
}).strict().describe("Internal message representation");
|
|
113
133
|
const LLMConfigResponseSchema = import_core.LLMConfigBaseSchema.omit({ apiKey: true }).extend({
|
|
114
134
|
hasApiKey: import_zod.z.boolean().optional().describe("Whether an API key is configured")
|
|
@@ -163,7 +183,6 @@ const CatalogModelInfoSchema = import_zod.z.object({
|
|
|
163
183
|
maxInputTokens: import_zod.z.number().int().positive().describe("Maximum input tokens"),
|
|
164
184
|
default: import_zod.z.boolean().optional().describe("Whether this is a default model"),
|
|
165
185
|
supportedFileTypes: import_zod.z.array(import_zod.z.enum(["audio", "pdf", "image"])).describe("File types this model supports"),
|
|
166
|
-
supportedRouters: import_zod.z.array(import_zod.z.enum(["vercel", "in-built"])).optional().describe("Routing strategies this model supports"),
|
|
167
186
|
displayName: import_zod.z.string().optional().describe("Human-readable display name"),
|
|
168
187
|
pricing: import_zod.z.object({
|
|
169
188
|
inputPerM: import_zod.z.number().describe("Input cost per million tokens (USD)"),
|
|
@@ -178,7 +197,6 @@ const ProviderCatalogSchema = import_zod.z.object({
|
|
|
178
197
|
name: import_zod.z.string().describe("Provider display name"),
|
|
179
198
|
hasApiKey: import_zod.z.boolean().describe("Whether API key is configured"),
|
|
180
199
|
primaryEnvVar: import_zod.z.string().describe("Primary environment variable for API key"),
|
|
181
|
-
supportedRouters: import_zod.z.array(import_zod.z.enum(["vercel", "in-built"])).describe("Routing strategies supported by this provider"),
|
|
182
200
|
supportsBaseURL: import_zod.z.boolean().describe("Whether custom base URLs are supported"),
|
|
183
201
|
models: import_zod.z.array(CatalogModelInfoSchema).describe("Models available from this provider"),
|
|
184
202
|
supportedFileTypes: import_zod.z.array(import_zod.z.enum(["audio", "pdf", "image"])).describe("Provider-level file type support")
|
|
@@ -295,5 +313,6 @@ const DeleteResponseSchema = import_zod.z.object({
|
|
|
295
313
|
ToolCallSchema,
|
|
296
314
|
ToolConfirmationConfigSchema,
|
|
297
315
|
ToolSchema,
|
|
316
|
+
UIResourcePartSchema,
|
|
298
317
|
WebhookSchema
|
|
299
318
|
});
|