@dexto/server 1.2.6 → 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.
Files changed (60) hide show
  1. package/dist/approval/manual-approval-handler.cjs +23 -15
  2. package/dist/approval/manual-approval-handler.d.ts.map +1 -1
  3. package/dist/approval/manual-approval-handler.js +23 -15
  4. package/dist/events/webhook-subscriber.cjs +1 -1
  5. package/dist/events/webhook-subscriber.d.ts.map +1 -1
  6. package/dist/events/webhook-subscriber.js +1 -1
  7. package/dist/hono/__tests__/test-fixtures.cjs +2 -2
  8. package/dist/hono/__tests__/test-fixtures.d.ts.map +1 -1
  9. package/dist/hono/__tests__/test-fixtures.js +2 -2
  10. package/dist/hono/index.cjs +14 -2
  11. package/dist/hono/index.d.ts +486 -132
  12. package/dist/hono/index.d.ts.map +1 -1
  13. package/dist/hono/index.js +17 -2
  14. package/dist/hono/middleware/error.d.ts.map +1 -1
  15. package/dist/hono/routes/agents.cjs +8 -10
  16. package/dist/hono/routes/agents.d.ts +15 -8
  17. package/dist/hono/routes/agents.d.ts.map +1 -1
  18. package/dist/hono/routes/agents.js +10 -10
  19. package/dist/hono/routes/approvals.cjs +52 -1
  20. package/dist/hono/routes/approvals.d.ts +25 -0
  21. package/dist/hono/routes/approvals.d.ts.map +1 -1
  22. package/dist/hono/routes/approvals.js +52 -1
  23. package/dist/hono/routes/llm.cjs +110 -31
  24. package/dist/hono/routes/llm.d.ts +89 -37
  25. package/dist/hono/routes/llm.d.ts.map +1 -1
  26. package/dist/hono/routes/llm.js +108 -25
  27. package/dist/hono/routes/mcp.cjs +8 -4
  28. package/dist/hono/routes/mcp.d.ts +4 -1
  29. package/dist/hono/routes/mcp.d.ts.map +1 -1
  30. package/dist/hono/routes/mcp.js +9 -5
  31. package/dist/hono/routes/memory.d.ts +1 -1
  32. package/dist/hono/routes/messages.cjs +56 -64
  33. package/dist/hono/routes/messages.d.ts +101 -57
  34. package/dist/hono/routes/messages.d.ts.map +1 -1
  35. package/dist/hono/routes/messages.js +57 -65
  36. package/dist/hono/routes/prompts.cjs +2 -2
  37. package/dist/hono/routes/prompts.d.ts +7 -7
  38. package/dist/hono/routes/prompts.js +2 -2
  39. package/dist/hono/routes/queue.cjs +202 -0
  40. package/dist/hono/routes/queue.d.ts +171 -0
  41. package/dist/hono/routes/queue.d.ts.map +1 -0
  42. package/dist/hono/routes/queue.js +178 -0
  43. package/dist/hono/routes/resources.d.ts +1 -1
  44. package/dist/hono/routes/search.cjs +2 -24
  45. package/dist/hono/routes/search.d.ts +43 -15
  46. package/dist/hono/routes/search.d.ts.map +1 -1
  47. package/dist/hono/routes/search.js +3 -25
  48. package/dist/hono/routes/sessions.cjs +65 -11
  49. package/dist/hono/routes/sessions.d.ts +27 -5
  50. package/dist/hono/routes/sessions.d.ts.map +1 -1
  51. package/dist/hono/routes/sessions.js +65 -11
  52. package/dist/hono/routes/static.cjs +77 -0
  53. package/dist/hono/routes/static.d.ts +41 -0
  54. package/dist/hono/routes/static.d.ts.map +1 -0
  55. package/dist/hono/routes/static.js +52 -0
  56. package/dist/hono/schemas/responses.cjs +67 -25
  57. package/dist/hono/schemas/responses.d.ts +2076 -354
  58. package/dist/hono/schemas/responses.d.ts.map +1 -1
  59. package/dist/hono/schemas/responses.js +69 -35
  60. package/package.json +3 -3
@@ -21,18 +21,29 @@ export declare function createSearchRouter(getAgent: () => DextoAgent): OpenAPIH
21
21
  text: string;
22
22
  } | {
23
23
  type: "image";
24
- image?: import("hono/utils/types").JSONValue;
24
+ image: string;
25
25
  mimeType?: string | undefined;
26
26
  } | {
27
27
  type: "file";
28
28
  mimeType: string;
29
- data?: import("hono/utils/types").JSONValue;
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
- provider?: string | undefined;
34
- model?: string | undefined;
35
- router?: string | undefined;
46
+ id?: string | undefined;
36
47
  name?: string | undefined;
37
48
  timestamp?: number | undefined;
38
49
  reasoning?: string | undefined;
@@ -42,6 +53,8 @@ export declare function createSearchRouter(getAgent: () => DextoAgent): OpenAPIH
42
53
  reasoningTokens?: number | undefined;
43
54
  totalTokens?: number | undefined;
44
55
  } | undefined;
56
+ model?: string | undefined;
57
+ provider?: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | undefined;
45
58
  toolCalls?: {
46
59
  function: {
47
60
  name: string;
@@ -51,6 +64,7 @@ export declare function createSearchRouter(getAgent: () => DextoAgent): OpenAPIH
51
64
  id: string;
52
65
  }[] | undefined;
53
66
  toolCallId?: string | undefined;
67
+ success?: boolean | undefined;
54
68
  };
55
69
  sessionId: string;
56
70
  matchedText: string;
@@ -76,6 +90,11 @@ export declare function createSearchRouter(getAgent: () => DextoAgent): OpenAPIH
76
90
  query: string;
77
91
  results: {
78
92
  sessionId: string;
93
+ metadata: {
94
+ createdAt: number;
95
+ lastActivity: number;
96
+ messageCount: number;
97
+ };
79
98
  matchCount: number;
80
99
  firstMatch: {
81
100
  message: {
@@ -84,18 +103,29 @@ export declare function createSearchRouter(getAgent: () => DextoAgent): OpenAPIH
84
103
  text: string;
85
104
  } | {
86
105
  type: "image";
87
- image?: import("hono/utils/types").JSONValue;
106
+ image: string;
88
107
  mimeType?: string | undefined;
89
108
  } | {
90
109
  type: "file";
91
110
  mimeType: string;
92
- data?: import("hono/utils/types").JSONValue;
111
+ data: string;
93
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;
94
126
  })[] | null;
95
127
  role: "system" | "user" | "assistant" | "tool";
96
- provider?: string | undefined;
97
- model?: string | undefined;
98
- router?: string | undefined;
128
+ id?: string | undefined;
99
129
  name?: string | undefined;
100
130
  timestamp?: number | undefined;
101
131
  reasoning?: string | undefined;
@@ -105,6 +135,8 @@ export declare function createSearchRouter(getAgent: () => DextoAgent): OpenAPIH
105
135
  reasoningTokens?: number | undefined;
106
136
  totalTokens?: number | undefined;
107
137
  } | undefined;
138
+ model?: string | undefined;
139
+ provider?: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | undefined;
108
140
  toolCalls?: {
109
141
  function: {
110
142
  name: string;
@@ -114,17 +146,13 @@ export declare function createSearchRouter(getAgent: () => DextoAgent): OpenAPIH
114
146
  id: string;
115
147
  }[] | undefined;
116
148
  toolCallId?: string | undefined;
149
+ success?: boolean | undefined;
117
150
  };
118
151
  sessionId: string;
119
152
  matchedText: string;
120
153
  context: string;
121
154
  messageIndex: number;
122
155
  };
123
- metadata: {
124
- createdAt: number;
125
- lastActivity: number;
126
- messageCount: number;
127
- };
128
156
  }[];
129
157
  total: number;
130
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAiG5D"}
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"}
@@ -1,5 +1,5 @@
1
1
  import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
2
- import { SearchResultSchema, SessionSearchResultSchema } from "../schemas/responses.js";
2
+ import { MessageSearchResponseSchema, SessionSearchResponseSchema } from "../schemas/responses.js";
3
3
  const MessageSearchQuery = z.object({
4
4
  q: z.string().min(1, "Search query is required").describe("Search query string"),
5
5
  limit: z.coerce.number().min(1).max(100).optional().describe("Maximum number of results to return (default: 20)"),
@@ -22,18 +22,7 @@ function createSearchRouter(getAgent) {
22
22
  responses: {
23
23
  200: {
24
24
  description: "Message search results",
25
- content: {
26
- "application/json": {
27
- schema: z.object({
28
- results: z.array(SearchResultSchema).describe("Array of search results"),
29
- total: z.number().int().nonnegative().describe("Total number of results available"),
30
- hasMore: z.boolean().describe(
31
- "Whether there are more results beyond the current page"
32
- ),
33
- query: z.string().describe("Query that was searched")
34
- }).strict().describe("Message search response")
35
- }
36
- }
25
+ content: { "application/json": { schema: MessageSearchResponseSchema } }
37
26
  }
38
27
  }
39
28
  });
@@ -47,18 +36,7 @@ function createSearchRouter(getAgent) {
47
36
  responses: {
48
37
  200: {
49
38
  description: "Session search results",
50
- content: {
51
- "application/json": {
52
- schema: z.object({
53
- results: z.array(SessionSearchResultSchema).describe("Array of session search results"),
54
- total: z.number().int().nonnegative().describe("Total number of sessions with matches"),
55
- hasMore: z.boolean().describe(
56
- "Always false - session search returns all matching sessions without pagination"
57
- ),
58
- query: z.string().describe("Query that was searched")
59
- }).strict().describe("Session search response")
60
- }
61
- }
39
+ content: { "application/json": { schema: SessionSearchResponseSchema } }
62
40
  }
63
41
  }
64
42
  });
@@ -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: { params: import_zod_openapi.z.object({ sessionId: import_zod_openapi.z.string().describe("Session identifier") }) },
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.describe("Session metadata")
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 agent.getSessionHistory(sessionId);
307
- return ctx.json({ history });
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({ cancelled, sessionId });
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
@@ -75,18 +75,29 @@ export declare function createSessionsRouter(getAgent: () => DextoAgent): OpenAP
75
75
  text: string;
76
76
  } | {
77
77
  type: "image";
78
- image?: import("hono/utils/types").JSONValue;
78
+ image: string;
79
79
  mimeType?: string | undefined;
80
80
  } | {
81
81
  type: "file";
82
82
  mimeType: string;
83
- data?: import("hono/utils/types").JSONValue;
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
- provider?: string | undefined;
88
- model?: string | undefined;
89
- router?: string | undefined;
100
+ id?: string | undefined;
90
101
  name?: string | undefined;
91
102
  timestamp?: number | undefined;
92
103
  reasoning?: string | undefined;
@@ -96,6 +107,8 @@ export declare function createSessionsRouter(getAgent: () => DextoAgent): OpenAP
96
107
  reasoningTokens?: number | undefined;
97
108
  totalTokens?: number | undefined;
98
109
  } | undefined;
110
+ model?: string | undefined;
111
+ provider?: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | undefined;
99
112
  toolCalls?: {
100
113
  function: {
101
114
  name: string;
@@ -105,7 +118,9 @@ export declare function createSessionsRouter(getAgent: () => DextoAgent): OpenAP
105
118
  id: string;
106
119
  }[] | undefined;
107
120
  toolCallId?: string | undefined;
121
+ success?: boolean | undefined;
108
122
  }[];
123
+ isBusy: boolean;
109
124
  };
110
125
  outputFormat: "json";
111
126
  status: 200;
@@ -134,10 +149,16 @@ export declare function createSessionsRouter(getAgent: () => DextoAgent): OpenAP
134
149
  param: {
135
150
  sessionId: string;
136
151
  };
152
+ } & {
153
+ json: {
154
+ clearQueue?: boolean | undefined;
155
+ };
137
156
  };
138
157
  output: {
139
158
  sessionId: string;
140
159
  cancelled: boolean;
160
+ queueCleared: boolean;
161
+ clearedCount: number;
141
162
  };
142
163
  outputFormat: "json";
143
164
  status: 200;
@@ -157,6 +178,7 @@ export declare function createSessionsRouter(getAgent: () => DextoAgent): OpenAP
157
178
  createdAt: number | null;
158
179
  lastActivity: number | null;
159
180
  messageCount: number;
181
+ isBusy: boolean;
160
182
  title?: string | null | undefined;
161
183
  };
162
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA6Y9D"}
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: { params: z.object({ sessionId: z.string().describe("Session identifier") }) },
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.describe("Session metadata")
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 agent.getSessionHistory(sessionId);
284
- return ctx.json({ history });
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({ cancelled, sessionId });
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
@@ -0,0 +1,77 @@
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 static_exports = {};
20
+ __export(static_exports, {
21
+ createSpaFallbackHandler: () => createSpaFallbackHandler,
22
+ createStaticRouter: () => createStaticRouter
23
+ });
24
+ module.exports = __toCommonJS(static_exports);
25
+ var import_hono = require("hono");
26
+ var import_serve_static = require("@hono/node-server/serve-static");
27
+ var import_promises = require("node:fs/promises");
28
+ var import_node_path = require("node:path");
29
+ function createStaticRouter(webRoot) {
30
+ const app = new import_hono.Hono();
31
+ app.use("/assets/*", (0, import_serve_static.serveStatic)({ root: webRoot }));
32
+ app.use("/logos/*", (0, import_serve_static.serveStatic)({ root: webRoot }));
33
+ app.use("/favicon.ico", (0, import_serve_static.serveStatic)({ root: webRoot }));
34
+ return app;
35
+ }
36
+ function buildInjectionScript(config) {
37
+ const scripts = [];
38
+ if (config.analytics) {
39
+ const safeJson = JSON.stringify(config.analytics).replace(/</g, "\\u003c");
40
+ scripts.push(`window.__DEXTO_ANALYTICS__ = ${safeJson};`);
41
+ }
42
+ if (scripts.length === 0) return "";
43
+ return `<script>${scripts.join("\n")}</script>`;
44
+ }
45
+ function createSpaFallbackHandler(webRoot, runtimeConfig) {
46
+ const injectionScript = runtimeConfig ? buildInjectionScript(runtimeConfig) : "";
47
+ return async (c) => {
48
+ const path = c.req.path;
49
+ if (/\.[a-zA-Z0-9]+$/.test(path)) {
50
+ return c.json({ error: "Not Found", path }, 404);
51
+ }
52
+ try {
53
+ let html = await (0, import_promises.readFile)((0, import_node_path.join)(webRoot, "index.html"), "utf-8");
54
+ if (injectionScript) {
55
+ html = html.replace("</head>", `${injectionScript}</head>`);
56
+ }
57
+ return c.html(html);
58
+ } catch {
59
+ return c.html(
60
+ `<!DOCTYPE html>
61
+ <html>
62
+ <head><title>Dexto API Server</title></head>
63
+ <body>
64
+ <h1>Dexto API Server</h1>
65
+ <p>WebUI is not available. API endpoints are accessible at <code>/api/*</code></p>
66
+ </body>
67
+ </html>`,
68
+ 200
69
+ );
70
+ }
71
+ };
72
+ }
73
+ // Annotate the CommonJS export names for ESM import in node:
74
+ 0 && (module.exports = {
75
+ createSpaFallbackHandler,
76
+ createStaticRouter
77
+ });