@dexto/server 1.3.0 → 1.4.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 +2 -2
- package/dist/hono/__tests__/test-fixtures.d.ts.map +1 -1
- package/dist/hono/__tests__/test-fixtures.js +2 -2
- package/dist/hono/index.cjs +6 -1
- package/dist/hono/index.d.ts +433 -88
- package/dist/hono/index.d.ts.map +1 -1
- package/dist/hono/index.js +6 -1
- package/dist/hono/middleware/error.d.ts.map +1 -1
- package/dist/hono/routes/agents.cjs +8 -10
- package/dist/hono/routes/agents.d.ts +15 -8
- package/dist/hono/routes/agents.d.ts.map +1 -1
- package/dist/hono/routes/agents.js +10 -10
- package/dist/hono/routes/approvals.cjs +52 -1
- package/dist/hono/routes/approvals.d.ts +25 -0
- package/dist/hono/routes/approvals.d.ts.map +1 -1
- package/dist/hono/routes/approvals.js +52 -1
- package/dist/hono/routes/llm.cjs +110 -31
- package/dist/hono/routes/llm.d.ts +72 -20
- package/dist/hono/routes/llm.d.ts.map +1 -1
- package/dist/hono/routes/llm.js +108 -25
- package/dist/hono/routes/mcp.cjs +8 -4
- package/dist/hono/routes/mcp.d.ts +4 -1
- package/dist/hono/routes/mcp.d.ts.map +1 -1
- package/dist/hono/routes/mcp.js +9 -5
- package/dist/hono/routes/memory.d.ts +1 -1
- package/dist/hono/routes/messages.cjs +54 -62
- package/dist/hono/routes/messages.d.ts +87 -43
- package/dist/hono/routes/messages.d.ts.map +1 -1
- package/dist/hono/routes/messages.js +55 -63
- package/dist/hono/routes/prompts.d.ts +6 -6
- package/dist/hono/routes/queue.cjs +202 -0
- package/dist/hono/routes/queue.d.ts +171 -0
- package/dist/hono/routes/queue.d.ts.map +1 -0
- package/dist/hono/routes/queue.js +178 -0
- package/dist/hono/routes/resources.d.ts +1 -1
- package/dist/hono/routes/search.d.ts +33 -7
- package/dist/hono/routes/search.d.ts.map +1 -1
- package/dist/hono/routes/sessions.cjs +65 -11
- package/dist/hono/routes/sessions.d.ts +22 -1
- package/dist/hono/routes/sessions.d.ts.map +1 -1
- package/dist/hono/routes/sessions.js +65 -11
- package/dist/hono/schemas/responses.cjs +24 -5
- package/dist/hono/schemas/responses.d.ts +799 -81
- package/dist/hono/schemas/responses.d.ts.map +1 -1
- package/dist/hono/schemas/responses.js +24 -10
- package/package.json +3 -3
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
|
|
2
|
+
import { ContentPartSchema } from "../schemas/responses.js";
|
|
3
|
+
const QueuedMessageSchema = z.object({
|
|
4
|
+
id: z.string().describe("Unique identifier for the queued message"),
|
|
5
|
+
content: z.array(ContentPartSchema).describe("Message content parts"),
|
|
6
|
+
queuedAt: z.number().describe("Unix timestamp when message was queued"),
|
|
7
|
+
metadata: z.record(z.unknown()).optional().describe("Optional metadata")
|
|
8
|
+
}).strict().describe("A message waiting in the queue");
|
|
9
|
+
const TextPartSchema = z.object({
|
|
10
|
+
type: z.literal("text").describe("Content type identifier"),
|
|
11
|
+
text: z.string().describe("Text content")
|
|
12
|
+
}).describe("Text content part");
|
|
13
|
+
const ImagePartSchema = z.object({
|
|
14
|
+
type: z.literal("image").describe("Content type identifier"),
|
|
15
|
+
image: z.string().describe("Base64-encoded image data or URL"),
|
|
16
|
+
mimeType: z.string().optional().describe("MIME type (e.g., image/png)")
|
|
17
|
+
}).describe("Image content part");
|
|
18
|
+
const FilePartSchema = z.object({
|
|
19
|
+
type: z.literal("file").describe("Content type identifier"),
|
|
20
|
+
data: z.string().describe("Base64-encoded file data or URL"),
|
|
21
|
+
mimeType: z.string().describe("MIME type (e.g., application/pdf)"),
|
|
22
|
+
filename: z.string().optional().describe("Optional filename")
|
|
23
|
+
}).describe("File content part");
|
|
24
|
+
const QueueContentPartSchema = z.discriminatedUnion("type", [TextPartSchema, ImagePartSchema, FilePartSchema]).describe("Content part - text, image, or file");
|
|
25
|
+
const QueueMessageBodySchema = z.object({
|
|
26
|
+
content: z.union([z.string(), z.array(QueueContentPartSchema)]).describe("Message content - string for text, or ContentPart[] for multimodal")
|
|
27
|
+
}).describe("Request body for queueing a message");
|
|
28
|
+
function createQueueRouter(getAgent) {
|
|
29
|
+
const app = new OpenAPIHono();
|
|
30
|
+
const getQueueRoute = createRoute({
|
|
31
|
+
method: "get",
|
|
32
|
+
path: "/queue/{sessionId}",
|
|
33
|
+
summary: "Get queued messages",
|
|
34
|
+
description: "Returns all messages waiting in the queue for a session",
|
|
35
|
+
tags: ["queue"],
|
|
36
|
+
request: {
|
|
37
|
+
params: z.object({
|
|
38
|
+
sessionId: z.string().min(1).describe("Session ID")
|
|
39
|
+
})
|
|
40
|
+
},
|
|
41
|
+
responses: {
|
|
42
|
+
200: {
|
|
43
|
+
description: "List of queued messages",
|
|
44
|
+
content: {
|
|
45
|
+
"application/json": {
|
|
46
|
+
schema: z.object({
|
|
47
|
+
messages: z.array(QueuedMessageSchema).describe("Queued messages"),
|
|
48
|
+
count: z.number().describe("Number of messages in queue")
|
|
49
|
+
}).strict()
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
404: { description: "Session not found" }
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
const queueMessageRoute = createRoute({
|
|
57
|
+
method: "post",
|
|
58
|
+
path: "/queue/{sessionId}",
|
|
59
|
+
summary: "Queue a message",
|
|
60
|
+
description: "Adds a message to the queue for processing when the session is no longer busy",
|
|
61
|
+
tags: ["queue"],
|
|
62
|
+
request: {
|
|
63
|
+
params: z.object({
|
|
64
|
+
sessionId: z.string().min(1).describe("Session ID")
|
|
65
|
+
}),
|
|
66
|
+
body: {
|
|
67
|
+
content: { "application/json": { schema: QueueMessageBodySchema } }
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
responses: {
|
|
71
|
+
201: {
|
|
72
|
+
description: "Message queued successfully",
|
|
73
|
+
content: {
|
|
74
|
+
"application/json": {
|
|
75
|
+
schema: z.object({
|
|
76
|
+
queued: z.literal(true).describe("Indicates message was queued"),
|
|
77
|
+
id: z.string().describe("ID of the queued message"),
|
|
78
|
+
position: z.number().describe("Position in the queue (1-based)")
|
|
79
|
+
}).strict()
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
404: { description: "Session not found" }
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
const removeQueuedMessageRoute = createRoute({
|
|
87
|
+
method: "delete",
|
|
88
|
+
path: "/queue/{sessionId}/{messageId}",
|
|
89
|
+
summary: "Remove queued message",
|
|
90
|
+
description: "Removes a specific message from the queue",
|
|
91
|
+
tags: ["queue"],
|
|
92
|
+
request: {
|
|
93
|
+
params: z.object({
|
|
94
|
+
sessionId: z.string().min(1).describe("Session ID"),
|
|
95
|
+
messageId: z.string().min(1).describe("ID of the queued message to remove")
|
|
96
|
+
})
|
|
97
|
+
},
|
|
98
|
+
responses: {
|
|
99
|
+
200: {
|
|
100
|
+
description: "Message removed successfully",
|
|
101
|
+
content: {
|
|
102
|
+
"application/json": {
|
|
103
|
+
schema: z.object({
|
|
104
|
+
removed: z.literal(true).describe("Indicates message was removed"),
|
|
105
|
+
id: z.string().describe("ID of the removed message")
|
|
106
|
+
}).strict()
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
404: { description: "Session or message not found" }
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
const clearQueueRoute = createRoute({
|
|
114
|
+
method: "delete",
|
|
115
|
+
path: "/queue/{sessionId}",
|
|
116
|
+
summary: "Clear message queue",
|
|
117
|
+
description: "Removes all messages from the queue for a session",
|
|
118
|
+
tags: ["queue"],
|
|
119
|
+
request: {
|
|
120
|
+
params: z.object({
|
|
121
|
+
sessionId: z.string().min(1).describe("Session ID")
|
|
122
|
+
})
|
|
123
|
+
},
|
|
124
|
+
responses: {
|
|
125
|
+
200: {
|
|
126
|
+
description: "Queue cleared successfully",
|
|
127
|
+
content: {
|
|
128
|
+
"application/json": {
|
|
129
|
+
schema: z.object({
|
|
130
|
+
cleared: z.literal(true).describe("Indicates queue was cleared"),
|
|
131
|
+
count: z.number().describe("Number of messages that were removed")
|
|
132
|
+
}).strict()
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
404: { description: "Session not found" }
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
return app.openapi(getQueueRoute, async (ctx) => {
|
|
140
|
+
const agent = getAgent();
|
|
141
|
+
const { sessionId } = ctx.req.valid("param");
|
|
142
|
+
const messages = await agent.getQueuedMessages(sessionId);
|
|
143
|
+
return ctx.json({
|
|
144
|
+
messages,
|
|
145
|
+
count: messages.length
|
|
146
|
+
});
|
|
147
|
+
}).openapi(queueMessageRoute, async (ctx) => {
|
|
148
|
+
const agent = getAgent();
|
|
149
|
+
const { sessionId } = ctx.req.valid("param");
|
|
150
|
+
const { content: rawContent } = ctx.req.valid("json");
|
|
151
|
+
const content = typeof rawContent === "string" ? [{ type: "text", text: rawContent }] : rawContent;
|
|
152
|
+
const result = await agent.queueMessage(sessionId, { content });
|
|
153
|
+
return ctx.json(
|
|
154
|
+
{
|
|
155
|
+
queued: result.queued,
|
|
156
|
+
id: result.id,
|
|
157
|
+
position: result.position
|
|
158
|
+
},
|
|
159
|
+
201
|
|
160
|
+
);
|
|
161
|
+
}).openapi(removeQueuedMessageRoute, async (ctx) => {
|
|
162
|
+
const agent = getAgent();
|
|
163
|
+
const { sessionId, messageId } = ctx.req.valid("param");
|
|
164
|
+
const removed = await agent.removeQueuedMessage(sessionId, messageId);
|
|
165
|
+
if (!removed) {
|
|
166
|
+
return ctx.json({ error: "Message not found in queue" }, 404);
|
|
167
|
+
}
|
|
168
|
+
return ctx.json({ removed: true, id: messageId });
|
|
169
|
+
}).openapi(clearQueueRoute, async (ctx) => {
|
|
170
|
+
const agent = getAgent();
|
|
171
|
+
const { sessionId } = ctx.req.valid("param");
|
|
172
|
+
const count = await agent.clearMessageQueue(sessionId);
|
|
173
|
+
return ctx.json({ cleared: true, count });
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
export {
|
|
177
|
+
createQueueRouter
|
|
178
|
+
};
|
|
@@ -11,10 +11,10 @@ export declare function createResourcesRouter(getAgent: () => DextoAgent): OpenA
|
|
|
11
11
|
source: "mcp" | "internal";
|
|
12
12
|
description?: string | undefined;
|
|
13
13
|
mimeType?: string | undefined;
|
|
14
|
-
name?: string | undefined;
|
|
15
14
|
metadata?: {
|
|
16
15
|
[x: string]: import("hono/utils/types").JSONValue;
|
|
17
16
|
} | undefined;
|
|
17
|
+
name?: string | undefined;
|
|
18
18
|
serverName?: string | undefined;
|
|
19
19
|
size?: number | undefined;
|
|
20
20
|
lastModified?: string | undefined;
|
|
@@ -28,6 +28,19 @@ export declare function createSearchRouter(getAgent: () => DextoAgent): OpenAPIH
|
|
|
28
28
|
mimeType: string;
|
|
29
29
|
data: string;
|
|
30
30
|
filename?: string | undefined;
|
|
31
|
+
} | {
|
|
32
|
+
type: "ui-resource";
|
|
33
|
+
mimeType: string;
|
|
34
|
+
uri: string;
|
|
35
|
+
content?: string | undefined;
|
|
36
|
+
blob?: string | undefined;
|
|
37
|
+
metadata?: {
|
|
38
|
+
title?: string | undefined;
|
|
39
|
+
preferredSize?: {
|
|
40
|
+
width: number;
|
|
41
|
+
height: number;
|
|
42
|
+
} | undefined;
|
|
43
|
+
} | undefined;
|
|
31
44
|
})[] | null;
|
|
32
45
|
role: "system" | "user" | "assistant" | "tool";
|
|
33
46
|
id?: string | undefined;
|
|
@@ -42,7 +55,6 @@ export declare function createSearchRouter(getAgent: () => DextoAgent): OpenAPIH
|
|
|
42
55
|
} | undefined;
|
|
43
56
|
model?: string | undefined;
|
|
44
57
|
provider?: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | undefined;
|
|
45
|
-
router?: "vercel" | "in-built" | undefined;
|
|
46
58
|
toolCalls?: {
|
|
47
59
|
function: {
|
|
48
60
|
name: string;
|
|
@@ -52,6 +64,7 @@ export declare function createSearchRouter(getAgent: () => DextoAgent): OpenAPIH
|
|
|
52
64
|
id: string;
|
|
53
65
|
}[] | undefined;
|
|
54
66
|
toolCallId?: string | undefined;
|
|
67
|
+
success?: boolean | undefined;
|
|
55
68
|
};
|
|
56
69
|
sessionId: string;
|
|
57
70
|
matchedText: string;
|
|
@@ -77,6 +90,11 @@ export declare function createSearchRouter(getAgent: () => DextoAgent): OpenAPIH
|
|
|
77
90
|
query: string;
|
|
78
91
|
results: {
|
|
79
92
|
sessionId: string;
|
|
93
|
+
metadata: {
|
|
94
|
+
createdAt: number;
|
|
95
|
+
lastActivity: number;
|
|
96
|
+
messageCount: number;
|
|
97
|
+
};
|
|
80
98
|
matchCount: number;
|
|
81
99
|
firstMatch: {
|
|
82
100
|
message: {
|
|
@@ -92,6 +110,19 @@ export declare function createSearchRouter(getAgent: () => DextoAgent): OpenAPIH
|
|
|
92
110
|
mimeType: string;
|
|
93
111
|
data: string;
|
|
94
112
|
filename?: string | undefined;
|
|
113
|
+
} | {
|
|
114
|
+
type: "ui-resource";
|
|
115
|
+
mimeType: string;
|
|
116
|
+
uri: string;
|
|
117
|
+
content?: string | undefined;
|
|
118
|
+
blob?: string | undefined;
|
|
119
|
+
metadata?: {
|
|
120
|
+
title?: string | undefined;
|
|
121
|
+
preferredSize?: {
|
|
122
|
+
width: number;
|
|
123
|
+
height: number;
|
|
124
|
+
} | undefined;
|
|
125
|
+
} | undefined;
|
|
95
126
|
})[] | null;
|
|
96
127
|
role: "system" | "user" | "assistant" | "tool";
|
|
97
128
|
id?: string | undefined;
|
|
@@ -106,7 +137,6 @@ export declare function createSearchRouter(getAgent: () => DextoAgent): OpenAPIH
|
|
|
106
137
|
} | undefined;
|
|
107
138
|
model?: string | undefined;
|
|
108
139
|
provider?: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | undefined;
|
|
109
|
-
router?: "vercel" | "in-built" | undefined;
|
|
110
140
|
toolCalls?: {
|
|
111
141
|
function: {
|
|
112
142
|
name: string;
|
|
@@ -116,17 +146,13 @@ export declare function createSearchRouter(getAgent: () => DextoAgent): OpenAPIH
|
|
|
116
146
|
id: string;
|
|
117
147
|
}[] | undefined;
|
|
118
148
|
toolCallId?: string | undefined;
|
|
149
|
+
success?: boolean | undefined;
|
|
119
150
|
};
|
|
120
151
|
sessionId: string;
|
|
121
152
|
matchedText: string;
|
|
122
153
|
context: string;
|
|
123
154
|
messageIndex: number;
|
|
124
155
|
};
|
|
125
|
-
metadata: {
|
|
126
|
-
createdAt: number;
|
|
127
|
-
lastActivity: number;
|
|
128
|
-
messageCount: number;
|
|
129
|
-
};
|
|
130
156
|
}[];
|
|
131
157
|
total: number;
|
|
132
158
|
hasMore: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA2B9C,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,UAAU
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA2B9C,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAwD5D"}
|
|
@@ -95,7 +95,7 @@ function createSessionsRouter(getAgent) {
|
|
|
95
95
|
method: "get",
|
|
96
96
|
path: "/sessions/{sessionId}/history",
|
|
97
97
|
summary: "Get Session History",
|
|
98
|
-
description: "Retrieves the conversation history for a session",
|
|
98
|
+
description: "Retrieves the conversation history for a session along with processing status",
|
|
99
99
|
tags: ["sessions"],
|
|
100
100
|
request: { params: import_zod_openapi.z.object({ sessionId: import_zod_openapi.z.string().describe("Session identifier") }) },
|
|
101
101
|
responses: {
|
|
@@ -104,7 +104,10 @@ function createSessionsRouter(getAgent) {
|
|
|
104
104
|
content: {
|
|
105
105
|
"application/json": {
|
|
106
106
|
schema: import_zod_openapi.z.object({
|
|
107
|
-
history: import_zod_openapi.z.array(import_responses.InternalMessageSchema).describe("Array of messages in conversation history")
|
|
107
|
+
history: import_zod_openapi.z.array(import_responses.InternalMessageSchema).describe("Array of messages in conversation history"),
|
|
108
|
+
isBusy: import_zod_openapi.z.boolean().describe(
|
|
109
|
+
"Whether the session is currently processing a message"
|
|
110
|
+
)
|
|
108
111
|
}).strict()
|
|
109
112
|
}
|
|
110
113
|
}
|
|
@@ -136,9 +139,23 @@ function createSessionsRouter(getAgent) {
|
|
|
136
139
|
method: "post",
|
|
137
140
|
path: "/sessions/{sessionId}/cancel",
|
|
138
141
|
summary: "Cancel Session Run",
|
|
139
|
-
description: "Cancels an in-flight agent run for the specified session",
|
|
142
|
+
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.",
|
|
140
143
|
tags: ["sessions"],
|
|
141
|
-
request: {
|
|
144
|
+
request: {
|
|
145
|
+
params: import_zod_openapi.z.object({ sessionId: import_zod_openapi.z.string().describe("Session identifier") }),
|
|
146
|
+
body: {
|
|
147
|
+
content: {
|
|
148
|
+
"application/json": {
|
|
149
|
+
schema: import_zod_openapi.z.object({
|
|
150
|
+
clearQueue: import_zod_openapi.z.boolean().optional().default(false).describe(
|
|
151
|
+
"If true (hard cancel), clears queued messages. If false (soft cancel, default), queued messages continue processing."
|
|
152
|
+
)
|
|
153
|
+
}).strict()
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
required: false
|
|
157
|
+
}
|
|
158
|
+
},
|
|
142
159
|
responses: {
|
|
143
160
|
200: {
|
|
144
161
|
description: "Cancel operation result",
|
|
@@ -146,7 +163,11 @@ function createSessionsRouter(getAgent) {
|
|
|
146
163
|
"application/json": {
|
|
147
164
|
schema: import_zod_openapi.z.object({
|
|
148
165
|
cancelled: import_zod_openapi.z.boolean().describe("Whether a run was cancelled"),
|
|
149
|
-
sessionId: import_zod_openapi.z.string().describe("Session ID")
|
|
166
|
+
sessionId: import_zod_openapi.z.string().describe("Session ID"),
|
|
167
|
+
queueCleared: import_zod_openapi.z.boolean().describe("Whether queued messages were cleared"),
|
|
168
|
+
clearedCount: import_zod_openapi.z.number().describe(
|
|
169
|
+
"Number of queued messages cleared (0 if soft cancel)"
|
|
170
|
+
)
|
|
150
171
|
}).strict()
|
|
151
172
|
}
|
|
152
173
|
}
|
|
@@ -157,7 +178,7 @@ function createSessionsRouter(getAgent) {
|
|
|
157
178
|
method: "get",
|
|
158
179
|
path: "/sessions/{sessionId}/load",
|
|
159
180
|
summary: "Load Session",
|
|
160
|
-
description: "Validates and retrieves session information. The client should track the active session.",
|
|
181
|
+
description: "Validates and retrieves session information including processing status. The client should track the active session.",
|
|
161
182
|
tags: ["sessions"],
|
|
162
183
|
request: {
|
|
163
184
|
params: import_zod_openapi.z.object({ sessionId: import_zod_openapi.z.string().describe("Session identifier") })
|
|
@@ -168,7 +189,11 @@ function createSessionsRouter(getAgent) {
|
|
|
168
189
|
content: {
|
|
169
190
|
"application/json": {
|
|
170
191
|
schema: import_zod_openapi.z.object({
|
|
171
|
-
session: import_responses.SessionMetadataSchema.
|
|
192
|
+
session: import_responses.SessionMetadataSchema.extend({
|
|
193
|
+
isBusy: import_zod_openapi.z.boolean().describe(
|
|
194
|
+
"Whether the session is currently processing a message"
|
|
195
|
+
)
|
|
196
|
+
}).describe("Session metadata with processing status")
|
|
172
197
|
}).strict()
|
|
173
198
|
}
|
|
174
199
|
}
|
|
@@ -303,8 +328,14 @@ function createSessionsRouter(getAgent) {
|
|
|
303
328
|
}).openapi(historyRoute, async (ctx) => {
|
|
304
329
|
const agent = getAgent();
|
|
305
330
|
const { sessionId } = ctx.req.param();
|
|
306
|
-
const history = await
|
|
307
|
-
|
|
331
|
+
const [history, isBusy] = await Promise.all([
|
|
332
|
+
agent.getSessionHistory(sessionId),
|
|
333
|
+
agent.isSessionBusy(sessionId)
|
|
334
|
+
]);
|
|
335
|
+
return ctx.json({
|
|
336
|
+
history,
|
|
337
|
+
isBusy
|
|
338
|
+
});
|
|
308
339
|
}).openapi(deleteRoute, async (ctx) => {
|
|
309
340
|
const agent = getAgent();
|
|
310
341
|
const { sessionId } = ctx.req.param();
|
|
@@ -313,11 +344,32 @@ function createSessionsRouter(getAgent) {
|
|
|
313
344
|
}).openapi(cancelRoute, async (ctx) => {
|
|
314
345
|
const agent = getAgent();
|
|
315
346
|
const { sessionId } = ctx.req.valid("param");
|
|
347
|
+
let clearQueue = false;
|
|
348
|
+
try {
|
|
349
|
+
const body = ctx.req.valid("json");
|
|
350
|
+
clearQueue = body?.clearQueue ?? false;
|
|
351
|
+
} catch {
|
|
352
|
+
}
|
|
353
|
+
let clearedCount = 0;
|
|
354
|
+
if (clearQueue) {
|
|
355
|
+
try {
|
|
356
|
+
clearedCount = await agent.clearMessageQueue(sessionId);
|
|
357
|
+
agent.logger.debug(
|
|
358
|
+
`Hard cancel: cleared ${clearedCount} queued message(s) for session: ${sessionId}`
|
|
359
|
+
);
|
|
360
|
+
} catch {
|
|
361
|
+
}
|
|
362
|
+
}
|
|
316
363
|
const cancelled = await agent.cancel(sessionId);
|
|
317
364
|
if (!cancelled) {
|
|
318
365
|
agent.logger.debug(`No in-flight run to cancel for session: ${sessionId}`);
|
|
319
366
|
}
|
|
320
|
-
return ctx.json({
|
|
367
|
+
return ctx.json({
|
|
368
|
+
cancelled,
|
|
369
|
+
sessionId,
|
|
370
|
+
queueCleared: clearQueue,
|
|
371
|
+
clearedCount
|
|
372
|
+
});
|
|
321
373
|
}).openapi(loadRoute, async (ctx) => {
|
|
322
374
|
const agent = getAgent();
|
|
323
375
|
const { sessionId } = ctx.req.valid("param");
|
|
@@ -326,6 +378,7 @@ function createSessionsRouter(getAgent) {
|
|
|
326
378
|
return ctx.json({ error: `Session not found: ${sessionId}` }, 404);
|
|
327
379
|
}
|
|
328
380
|
const metadata = await agent.getSessionMetadata(sessionId);
|
|
381
|
+
const isBusy = await agent.isSessionBusy(sessionId);
|
|
329
382
|
return ctx.json(
|
|
330
383
|
{
|
|
331
384
|
session: {
|
|
@@ -333,7 +386,8 @@ function createSessionsRouter(getAgent) {
|
|
|
333
386
|
createdAt: metadata?.createdAt || null,
|
|
334
387
|
lastActivity: metadata?.lastActivity || null,
|
|
335
388
|
messageCount: metadata?.messageCount || 0,
|
|
336
|
-
title: metadata?.title || null
|
|
389
|
+
title: metadata?.title || null,
|
|
390
|
+
isBusy
|
|
337
391
|
}
|
|
338
392
|
},
|
|
339
393
|
200
|
|
@@ -82,6 +82,19 @@ export declare function createSessionsRouter(getAgent: () => DextoAgent): OpenAP
|
|
|
82
82
|
mimeType: string;
|
|
83
83
|
data: string;
|
|
84
84
|
filename?: string | undefined;
|
|
85
|
+
} | {
|
|
86
|
+
type: "ui-resource";
|
|
87
|
+
mimeType: string;
|
|
88
|
+
uri: string;
|
|
89
|
+
content?: string | undefined;
|
|
90
|
+
blob?: string | undefined;
|
|
91
|
+
metadata?: {
|
|
92
|
+
title?: string | undefined;
|
|
93
|
+
preferredSize?: {
|
|
94
|
+
width: number;
|
|
95
|
+
height: number;
|
|
96
|
+
} | undefined;
|
|
97
|
+
} | undefined;
|
|
85
98
|
})[] | null;
|
|
86
99
|
role: "system" | "user" | "assistant" | "tool";
|
|
87
100
|
id?: string | undefined;
|
|
@@ -96,7 +109,6 @@ export declare function createSessionsRouter(getAgent: () => DextoAgent): OpenAP
|
|
|
96
109
|
} | undefined;
|
|
97
110
|
model?: string | undefined;
|
|
98
111
|
provider?: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | undefined;
|
|
99
|
-
router?: "vercel" | "in-built" | undefined;
|
|
100
112
|
toolCalls?: {
|
|
101
113
|
function: {
|
|
102
114
|
name: string;
|
|
@@ -106,7 +118,9 @@ export declare function createSessionsRouter(getAgent: () => DextoAgent): OpenAP
|
|
|
106
118
|
id: string;
|
|
107
119
|
}[] | undefined;
|
|
108
120
|
toolCallId?: string | undefined;
|
|
121
|
+
success?: boolean | undefined;
|
|
109
122
|
}[];
|
|
123
|
+
isBusy: boolean;
|
|
110
124
|
};
|
|
111
125
|
outputFormat: "json";
|
|
112
126
|
status: 200;
|
|
@@ -135,10 +149,16 @@ export declare function createSessionsRouter(getAgent: () => DextoAgent): OpenAP
|
|
|
135
149
|
param: {
|
|
136
150
|
sessionId: string;
|
|
137
151
|
};
|
|
152
|
+
} & {
|
|
153
|
+
json: {
|
|
154
|
+
clearQueue?: boolean | undefined;
|
|
155
|
+
};
|
|
138
156
|
};
|
|
139
157
|
output: {
|
|
140
158
|
sessionId: string;
|
|
141
159
|
cancelled: boolean;
|
|
160
|
+
queueCleared: boolean;
|
|
161
|
+
clearedCount: number;
|
|
142
162
|
};
|
|
143
163
|
outputFormat: "json";
|
|
144
164
|
status: 200;
|
|
@@ -158,6 +178,7 @@ export declare function createSessionsRouter(getAgent: () => DextoAgent): OpenAP
|
|
|
158
178
|
createdAt: number | null;
|
|
159
179
|
lastActivity: number | null;
|
|
160
180
|
messageCount: number;
|
|
181
|
+
isBusy: boolean;
|
|
161
182
|
title?: string | null | undefined;
|
|
162
183
|
};
|
|
163
184
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/sessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAS9C,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,UAAU
|
|
1
|
+
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/sessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAS9C,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAie9D"}
|
|
@@ -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
|
}
|
|
@@ -280,8 +305,14 @@ function createSessionsRouter(getAgent) {
|
|
|
280
305
|
}).openapi(historyRoute, async (ctx) => {
|
|
281
306
|
const agent = getAgent();
|
|
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
317
|
const agent = getAgent();
|
|
287
318
|
const { sessionId } = ctx.req.param();
|
|
@@ -290,11 +321,32 @@ function createSessionsRouter(getAgent) {
|
|
|
290
321
|
}).openapi(cancelRoute, async (ctx) => {
|
|
291
322
|
const agent = getAgent();
|
|
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
351
|
const agent = getAgent();
|
|
300
352
|
const { sessionId } = ctx.req.valid("param");
|
|
@@ -303,6 +355,7 @@ function createSessionsRouter(getAgent) {
|
|
|
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,7 +363,8 @@ 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
|