@dexto/server 1.6.20 → 1.6.21

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 (111) hide show
  1. package/dist/a2a/jsonrpc/methods.cjs +1 -1
  2. package/dist/a2a/jsonrpc/methods.d.ts +14 -4
  3. package/dist/a2a/jsonrpc/methods.d.ts.map +1 -1
  4. package/dist/a2a/jsonrpc/methods.js +1 -1
  5. package/dist/hono/index.cjs +39 -8
  6. package/dist/hono/index.d.ts +43 -4531
  7. package/dist/hono/index.d.ts.map +1 -1
  8. package/dist/hono/index.js +42 -9
  9. package/dist/hono/routes/a2a-jsonrpc.d.ts.map +1 -1
  10. package/dist/hono/routes/a2a-tasks.cjs +158 -32
  11. package/dist/hono/routes/a2a-tasks.d.ts +1 -502
  12. package/dist/hono/routes/a2a-tasks.d.ts.map +1 -1
  13. package/dist/hono/routes/a2a-tasks.js +162 -32
  14. package/dist/hono/routes/a2a.d.ts.map +1 -1
  15. package/dist/hono/routes/agents.cjs +410 -329
  16. package/dist/hono/routes/agents.d.ts +16043 -68
  17. package/dist/hono/routes/agents.d.ts.map +1 -1
  18. package/dist/hono/routes/agents.js +418 -330
  19. package/dist/hono/routes/approvals.cjs +102 -88
  20. package/dist/hono/routes/approvals.d.ts +2089 -142
  21. package/dist/hono/routes/approvals.d.ts.map +1 -1
  22. package/dist/hono/routes/approvals.js +108 -89
  23. package/dist/hono/routes/dexto-auth.cjs +40 -33
  24. package/dist/hono/routes/dexto-auth.d.ts +401 -2
  25. package/dist/hono/routes/dexto-auth.d.ts.map +1 -1
  26. package/dist/hono/routes/dexto-auth.js +40 -33
  27. package/dist/hono/routes/discovery.cjs +16 -14
  28. package/dist/hono/routes/discovery.d.ts +586 -1
  29. package/dist/hono/routes/discovery.d.ts.map +1 -1
  30. package/dist/hono/routes/discovery.js +16 -14
  31. package/dist/hono/routes/greeting.cjs +26 -22
  32. package/dist/hono/routes/greeting.d.ts +787 -3
  33. package/dist/hono/routes/greeting.d.ts.map +1 -1
  34. package/dist/hono/routes/greeting.js +26 -22
  35. package/dist/hono/routes/health.d.ts +1 -1
  36. package/dist/hono/routes/key.cjs +60 -52
  37. package/dist/hono/routes/key.d.ts +1597 -1
  38. package/dist/hono/routes/key.d.ts.map +1 -1
  39. package/dist/hono/routes/key.js +60 -52
  40. package/dist/hono/routes/llm.cjs +381 -348
  41. package/dist/hono/routes/llm.d.ts +12136 -86
  42. package/dist/hono/routes/llm.d.ts.map +1 -1
  43. package/dist/hono/routes/llm.js +385 -348
  44. package/dist/hono/routes/mcp.cjs +257 -226
  45. package/dist/hono/routes/mcp.d.ts +6605 -309
  46. package/dist/hono/routes/mcp.d.ts.map +1 -1
  47. package/dist/hono/routes/mcp.js +263 -225
  48. package/dist/hono/routes/memory.cjs +102 -89
  49. package/dist/hono/routes/memory.d.ts +5368 -4
  50. package/dist/hono/routes/memory.d.ts.map +1 -1
  51. package/dist/hono/routes/memory.js +108 -90
  52. package/dist/hono/routes/messages.cjs +147 -139
  53. package/dist/hono/routes/messages.d.ts +3900 -11
  54. package/dist/hono/routes/messages.d.ts.map +1 -1
  55. package/dist/hono/routes/messages.js +150 -139
  56. package/dist/hono/routes/models.cjs +106 -64
  57. package/dist/hono/routes/models.d.ts +2874 -1
  58. package/dist/hono/routes/models.d.ts.map +1 -1
  59. package/dist/hono/routes/models.js +108 -64
  60. package/dist/hono/routes/openrouter.cjs +79 -65
  61. package/dist/hono/routes/openrouter.d.ts +854 -1
  62. package/dist/hono/routes/openrouter.d.ts.map +1 -1
  63. package/dist/hono/routes/openrouter.js +79 -65
  64. package/dist/hono/routes/prompts.cjs +136 -109
  65. package/dist/hono/routes/prompts.d.ts +2818 -10
  66. package/dist/hono/routes/prompts.d.ts.map +1 -1
  67. package/dist/hono/routes/prompts.js +138 -109
  68. package/dist/hono/routes/queue.cjs +133 -120
  69. package/dist/hono/routes/queue.d.ts +5144 -9
  70. package/dist/hono/routes/queue.d.ts.map +1 -1
  71. package/dist/hono/routes/queue.js +136 -120
  72. package/dist/hono/routes/resources.cjs +65 -46
  73. package/dist/hono/routes/resources.d.ts +1982 -4
  74. package/dist/hono/routes/resources.d.ts.map +1 -1
  75. package/dist/hono/routes/resources.js +72 -47
  76. package/dist/hono/routes/schedules.cjs +233 -226
  77. package/dist/hono/routes/schedules.d.ts +4198 -22
  78. package/dist/hono/routes/schedules.d.ts.map +1 -1
  79. package/dist/hono/routes/schedules.js +233 -226
  80. package/dist/hono/routes/search.cjs +34 -30
  81. package/dist/hono/routes/search.d.ts +2835 -12
  82. package/dist/hono/routes/search.d.ts.map +1 -1
  83. package/dist/hono/routes/search.js +40 -31
  84. package/dist/hono/routes/sessions.cjs +403 -396
  85. package/dist/hono/routes/sessions.d.ts +16582 -27
  86. package/dist/hono/routes/sessions.d.ts.map +1 -1
  87. package/dist/hono/routes/sessions.js +407 -397
  88. package/dist/hono/routes/static.d.ts.map +1 -1
  89. package/dist/hono/routes/system-prompt.cjs +57 -61
  90. package/dist/hono/routes/system-prompt.d.ts +1228 -2
  91. package/dist/hono/routes/system-prompt.d.ts.map +1 -1
  92. package/dist/hono/routes/system-prompt.js +58 -62
  93. package/dist/hono/routes/tools.cjs +29 -34
  94. package/dist/hono/routes/tools.d.ts +1755 -6
  95. package/dist/hono/routes/tools.d.ts.map +1 -1
  96. package/dist/hono/routes/tools.js +33 -33
  97. package/dist/hono/routes/webhooks.cjs +115 -123
  98. package/dist/hono/routes/webhooks.d.ts +2501 -11
  99. package/dist/hono/routes/webhooks.d.ts.map +1 -1
  100. package/dist/hono/routes/webhooks.js +120 -124
  101. package/dist/hono/routes/workspaces.cjs +84 -79
  102. package/dist/hono/routes/workspaces.d.ts +2093 -2
  103. package/dist/hono/routes/workspaces.d.ts.map +1 -1
  104. package/dist/hono/routes/workspaces.js +89 -80
  105. package/dist/hono/schemas/responses.cjs +406 -259
  106. package/dist/hono/schemas/responses.d.ts +1246 -123
  107. package/dist/hono/schemas/responses.d.ts.map +1 -1
  108. package/dist/hono/schemas/responses.js +144 -10
  109. package/dist/hono/types.d.ts +11 -0
  110. package/dist/hono/types.d.ts.map +1 -1
  111. package/package.json +7 -7
@@ -6,10 +6,13 @@ import {
6
6
  zodToIssues
7
7
  } from "@dexto/core";
8
8
  import {
9
+ BadRequestErrorResponse,
10
+ ConflictErrorResponse,
11
+ InternalErrorResponse,
9
12
  SessionMetadataSchema,
10
13
  InternalMessageSchema,
14
+ NotFoundErrorResponse,
11
15
  ScopedUsageSummarySchema,
12
- StandardErrorEnvelopeSchema,
13
16
  UsageSummarySchema
14
17
  } from "../schemas/responses.js";
15
18
  import { handleHonoError } from "../middleware/error.js";
@@ -56,423 +59,412 @@ function mapSessionMetadata(sessionId, metadata, defaults) {
56
59
  parentSessionId: metadata?.parentSessionId ?? defaults?.parentSessionId ?? null
57
60
  };
58
61
  }
59
- function createSessionsRouter(getAgent) {
60
- const app = new OpenAPIHono({
61
- defaultHook: (result, ctx) => {
62
- if (!result.success) {
63
- const issues = zodToIssues(result.error);
64
- return handleHonoError(
65
- ctx,
66
- new DextoRuntimeError(
67
- "validation_failed",
68
- "validation",
69
- ErrorType.USER,
70
- issues[0]?.message ?? "Validation failed",
71
- { issues }
72
- )
73
- );
74
- }
75
- }
76
- });
77
- app.onError((err, ctx) => handleHonoError(ctx, err));
78
- const listRoute = createRoute({
79
- method: "get",
80
- path: "/sessions",
81
- summary: "List Sessions",
82
- description: "Retrieves a list of all active sessions",
83
- tags: ["sessions"],
84
- responses: {
85
- 200: {
86
- description: "List of all active sessions",
87
- content: {
88
- "application/json": {
89
- schema: z.object({
90
- sessions: z.array(SessionMetadataSchema).describe("Array of session metadata objects")
91
- }).strict()
92
- }
62
+ const listRoute = createRoute({
63
+ method: "get",
64
+ path: "/sessions",
65
+ summary: "List Sessions",
66
+ description: "Retrieves a list of all active sessions",
67
+ tags: ["sessions"],
68
+ responses: {
69
+ 200: {
70
+ description: "List of all active sessions",
71
+ content: {
72
+ "application/json": {
73
+ schema: z.object({
74
+ sessions: z.array(SessionMetadataSchema).describe("Array of session metadata objects")
75
+ }).strict()
93
76
  }
94
77
  }
95
- }
96
- });
97
- const createRouteDef = createRoute({
98
- method: "post",
99
- path: "/sessions",
100
- summary: "Create Session",
101
- description: "Creates a new session",
102
- tags: ["sessions"],
103
- request: { body: { content: { "application/json": { schema: CreateSessionSchema } } } },
104
- responses: {
105
- 201: {
106
- description: "Session created successfully",
107
- content: {
108
- "application/json": {
109
- schema: z.object({
110
- session: SessionMetadataSchema.describe(
111
- "Newly created session metadata"
112
- )
113
- }).strict()
114
- }
78
+ },
79
+ 400: BadRequestErrorResponse,
80
+ 500: InternalErrorResponse
81
+ }
82
+ });
83
+ const createRouteDef = createRoute({
84
+ method: "post",
85
+ path: "/sessions",
86
+ summary: "Create Session",
87
+ description: "Creates a new session",
88
+ tags: ["sessions"],
89
+ request: { body: { content: { "application/json": { schema: CreateSessionSchema } } } },
90
+ responses: {
91
+ 201: {
92
+ description: "Session created successfully",
93
+ content: {
94
+ "application/json": {
95
+ schema: z.object({
96
+ session: SessionMetadataSchema.describe(
97
+ "Newly created session metadata"
98
+ )
99
+ }).strict()
115
100
  }
116
101
  }
117
- }
118
- });
119
- const getRoute = createRoute({
120
- method: "get",
121
- path: "/sessions/{sessionId}",
122
- summary: "Get Session Details",
123
- description: "Fetches details for a specific session",
124
- tags: ["sessions"],
125
- request: { params: z.object({ sessionId: z.string().describe("Session identifier") }) },
126
- responses: {
127
- 200: {
128
- description: "Session details with metadata",
129
- content: {
130
- "application/json": {
131
- schema: z.object({
132
- session: SessionMetadataSchema.extend({
133
- history: z.number().int().nonnegative().describe("Number of messages in history")
134
- }).strict().describe("Session metadata with history count")
135
- }).strict()
136
- }
102
+ },
103
+ 400: BadRequestErrorResponse,
104
+ 500: InternalErrorResponse
105
+ }
106
+ });
107
+ const getRoute = createRoute({
108
+ method: "get",
109
+ path: "/sessions/{sessionId}",
110
+ summary: "Get Session Details",
111
+ description: "Fetches details for a specific session",
112
+ tags: ["sessions"],
113
+ request: { params: z.object({ sessionId: z.string().describe("Session identifier") }) },
114
+ responses: {
115
+ 200: {
116
+ description: "Session details with metadata",
117
+ content: {
118
+ "application/json": {
119
+ schema: z.object({
120
+ session: SessionMetadataSchema.extend({
121
+ history: z.number().int().nonnegative().describe("Number of messages in history")
122
+ }).strict().describe("Session metadata with history count")
123
+ }).strict()
137
124
  }
138
125
  }
139
- }
140
- });
141
- const forkRoute = createRoute({
142
- method: "post",
143
- path: "/sessions/{sessionId}/fork",
144
- summary: "Fork Session",
145
- description: "Creates a new child session by cloning the specified parent session history and metadata lineage.",
146
- tags: ["sessions"],
147
- request: {
148
- params: z.object({
149
- sessionId: z.string().describe("Parent session identifier")
150
- })
151
126
  },
152
- responses: {
153
- 201: {
154
- description: "Forked session created successfully",
155
- content: {
156
- "application/json": {
157
- schema: z.object({
158
- session: SessionMetadataSchema.describe(
159
- "Newly created child session metadata"
160
- )
161
- }).strict()
162
- }
163
- }
164
- },
165
- 400: {
166
- description: "Invalid fork request (for example, max session limit reached)",
167
- content: {
168
- "application/json": {
169
- schema: StandardErrorEnvelopeSchema
170
- }
171
- }
172
- },
173
- 404: {
174
- description: "Parent session not found",
175
- content: {
176
- "application/json": {
177
- schema: StandardErrorEnvelopeSchema
178
- }
127
+ 400: BadRequestErrorResponse,
128
+ 404: NotFoundErrorResponse,
129
+ 500: InternalErrorResponse
130
+ }
131
+ });
132
+ const forkRoute = createRoute({
133
+ method: "post",
134
+ path: "/sessions/{sessionId}/fork",
135
+ summary: "Fork Session",
136
+ description: "Creates a new child session by cloning the specified parent session history and metadata lineage.",
137
+ tags: ["sessions"],
138
+ request: {
139
+ params: z.object({
140
+ sessionId: z.string().describe("Parent session identifier")
141
+ })
142
+ },
143
+ responses: {
144
+ 201: {
145
+ description: "Forked session created successfully",
146
+ content: {
147
+ "application/json": {
148
+ schema: z.object({
149
+ session: SessionMetadataSchema.describe(
150
+ "Newly created child session metadata"
151
+ )
152
+ }).strict()
179
153
  }
180
154
  }
181
- }
182
- });
183
- const historyRoute = createRoute({
184
- method: "get",
185
- path: "/sessions/{sessionId}/history",
186
- summary: "Get Session History",
187
- description: "Retrieves the conversation history for a session along with processing status",
188
- tags: ["sessions"],
189
- request: { params: z.object({ sessionId: z.string().describe("Session identifier") }) },
190
- responses: {
191
- 200: {
192
- description: "Session conversation history",
193
- content: {
194
- "application/json": {
195
- schema: z.object({
196
- history: z.array(InternalMessageSchema).describe("Array of messages in conversation history"),
197
- isBusy: z.boolean().describe(
198
- "Whether the session is currently processing a message"
199
- )
200
- }).strict()
201
- }
155
+ },
156
+ 400: {
157
+ ...BadRequestErrorResponse
158
+ },
159
+ 404: {
160
+ ...NotFoundErrorResponse
161
+ },
162
+ 500: InternalErrorResponse
163
+ }
164
+ });
165
+ const historyRoute = createRoute({
166
+ method: "get",
167
+ path: "/sessions/{sessionId}/history",
168
+ summary: "Get Session History",
169
+ description: "Retrieves the conversation history for a session along with processing status",
170
+ tags: ["sessions"],
171
+ request: { params: z.object({ sessionId: z.string().describe("Session identifier") }) },
172
+ responses: {
173
+ 200: {
174
+ description: "Session conversation history",
175
+ content: {
176
+ "application/json": {
177
+ schema: z.object({
178
+ history: z.array(InternalMessageSchema).describe("Array of messages in conversation history"),
179
+ isBusy: z.boolean().describe("Whether the session is currently processing a message")
180
+ }).strict()
202
181
  }
203
182
  }
204
- }
205
- });
206
- const listSessionPromptContributorsRoute = createRoute({
207
- method: "get",
208
- path: "/sessions/{sessionId}/system-prompt/contributors",
209
- summary: "List Session System Prompt Contributors",
210
- description: "Lists static system prompt contributors that apply only to the specified session.",
211
- tags: ["sessions", "config"],
212
- request: { params: z.object({ sessionId: z.string().describe("Session identifier") }) },
213
- responses: {
214
- 200: {
215
- description: "Current session contributor list",
216
- content: {
217
- "application/json": {
218
- schema: z.object({
219
- contributors: z.array(SessionPromptContributorInfoSchema).describe("Registered session prompt contributors.")
220
- }).strict()
221
- }
183
+ },
184
+ 400: BadRequestErrorResponse,
185
+ 404: NotFoundErrorResponse,
186
+ 500: InternalErrorResponse
187
+ }
188
+ });
189
+ const listSessionPromptContributorsRoute = createRoute({
190
+ method: "get",
191
+ path: "/sessions/{sessionId}/system-prompt/contributors",
192
+ summary: "List Session System Prompt Contributors",
193
+ description: "Lists static system prompt contributors that apply only to the specified session.",
194
+ tags: ["sessions", "config"],
195
+ request: { params: z.object({ sessionId: z.string().describe("Session identifier") }) },
196
+ responses: {
197
+ 200: {
198
+ description: "Current session contributor list",
199
+ content: {
200
+ "application/json": {
201
+ schema: z.object({
202
+ contributors: z.array(SessionPromptContributorInfoSchema).describe("Registered session prompt contributors.")
203
+ }).strict()
222
204
  }
223
- },
224
- 404: {
225
- description: "Session not found",
226
- content: {
227
- "application/json": {
228
- schema: StandardErrorEnvelopeSchema
229
- }
205
+ }
206
+ },
207
+ 404: {
208
+ ...NotFoundErrorResponse
209
+ },
210
+ 500: InternalErrorResponse
211
+ }
212
+ });
213
+ const upsertSessionPromptContributorRoute = createRoute({
214
+ method: "post",
215
+ path: "/sessions/{sessionId}/system-prompt/contributors",
216
+ summary: "Upsert Session System Prompt Contributor",
217
+ description: "Adds or updates a static system prompt contributor that applies only to the specified session. Set enabled=false to remove it.",
218
+ tags: ["sessions", "config"],
219
+ request: {
220
+ params: z.object({ sessionId: z.string().describe("Session identifier") }),
221
+ body: {
222
+ required: true,
223
+ content: {
224
+ "application/json": {
225
+ schema: UpsertSessionPromptContributorSchema
230
226
  }
231
227
  }
232
228
  }
233
- });
234
- const upsertSessionPromptContributorRoute = createRoute({
235
- method: "post",
236
- path: "/sessions/{sessionId}/system-prompt/contributors",
237
- summary: "Upsert Session System Prompt Contributor",
238
- description: "Adds or updates a static system prompt contributor that applies only to the specified session. Set enabled=false to remove it.",
239
- tags: ["sessions", "config"],
240
- request: {
241
- params: z.object({ sessionId: z.string().describe("Session identifier") }),
242
- body: {
243
- required: true,
244
- content: {
245
- "application/json": {
246
- schema: UpsertSessionPromptContributorSchema
247
- }
229
+ },
230
+ responses: {
231
+ 200: {
232
+ description: "Session contributor upsert result",
233
+ content: {
234
+ "application/json": {
235
+ schema: z.object({
236
+ id: z.string().describe("Contributor identifier"),
237
+ enabled: z.boolean().describe("Whether the contributor remains enabled"),
238
+ priority: z.number().optional().describe("Contributor priority"),
239
+ replaced: z.boolean().optional().describe("Whether an existing contributor was replaced"),
240
+ removed: z.boolean().optional().describe("Whether the contributor was removed"),
241
+ contentLength: z.number().optional().describe("Stored content length in characters"),
242
+ truncated: z.boolean().optional().describe("Whether the submitted content was truncated")
243
+ }).strict()
248
244
  }
249
245
  }
250
246
  },
251
- responses: {
252
- 200: {
253
- description: "Session contributor upsert result",
254
- content: {
255
- "application/json": {
256
- schema: z.object({
257
- id: z.string().describe("Contributor identifier"),
258
- enabled: z.boolean().describe("Whether the contributor remains enabled"),
259
- priority: z.number().optional().describe("Contributor priority"),
260
- replaced: z.boolean().optional().describe("Whether an existing contributor was replaced"),
261
- removed: z.boolean().optional().describe("Whether the contributor was removed"),
262
- contentLength: z.number().optional().describe("Stored content length in characters"),
263
- truncated: z.boolean().optional().describe("Whether the submitted content was truncated")
264
- }).strict()
265
- }
247
+ 400: {
248
+ ...BadRequestErrorResponse
249
+ },
250
+ 404: {
251
+ ...NotFoundErrorResponse
252
+ },
253
+ 500: InternalErrorResponse
254
+ }
255
+ });
256
+ const deleteRoute = createRoute({
257
+ method: "delete",
258
+ path: "/sessions/{sessionId}",
259
+ summary: "Delete Session",
260
+ description: "Permanently deletes a session and all its conversation history. This action cannot be undone",
261
+ tags: ["sessions"],
262
+ request: { params: z.object({ sessionId: z.string().describe("Session identifier") }) },
263
+ responses: {
264
+ 200: {
265
+ description: "Session deleted successfully",
266
+ content: {
267
+ "application/json": {
268
+ schema: z.object({
269
+ status: z.literal("deleted").describe("Deletion status"),
270
+ sessionId: z.string().describe("ID of the deleted session")
271
+ }).strict()
266
272
  }
267
- },
268
- 400: {
269
- description: "Invalid session contributor request",
270
- content: {
271
- "application/json": {
272
- schema: StandardErrorEnvelopeSchema
273
- }
273
+ }
274
+ },
275
+ 400: BadRequestErrorResponse,
276
+ 404: NotFoundErrorResponse,
277
+ 500: InternalErrorResponse
278
+ }
279
+ });
280
+ const cancelRoute = createRoute({
281
+ method: "post",
282
+ path: "/sessions/{sessionId}/cancel",
283
+ summary: "Cancel Session Run",
284
+ 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.",
285
+ tags: ["sessions"],
286
+ request: {
287
+ params: z.object({ sessionId: z.string().describe("Session identifier") }),
288
+ body: {
289
+ content: {
290
+ "application/json": {
291
+ schema: z.object({
292
+ clearQueue: z.boolean().optional().default(false).describe(
293
+ "If true (hard cancel), clears queued messages. If false (soft cancel, default), queued messages continue processing."
294
+ )
295
+ }).strict()
274
296
  }
275
297
  },
276
- 404: {
277
- description: "Session not found",
278
- content: {
279
- "application/json": {
280
- schema: StandardErrorEnvelopeSchema
281
- }
282
- }
283
- }
298
+ required: false
284
299
  }
285
- });
286
- const deleteRoute = createRoute({
287
- method: "delete",
288
- path: "/sessions/{sessionId}",
289
- summary: "Delete Session",
290
- description: "Permanently deletes a session and all its conversation history. This action cannot be undone",
291
- tags: ["sessions"],
292
- request: { params: z.object({ sessionId: z.string().describe("Session identifier") }) },
293
- responses: {
294
- 200: {
295
- description: "Session deleted successfully",
296
- content: {
297
- "application/json": {
298
- schema: z.object({
299
- status: z.literal("deleted").describe("Deletion status"),
300
- sessionId: z.string().describe("ID of the deleted session")
301
- }).strict()
302
- }
300
+ },
301
+ responses: {
302
+ 200: {
303
+ description: "Cancel operation result",
304
+ content: {
305
+ "application/json": {
306
+ schema: z.object({
307
+ cancelled: z.boolean().describe("Whether a run was cancelled"),
308
+ sessionId: z.string().describe("Session ID"),
309
+ queueCleared: z.boolean().describe("Whether queued messages were cleared"),
310
+ clearedCount: z.number().describe("Number of queued messages cleared (0 if soft cancel)")
311
+ }).strict()
303
312
  }
304
313
  }
305
- }
306
- });
307
- const cancelRoute = createRoute({
308
- method: "post",
309
- path: "/sessions/{sessionId}/cancel",
310
- summary: "Cancel Session Run",
311
- 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.",
312
- tags: ["sessions"],
313
- request: {
314
- params: z.object({ sessionId: z.string().describe("Session identifier") }),
315
- body: {
316
- content: {
317
- "application/json": {
318
- schema: z.object({
319
- clearQueue: z.boolean().optional().default(false).describe(
320
- "If true (hard cancel), clears queued messages. If false (soft cancel, default), queued messages continue processing."
321
- )
322
- }).strict()
323
- }
324
- },
325
- required: false
326
- }
327
314
  },
328
- responses: {
329
- 200: {
330
- description: "Cancel operation result",
331
- content: {
332
- "application/json": {
333
- schema: z.object({
334
- cancelled: z.boolean().describe("Whether a run was cancelled"),
335
- sessionId: z.string().describe("Session ID"),
336
- queueCleared: z.boolean().describe("Whether queued messages were cleared"),
337
- clearedCount: z.number().describe(
338
- "Number of queued messages cleared (0 if soft cancel)"
315
+ 400: BadRequestErrorResponse,
316
+ 404: NotFoundErrorResponse,
317
+ 409: ConflictErrorResponse,
318
+ 500: InternalErrorResponse
319
+ }
320
+ });
321
+ const loadRoute = createRoute({
322
+ method: "get",
323
+ path: "/sessions/{sessionId}/load",
324
+ summary: "Load Session",
325
+ description: "Validates and retrieves session information including processing status. The client should track the active session.",
326
+ tags: ["sessions"],
327
+ request: {
328
+ params: z.object({ sessionId: z.string().describe("Session identifier") })
329
+ },
330
+ responses: {
331
+ 200: {
332
+ description: "Session information retrieved successfully",
333
+ content: {
334
+ "application/json": {
335
+ schema: z.object({
336
+ session: SessionMetadataSchema.extend({
337
+ isBusy: z.boolean().describe(
338
+ "Whether the session is currently processing a message"
339
+ ),
340
+ usageSummary: UsageSummarySchema.describe(
341
+ "Exact usage summary derived from assistant message history"
342
+ ),
343
+ activeUsageScopeId: z.string().nullable().describe(
344
+ "Current runtime usage scope identifier, if configured"
345
+ ),
346
+ activeUsageScope: ScopedUsageSummarySchema.nullable().describe(
347
+ "Usage summary for the current runtime scope, if configured"
339
348
  )
340
- }).strict()
341
- }
349
+ }).describe("Session metadata with processing status")
350
+ }).strict()
342
351
  }
343
352
  }
344
- }
345
- });
346
- const loadRoute = createRoute({
347
- method: "get",
348
- path: "/sessions/{sessionId}/load",
349
- summary: "Load Session",
350
- description: "Validates and retrieves session information including processing status. The client should track the active session.",
351
- tags: ["sessions"],
352
- request: {
353
- params: z.object({ sessionId: z.string().describe("Session identifier") })
354
353
  },
355
- responses: {
356
- 200: {
357
- description: "Session information retrieved successfully",
358
- content: {
359
- "application/json": {
360
- schema: z.object({
361
- session: SessionMetadataSchema.extend({
362
- isBusy: z.boolean().describe(
363
- "Whether the session is currently processing a message"
364
- ),
365
- usageSummary: UsageSummarySchema.describe(
366
- "Exact usage summary derived from assistant message history"
367
- ),
368
- activeUsageScopeId: z.string().nullable().describe(
369
- "Current runtime usage scope identifier, if configured"
370
- ),
371
- activeUsageScope: ScopedUsageSummarySchema.nullable().describe(
372
- "Usage summary for the current runtime scope, if configured"
373
- )
374
- }).describe("Session metadata with processing status")
375
- }).strict()
376
- }
377
- }
378
- },
379
- 404: {
380
- description: "Session not found",
381
- content: {
382
- "application/json": {
383
- schema: z.object({
384
- error: z.string().describe("Error message")
385
- }).strict()
386
- }
354
+ 404: {
355
+ ...NotFoundErrorResponse
356
+ },
357
+ 400: BadRequestErrorResponse,
358
+ 500: InternalErrorResponse
359
+ }
360
+ });
361
+ const clearContextRoute = createRoute({
362
+ method: "post",
363
+ path: "/sessions/{sessionId}/clear-context",
364
+ summary: "Clear Session Context",
365
+ description: "Clears the model context window for a session while preserving conversation history for review.",
366
+ tags: ["sessions"],
367
+ request: {
368
+ params: z.object({ sessionId: z.string().describe("Session identifier") })
369
+ },
370
+ responses: {
371
+ 200: {
372
+ description: "Session context cleared successfully",
373
+ content: {
374
+ "application/json": {
375
+ schema: z.object({
376
+ status: z.literal("context cleared").describe("Context clear status"),
377
+ sessionId: z.string().describe("Session ID")
378
+ }).strict()
387
379
  }
388
380
  }
389
- }
390
- });
391
- const clearContextRoute = createRoute({
392
- method: "post",
393
- path: "/sessions/{sessionId}/clear-context",
394
- summary: "Clear Session Context",
395
- description: "Clears the model context window for a session while preserving conversation history for review.",
396
- tags: ["sessions"],
397
- request: {
398
- params: z.object({ sessionId: z.string().describe("Session identifier") })
399
381
  },
400
- responses: {
401
- 200: {
402
- description: "Session context cleared successfully",
403
- content: {
404
- "application/json": {
405
- schema: z.object({
406
- status: z.literal("context cleared").describe("Context clear status"),
407
- sessionId: z.string().describe("Session ID")
408
- }).strict()
409
- }
382
+ 400: BadRequestErrorResponse,
383
+ 404: NotFoundErrorResponse,
384
+ 500: InternalErrorResponse
385
+ }
386
+ });
387
+ const patchRoute = createRoute({
388
+ method: "patch",
389
+ path: "/sessions/{sessionId}",
390
+ summary: "Update Session Title",
391
+ description: "Updates the title of an existing session",
392
+ tags: ["sessions"],
393
+ request: {
394
+ params: z.object({ sessionId: z.string().describe("Session identifier") }),
395
+ body: {
396
+ content: {
397
+ "application/json": {
398
+ schema: z.object({
399
+ title: z.string().min(1, "Title is required").max(120, "Title too long").describe("New title for the session (maximum 120 characters)")
400
+ })
410
401
  }
411
402
  }
412
403
  }
413
- });
414
- const patchRoute = createRoute({
415
- method: "patch",
416
- path: "/sessions/{sessionId}",
417
- summary: "Update Session Title",
418
- description: "Updates the title of an existing session",
419
- tags: ["sessions"],
420
- request: {
421
- params: z.object({ sessionId: z.string().describe("Session identifier") }),
422
- body: {
423
- content: {
424
- "application/json": {
425
- schema: z.object({
426
- title: z.string().min(1, "Title is required").max(120, "Title too long").describe("New title for the session (maximum 120 characters)")
427
- })
428
- }
404
+ },
405
+ responses: {
406
+ 200: {
407
+ description: "Session updated successfully",
408
+ content: {
409
+ "application/json": {
410
+ schema: z.object({
411
+ session: SessionMetadataSchema.describe("Updated session metadata")
412
+ }).strict()
429
413
  }
430
414
  }
431
415
  },
432
- responses: {
433
- 200: {
434
- description: "Session updated successfully",
435
- content: {
436
- "application/json": {
437
- schema: z.object({
438
- session: SessionMetadataSchema.describe("Updated session metadata")
439
- }).strict()
440
- }
416
+ 400: BadRequestErrorResponse,
417
+ 404: NotFoundErrorResponse,
418
+ 500: InternalErrorResponse
419
+ }
420
+ });
421
+ const generateTitleRoute = createRoute({
422
+ method: "post",
423
+ path: "/sessions/{sessionId}/generate-title",
424
+ summary: "Generate Session Title",
425
+ description: "Generates a descriptive title for the session using the first user message. Returns existing title if already set.",
426
+ tags: ["sessions"],
427
+ request: {
428
+ params: z.object({ sessionId: z.string().describe("Session identifier") })
429
+ },
430
+ responses: {
431
+ 200: {
432
+ description: "Title generated successfully",
433
+ content: {
434
+ "application/json": {
435
+ schema: z.object({
436
+ title: z.string().nullable().describe("Generated title, or null if generation failed"),
437
+ sessionId: z.string().describe("Session ID")
438
+ }).strict()
441
439
  }
442
440
  }
443
- }
444
- });
445
- const generateTitleRoute = createRoute({
446
- method: "post",
447
- path: "/sessions/{sessionId}/generate-title",
448
- summary: "Generate Session Title",
449
- description: "Generates a descriptive title for the session using the first user message. Returns existing title if already set.",
450
- tags: ["sessions"],
451
- request: {
452
- params: z.object({ sessionId: z.string().describe("Session identifier") })
453
441
  },
454
- responses: {
455
- 200: {
456
- description: "Title generated successfully",
457
- content: {
458
- "application/json": {
459
- schema: z.object({
460
- title: z.string().nullable().describe("Generated title, or null if generation failed"),
461
- sessionId: z.string().describe("Session ID")
462
- }).strict()
463
- }
464
- }
465
- },
466
- 404: {
467
- description: "Session not found",
468
- content: {
469
- "application/json": {
470
- schema: StandardErrorEnvelopeSchema
471
- }
472
- }
442
+ 404: {
443
+ ...NotFoundErrorResponse
444
+ },
445
+ 400: BadRequestErrorResponse,
446
+ 500: InternalErrorResponse
447
+ }
448
+ });
449
+ function createSessionsRouter(getAgent) {
450
+ const app = new OpenAPIHono({
451
+ defaultHook: (result, ctx) => {
452
+ if (!result.success) {
453
+ const issues = zodToIssues(result.error);
454
+ return handleHonoError(
455
+ ctx,
456
+ new DextoRuntimeError(
457
+ "validation_failed",
458
+ "validation",
459
+ ErrorType.USER,
460
+ issues[0]?.message ?? "Validation failed",
461
+ { issues }
462
+ )
463
+ );
473
464
  }
474
465
  }
475
466
  });
467
+ app.onError((err, ctx) => handleHonoError(ctx, err));
476
468
  return app.openapi(listRoute, async (ctx) => {
477
469
  const agent = await getAgent(ctx);
478
470
  const sessionIds = await agent.listSessions();
@@ -486,7 +478,7 @@ function createSessionsRouter(getAgent) {
486
478
  }
487
479
  })
488
480
  );
489
- return ctx.json({ sessions });
481
+ return ctx.json({ sessions }, 200);
490
482
  }).openapi(createRouteDef, async (ctx) => {
491
483
  const agent = await getAgent(ctx);
492
484
  const { sessionId } = ctx.req.valid("json");
@@ -517,12 +509,15 @@ function createSessionsRouter(getAgent) {
517
509
  const { sessionId } = ctx.req.param();
518
510
  const metadata = await agent.getSessionMetadata(sessionId);
519
511
  const history = await agent.getSessionHistory(sessionId);
520
- return ctx.json({
521
- session: {
522
- ...mapSessionMetadata(sessionId, metadata),
523
- history: history.length
524
- }
525
- });
512
+ return ctx.json(
513
+ {
514
+ session: {
515
+ ...mapSessionMetadata(sessionId, metadata),
516
+ history: history.length
517
+ }
518
+ },
519
+ 200
520
+ );
526
521
  }).openapi(historyRoute, async (ctx) => {
527
522
  const agent = await getAgent(ctx);
528
523
  const { sessionId } = ctx.req.param();
@@ -530,10 +525,13 @@ function createSessionsRouter(getAgent) {
530
525
  agent.getSessionHistory(sessionId),
531
526
  agent.isSessionBusy(sessionId)
532
527
  ]);
533
- return ctx.json({
534
- history,
535
- isBusy
536
- });
528
+ return ctx.json(
529
+ {
530
+ history,
531
+ isBusy
532
+ },
533
+ 200
534
+ );
537
535
  }).openapi(listSessionPromptContributorsRoute, async (ctx) => {
538
536
  const agent = await getAgent(ctx);
539
537
  const { sessionId } = ctx.req.valid("param");
@@ -613,7 +611,7 @@ function createSessionsRouter(getAgent) {
613
611
  const agent = await getAgent(ctx);
614
612
  const { sessionId } = ctx.req.param();
615
613
  await agent.deleteSession(sessionId);
616
- return ctx.json({ status: "deleted", sessionId });
614
+ return ctx.json({ status: "deleted", sessionId }, 200);
617
615
  }).openapi(cancelRoute, async (ctx) => {
618
616
  const agent = await getAgent(ctx);
619
617
  const { sessionId } = ctx.req.valid("param");
@@ -637,18 +635,27 @@ function createSessionsRouter(getAgent) {
637
635
  if (!cancelled) {
638
636
  agent.logger.debug(`No in-flight run to cancel for session: ${sessionId}`);
639
637
  }
640
- return ctx.json({
641
- cancelled,
642
- sessionId,
643
- queueCleared: clearQueue,
644
- clearedCount
645
- });
638
+ return ctx.json(
639
+ {
640
+ cancelled,
641
+ sessionId,
642
+ queueCleared: clearQueue,
643
+ clearedCount
644
+ },
645
+ 200
646
+ );
646
647
  }).openapi(loadRoute, async (ctx) => {
647
648
  const agent = await getAgent(ctx);
648
649
  const { sessionId } = ctx.req.valid("param");
649
650
  const sessionIds = await agent.listSessions();
650
651
  if (!sessionIds.includes(sessionId)) {
651
- return ctx.json({ error: `Session not found: ${sessionId}` }, 404);
652
+ throw new DextoRuntimeError(
653
+ "session_not_found",
654
+ ErrorScope.SESSION,
655
+ ErrorType.NOT_FOUND,
656
+ `Session not found: ${sessionId}`,
657
+ { sessionId }
658
+ );
652
659
  }
653
660
  const metadata = await agent.getSessionMetadata(sessionId);
654
661
  const isBusy = await agent.isSessionBusy(sessionId);
@@ -674,16 +681,19 @@ function createSessionsRouter(getAgent) {
674
681
  const agent = await getAgent(ctx);
675
682
  const { sessionId } = ctx.req.valid("param");
676
683
  await agent.clearContext(sessionId);
677
- return ctx.json({ status: "context cleared", sessionId });
684
+ return ctx.json({ status: "context cleared", sessionId }, 200);
678
685
  }).openapi(patchRoute, async (ctx) => {
679
686
  const agent = await getAgent(ctx);
680
687
  const { sessionId } = ctx.req.valid("param");
681
688
  const { title } = ctx.req.valid("json");
682
689
  await agent.setSessionTitle(sessionId, title);
683
690
  const metadata = await agent.getSessionMetadata(sessionId);
684
- return ctx.json({
685
- session: mapSessionMetadata(sessionId, metadata, { title })
686
- });
691
+ return ctx.json(
692
+ {
693
+ session: mapSessionMetadata(sessionId, metadata, { title })
694
+ },
695
+ 200
696
+ );
687
697
  }).openapi(generateTitleRoute, async (ctx) => {
688
698
  const agent = await getAgent(ctx);
689
699
  const { sessionId } = ctx.req.valid("param");