@dexto/server 1.6.20 → 1.6.22
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/a2a/jsonrpc/methods.cjs +1 -1
- package/dist/a2a/jsonrpc/methods.d.ts +14 -4
- package/dist/a2a/jsonrpc/methods.d.ts.map +1 -1
- package/dist/a2a/jsonrpc/methods.js +1 -1
- package/dist/approval/wire-approval-events.cjs +44 -0
- package/dist/approval/wire-approval-events.d.ts +4 -0
- package/dist/approval/wire-approval-events.d.ts.map +1 -0
- package/dist/approval/wire-approval-events.js +20 -0
- package/dist/events/session-sse-subscriber.cjs +167 -0
- package/dist/events/session-sse-subscriber.d.ts +13 -0
- package/dist/events/session-sse-subscriber.d.ts.map +1 -0
- package/dist/events/session-sse-subscriber.js +143 -0
- package/dist/hono/__tests__/test-fixtures.cjs +8 -0
- package/dist/hono/__tests__/test-fixtures.d.ts +1 -0
- package/dist/hono/__tests__/test-fixtures.d.ts.map +1 -1
- package/dist/hono/__tests__/test-fixtures.js +8 -0
- package/dist/hono/index.cjs +40 -8
- package/dist/hono/index.d.ts +45 -4531
- package/dist/hono/index.d.ts.map +1 -1
- package/dist/hono/index.js +43 -9
- package/dist/hono/node/index.cjs +51 -6
- package/dist/hono/node/index.d.ts.map +1 -1
- package/dist/hono/node/index.js +51 -6
- package/dist/hono/routes/a2a-jsonrpc.d.ts.map +1 -1
- package/dist/hono/routes/a2a-tasks.cjs +158 -32
- package/dist/hono/routes/a2a-tasks.d.ts +1 -502
- package/dist/hono/routes/a2a-tasks.d.ts.map +1 -1
- package/dist/hono/routes/a2a-tasks.js +162 -32
- package/dist/hono/routes/a2a.d.ts.map +1 -1
- package/dist/hono/routes/agents.cjs +410 -329
- package/dist/hono/routes/agents.d.ts +16043 -68
- package/dist/hono/routes/agents.d.ts.map +1 -1
- package/dist/hono/routes/agents.js +418 -330
- package/dist/hono/routes/approvals.cjs +102 -88
- package/dist/hono/routes/approvals.d.ts +2089 -142
- package/dist/hono/routes/approvals.d.ts.map +1 -1
- package/dist/hono/routes/approvals.js +108 -89
- package/dist/hono/routes/dexto-auth.cjs +40 -33
- package/dist/hono/routes/dexto-auth.d.ts +401 -2
- package/dist/hono/routes/dexto-auth.d.ts.map +1 -1
- package/dist/hono/routes/dexto-auth.js +40 -33
- package/dist/hono/routes/discovery.cjs +16 -14
- package/dist/hono/routes/discovery.d.ts +586 -1
- package/dist/hono/routes/discovery.d.ts.map +1 -1
- package/dist/hono/routes/discovery.js +16 -14
- package/dist/hono/routes/greeting.cjs +26 -22
- package/dist/hono/routes/greeting.d.ts +787 -3
- package/dist/hono/routes/greeting.d.ts.map +1 -1
- package/dist/hono/routes/greeting.js +26 -22
- package/dist/hono/routes/health.d.ts +1 -1
- package/dist/hono/routes/key.cjs +60 -52
- package/dist/hono/routes/key.d.ts +1597 -1
- package/dist/hono/routes/key.d.ts.map +1 -1
- package/dist/hono/routes/key.js +60 -52
- package/dist/hono/routes/llm.cjs +382 -349
- package/dist/hono/routes/llm.d.ts +12148 -98
- package/dist/hono/routes/llm.d.ts.map +1 -1
- package/dist/hono/routes/llm.js +386 -349
- package/dist/hono/routes/mcp.cjs +257 -226
- package/dist/hono/routes/mcp.d.ts +6605 -309
- package/dist/hono/routes/mcp.d.ts.map +1 -1
- package/dist/hono/routes/mcp.js +263 -225
- package/dist/hono/routes/memory.cjs +102 -89
- package/dist/hono/routes/memory.d.ts +5368 -4
- package/dist/hono/routes/memory.d.ts.map +1 -1
- package/dist/hono/routes/memory.js +108 -90
- package/dist/hono/routes/messages.cjs +189 -191
- package/dist/hono/routes/messages.d.ts +3900 -12
- package/dist/hono/routes/messages.d.ts.map +1 -1
- package/dist/hono/routes/messages.js +192 -191
- package/dist/hono/routes/models.cjs +106 -64
- package/dist/hono/routes/models.d.ts +2875 -2
- package/dist/hono/routes/models.d.ts.map +1 -1
- package/dist/hono/routes/models.js +108 -64
- package/dist/hono/routes/openrouter.cjs +79 -65
- package/dist/hono/routes/openrouter.d.ts +854 -1
- package/dist/hono/routes/openrouter.d.ts.map +1 -1
- package/dist/hono/routes/openrouter.js +79 -65
- package/dist/hono/routes/prompts.cjs +136 -109
- package/dist/hono/routes/prompts.d.ts +2818 -10
- package/dist/hono/routes/prompts.d.ts.map +1 -1
- package/dist/hono/routes/prompts.js +138 -109
- package/dist/hono/routes/queue.cjs +133 -120
- package/dist/hono/routes/queue.d.ts +5240 -11
- package/dist/hono/routes/queue.d.ts.map +1 -1
- package/dist/hono/routes/queue.js +136 -120
- package/dist/hono/routes/resources.cjs +65 -46
- package/dist/hono/routes/resources.d.ts +1983 -5
- package/dist/hono/routes/resources.d.ts.map +1 -1
- package/dist/hono/routes/resources.js +72 -47
- package/dist/hono/routes/schedules.cjs +233 -226
- package/dist/hono/routes/schedules.d.ts +4198 -22
- package/dist/hono/routes/schedules.d.ts.map +1 -1
- package/dist/hono/routes/schedules.js +233 -226
- package/dist/hono/routes/search.cjs +34 -30
- package/dist/hono/routes/search.d.ts +3094 -17
- package/dist/hono/routes/search.d.ts.map +1 -1
- package/dist/hono/routes/search.js +40 -31
- package/dist/hono/routes/sessions.cjs +491 -393
- package/dist/hono/routes/sessions.d.ts +18263 -65
- package/dist/hono/routes/sessions.d.ts.map +1 -1
- package/dist/hono/routes/sessions.js +497 -395
- package/dist/hono/routes/static.d.ts.map +1 -1
- package/dist/hono/routes/system-prompt.cjs +57 -61
- package/dist/hono/routes/system-prompt.d.ts +1228 -2
- package/dist/hono/routes/system-prompt.d.ts.map +1 -1
- package/dist/hono/routes/system-prompt.js +58 -62
- package/dist/hono/routes/tools.cjs +29 -34
- package/dist/hono/routes/tools.d.ts +1755 -6
- package/dist/hono/routes/tools.d.ts.map +1 -1
- package/dist/hono/routes/tools.js +33 -33
- package/dist/hono/routes/webhooks.cjs +115 -123
- package/dist/hono/routes/webhooks.d.ts +2501 -11
- package/dist/hono/routes/webhooks.d.ts.map +1 -1
- package/dist/hono/routes/webhooks.js +120 -124
- package/dist/hono/routes/workspaces.cjs +84 -79
- package/dist/hono/routes/workspaces.d.ts +2093 -2
- package/dist/hono/routes/workspaces.d.ts.map +1 -1
- package/dist/hono/routes/workspaces.js +89 -80
- package/dist/hono/schemas/responses.cjs +463 -260
- package/dist/hono/schemas/responses.d.ts +1893 -209
- package/dist/hono/schemas/responses.d.ts.map +1 -1
- package/dist/hono/schemas/responses.js +203 -14
- package/dist/hono/start-server.cjs +9 -0
- package/dist/hono/start-server.d.ts.map +1 -1
- package/dist/hono/start-server.js +9 -0
- package/dist/hono/types.d.ts +11 -0
- package/dist/hono/types.d.ts.map +1 -1
- package/dist/index.cjs +5 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/package.json +7 -7
|
@@ -14,8 +14,15 @@ import os from "os";
|
|
|
14
14
|
import path from "path";
|
|
15
15
|
import { promises as fs } from "fs";
|
|
16
16
|
import { DextoValidationError, AgentErrorCode, ErrorScope, ErrorType } from "@dexto/core";
|
|
17
|
-
import {
|
|
18
|
-
|
|
17
|
+
import {
|
|
18
|
+
AgentRegistryEntrySchema,
|
|
19
|
+
BadRequestErrorResponse,
|
|
20
|
+
ConflictErrorResponse,
|
|
21
|
+
InternalErrorResponse,
|
|
22
|
+
JsonValueSchema,
|
|
23
|
+
NotFoundErrorResponse
|
|
24
|
+
} from "../schemas/responses.js";
|
|
25
|
+
const AgentConfigSchemaForOpenAPI = z.record(z.string(), JsonValueSchema).describe(
|
|
19
26
|
"Complete agent configuration. See AgentConfig type documentation for full schema details."
|
|
20
27
|
);
|
|
21
28
|
const AgentIdentifierSchema = z.object({
|
|
@@ -116,296 +123,341 @@ const SaveConfigResponseSchema = z.object({
|
|
|
116
123
|
changesApplied: z.array(z.string()).describe("List of changes that were applied"),
|
|
117
124
|
message: z.string().describe("Success message")
|
|
118
125
|
}).strict().describe("Configuration save result");
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
const installRoute = createRoute({
|
|
156
|
-
method: "post",
|
|
157
|
-
path: "/agents/install",
|
|
158
|
-
summary: "Install Agent",
|
|
159
|
-
description: "Installs an agent from the registry or from a custom source",
|
|
160
|
-
tags: ["agents"],
|
|
161
|
-
request: {
|
|
162
|
-
body: {
|
|
163
|
-
content: {
|
|
164
|
-
"application/json": {
|
|
165
|
-
schema: z.union([CustomAgentInstallSchema, AgentIdentifierSchema])
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
126
|
+
const CreateCustomAgentResponseSchema = z.object({
|
|
127
|
+
created: z.literal(true).describe("Creation success indicator"),
|
|
128
|
+
id: z.string().describe("Agent identifier"),
|
|
129
|
+
name: z.string().describe("Agent name")
|
|
130
|
+
}).strict().describe("Custom agent creation response");
|
|
131
|
+
const ValidateConfigErrorSchema = z.object({
|
|
132
|
+
line: z.number().int().optional().describe("Line number"),
|
|
133
|
+
column: z.number().int().optional().describe("Column number"),
|
|
134
|
+
path: z.string().optional().describe("Configuration path"),
|
|
135
|
+
message: z.string().describe("Error message"),
|
|
136
|
+
code: z.string().describe("Error code")
|
|
137
|
+
}).passthrough().describe("Configuration validation error");
|
|
138
|
+
const ValidateConfigWarningSchema = z.object({
|
|
139
|
+
path: z.string().describe("Configuration path"),
|
|
140
|
+
message: z.string().describe("Warning message"),
|
|
141
|
+
code: z.string().describe("Warning code")
|
|
142
|
+
}).strict().describe("Configuration validation warning");
|
|
143
|
+
const ValidateConfigResponseSchema = z.object({
|
|
144
|
+
valid: z.boolean().describe("Whether configuration is valid"),
|
|
145
|
+
errors: z.array(ValidateConfigErrorSchema).describe("Validation errors"),
|
|
146
|
+
warnings: z.array(ValidateConfigWarningSchema).describe("Configuration warnings")
|
|
147
|
+
}).strict().describe("Configuration validation result");
|
|
148
|
+
const ExportConfigQuerySchema = z.object({
|
|
149
|
+
sessionId: z.string().optional().describe("Session identifier to export session-specific configuration")
|
|
150
|
+
}).describe("Export configuration query");
|
|
151
|
+
const InstallAgentRequestSchema = z.union([CustomAgentInstallSchema, AgentIdentifierSchema]).describe("Agent installation request");
|
|
152
|
+
const listRoute = createRoute({
|
|
153
|
+
method: "get",
|
|
154
|
+
path: "/agents",
|
|
155
|
+
summary: "List Agents",
|
|
156
|
+
description: "Retrieves all agents (installed, available, and current active agent)",
|
|
157
|
+
tags: ["agents"],
|
|
158
|
+
responses: {
|
|
159
|
+
200: {
|
|
160
|
+
description: "List all agents",
|
|
161
|
+
content: { "application/json": { schema: ListAgentsResponseSchema } }
|
|
169
162
|
},
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
body: {
|
|
185
|
-
content: {
|
|
186
|
-
"application/json": {
|
|
187
|
-
schema: AgentIdentifierSchema
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
163
|
+
400: BadRequestErrorResponse,
|
|
164
|
+
500: InternalErrorResponse
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
const currentRoute = createRoute({
|
|
168
|
+
method: "get",
|
|
169
|
+
path: "/agents/current",
|
|
170
|
+
summary: "Get Current Agent",
|
|
171
|
+
description: "Retrieves the currently active agent",
|
|
172
|
+
tags: ["agents"],
|
|
173
|
+
responses: {
|
|
174
|
+
200: {
|
|
175
|
+
description: "Current agent",
|
|
176
|
+
content: { "application/json": { schema: AgentInfoNullableSchema } }
|
|
191
177
|
},
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
178
|
+
400: BadRequestErrorResponse,
|
|
179
|
+
500: InternalErrorResponse
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
const installRoute = createRoute({
|
|
183
|
+
method: "post",
|
|
184
|
+
path: "/agents/install",
|
|
185
|
+
summary: "Install Agent",
|
|
186
|
+
description: "Installs an agent from the registry or from a custom source",
|
|
187
|
+
tags: ["agents"],
|
|
188
|
+
request: {
|
|
189
|
+
body: {
|
|
190
|
+
content: {
|
|
191
|
+
"application/json": {
|
|
192
|
+
schema: InstallAgentRequestSchema
|
|
193
|
+
}
|
|
196
194
|
}
|
|
197
195
|
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
196
|
+
},
|
|
197
|
+
responses: {
|
|
198
|
+
201: {
|
|
199
|
+
description: "Agent installed",
|
|
200
|
+
content: { "application/json": { schema: InstallAgentResponseSchema } }
|
|
201
|
+
},
|
|
202
|
+
400: BadRequestErrorResponse,
|
|
203
|
+
404: NotFoundErrorResponse,
|
|
204
|
+
409: ConflictErrorResponse,
|
|
205
|
+
500: InternalErrorResponse
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
const switchRoute = createRoute({
|
|
209
|
+
method: "post",
|
|
210
|
+
path: "/agents/switch",
|
|
211
|
+
summary: "Switch Agent",
|
|
212
|
+
description: "Switches to a different agent by ID or file path",
|
|
213
|
+
tags: ["agents"],
|
|
214
|
+
request: {
|
|
215
|
+
body: {
|
|
216
|
+
content: {
|
|
217
|
+
"application/json": {
|
|
218
|
+
schema: AgentIdentifierSchema
|
|
211
219
|
}
|
|
212
220
|
}
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
responses: {
|
|
224
|
+
200: {
|
|
225
|
+
description: "Agent switched",
|
|
226
|
+
content: { "application/json": { schema: SwitchAgentResponseSchema } }
|
|
213
227
|
},
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
228
|
+
400: BadRequestErrorResponse,
|
|
229
|
+
404: NotFoundErrorResponse,
|
|
230
|
+
409: ConflictErrorResponse,
|
|
231
|
+
500: InternalErrorResponse
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
const validateNameRoute = createRoute({
|
|
235
|
+
method: "post",
|
|
236
|
+
path: "/agents/validate-name",
|
|
237
|
+
summary: "Validate Agent Name",
|
|
238
|
+
description: "Checks if an agent ID conflicts with existing agents",
|
|
239
|
+
tags: ["agents"],
|
|
240
|
+
request: {
|
|
241
|
+
body: {
|
|
242
|
+
content: {
|
|
243
|
+
"application/json": {
|
|
244
|
+
schema: AgentIdentifierSchema
|
|
245
|
+
}
|
|
218
246
|
}
|
|
219
247
|
}
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
248
|
+
},
|
|
249
|
+
responses: {
|
|
250
|
+
200: {
|
|
251
|
+
description: "Name validation result",
|
|
252
|
+
content: { "application/json": { schema: ValidateNameResponseSchema } }
|
|
253
|
+
},
|
|
254
|
+
400: BadRequestErrorResponse,
|
|
255
|
+
404: NotFoundErrorResponse,
|
|
256
|
+
409: ConflictErrorResponse,
|
|
257
|
+
500: InternalErrorResponse
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
const uninstallRoute = createRoute({
|
|
261
|
+
method: "post",
|
|
262
|
+
path: "/agents/uninstall",
|
|
263
|
+
summary: "Uninstall Agent",
|
|
264
|
+
description: "Removes an agent from the system. Custom agents are removed from registry; builtin agents can be reinstalled",
|
|
265
|
+
tags: ["agents"],
|
|
266
|
+
request: {
|
|
267
|
+
body: {
|
|
268
|
+
content: {
|
|
269
|
+
"application/json": {
|
|
270
|
+
schema: UninstallAgentSchema
|
|
233
271
|
}
|
|
234
272
|
}
|
|
273
|
+
}
|
|
274
|
+
},
|
|
275
|
+
responses: {
|
|
276
|
+
200: {
|
|
277
|
+
description: "Agent uninstalled",
|
|
278
|
+
content: { "application/json": { schema: UninstallAgentResponseSchema } }
|
|
235
279
|
},
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
280
|
+
400: BadRequestErrorResponse,
|
|
281
|
+
404: NotFoundErrorResponse,
|
|
282
|
+
409: ConflictErrorResponse,
|
|
283
|
+
500: InternalErrorResponse
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
const customCreateRoute = createRoute({
|
|
287
|
+
method: "post",
|
|
288
|
+
path: "/agents/custom/create",
|
|
289
|
+
summary: "Create Custom Agent",
|
|
290
|
+
description: "Creates a new custom agent from scratch via the UI/API",
|
|
291
|
+
tags: ["agents"],
|
|
292
|
+
request: {
|
|
293
|
+
body: {
|
|
294
|
+
content: {
|
|
295
|
+
"application/json": {
|
|
296
|
+
schema: CustomAgentCreateSchema
|
|
297
|
+
}
|
|
240
298
|
}
|
|
241
299
|
}
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
request: {
|
|
250
|
-
body: {
|
|
251
|
-
content: {
|
|
252
|
-
"application/json": {
|
|
253
|
-
schema: CustomAgentCreateSchema
|
|
254
|
-
}
|
|
300
|
+
},
|
|
301
|
+
responses: {
|
|
302
|
+
201: {
|
|
303
|
+
description: "Custom agent created",
|
|
304
|
+
content: {
|
|
305
|
+
"application/json": {
|
|
306
|
+
schema: CreateCustomAgentResponseSchema
|
|
255
307
|
}
|
|
256
308
|
}
|
|
257
309
|
},
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
310
|
+
400: BadRequestErrorResponse,
|
|
311
|
+
404: NotFoundErrorResponse,
|
|
312
|
+
409: ConflictErrorResponse,
|
|
313
|
+
500: InternalErrorResponse
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
const getPathRoute = createRoute({
|
|
317
|
+
method: "get",
|
|
318
|
+
path: "/agent/path",
|
|
319
|
+
summary: "Get Agent File Path",
|
|
320
|
+
description: "Retrieves the file path of the currently active agent configuration",
|
|
321
|
+
tags: ["agent"],
|
|
322
|
+
responses: {
|
|
323
|
+
200: {
|
|
324
|
+
description: "Agent file path",
|
|
325
|
+
content: {
|
|
326
|
+
"application/json": {
|
|
327
|
+
schema: AgentPathResponseSchema
|
|
269
328
|
}
|
|
270
329
|
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
330
|
+
},
|
|
331
|
+
400: BadRequestErrorResponse,
|
|
332
|
+
404: NotFoundErrorResponse,
|
|
333
|
+
409: ConflictErrorResponse,
|
|
334
|
+
500: InternalErrorResponse
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
const getConfigRoute = createRoute({
|
|
338
|
+
method: "get",
|
|
339
|
+
path: "/agent/config",
|
|
340
|
+
summary: "Get Agent Configuration",
|
|
341
|
+
description: "Retrieves the raw YAML configuration of the currently active agent",
|
|
342
|
+
tags: ["agent"],
|
|
343
|
+
responses: {
|
|
344
|
+
200: {
|
|
345
|
+
description: "Agent configuration",
|
|
346
|
+
content: {
|
|
347
|
+
"application/json": {
|
|
348
|
+
schema: AgentConfigResponseSchema
|
|
286
349
|
}
|
|
287
350
|
}
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
351
|
+
},
|
|
352
|
+
400: BadRequestErrorResponse,
|
|
353
|
+
404: NotFoundErrorResponse,
|
|
354
|
+
409: ConflictErrorResponse,
|
|
355
|
+
500: InternalErrorResponse
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
const validateConfigRoute = createRoute({
|
|
359
|
+
method: "post",
|
|
360
|
+
path: "/agent/validate",
|
|
361
|
+
summary: "Validate Agent Configuration",
|
|
362
|
+
description: "Validates YAML agent configuration without saving it",
|
|
363
|
+
tags: ["agent"],
|
|
364
|
+
request: {
|
|
365
|
+
body: {
|
|
366
|
+
content: {
|
|
367
|
+
"application/json": {
|
|
368
|
+
schema: AgentConfigValidateSchema
|
|
303
369
|
}
|
|
304
370
|
}
|
|
305
371
|
}
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
request: {
|
|
314
|
-
body: {
|
|
315
|
-
content: {
|
|
316
|
-
"application/json": {
|
|
317
|
-
schema: AgentConfigValidateSchema
|
|
318
|
-
}
|
|
372
|
+
},
|
|
373
|
+
responses: {
|
|
374
|
+
200: {
|
|
375
|
+
description: "Validation result",
|
|
376
|
+
content: {
|
|
377
|
+
"application/json": {
|
|
378
|
+
schema: ValidateConfigResponseSchema
|
|
319
379
|
}
|
|
320
380
|
}
|
|
321
381
|
},
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
z.object({
|
|
340
|
-
path: z.string().describe("Configuration path"),
|
|
341
|
-
message: z.string().describe("Warning message"),
|
|
342
|
-
code: z.string().describe("Warning code")
|
|
343
|
-
}).strict()
|
|
344
|
-
).describe("Configuration warnings")
|
|
345
|
-
}).strict()
|
|
346
|
-
}
|
|
382
|
+
400: BadRequestErrorResponse,
|
|
383
|
+
404: NotFoundErrorResponse,
|
|
384
|
+
409: ConflictErrorResponse,
|
|
385
|
+
500: InternalErrorResponse
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
const saveConfigRoute = createRoute({
|
|
389
|
+
method: "post",
|
|
390
|
+
path: "/agent/config",
|
|
391
|
+
summary: "Save Agent Configuration",
|
|
392
|
+
description: "Saves and applies YAML agent configuration. Creates backup before saving",
|
|
393
|
+
tags: ["agent"],
|
|
394
|
+
request: {
|
|
395
|
+
body: {
|
|
396
|
+
content: {
|
|
397
|
+
"application/json": {
|
|
398
|
+
schema: AgentConfigSaveSchema
|
|
347
399
|
}
|
|
348
400
|
}
|
|
349
401
|
}
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
request: {
|
|
358
|
-
body: {
|
|
359
|
-
content: {
|
|
360
|
-
"application/json": {
|
|
361
|
-
schema: AgentConfigSaveSchema
|
|
362
|
-
}
|
|
402
|
+
},
|
|
403
|
+
responses: {
|
|
404
|
+
200: {
|
|
405
|
+
description: "Configuration saved",
|
|
406
|
+
content: {
|
|
407
|
+
"application/json": {
|
|
408
|
+
schema: SaveConfigResponseSchema
|
|
363
409
|
}
|
|
364
410
|
}
|
|
365
411
|
},
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
412
|
+
400: BadRequestErrorResponse,
|
|
413
|
+
404: NotFoundErrorResponse,
|
|
414
|
+
409: ConflictErrorResponse,
|
|
415
|
+
500: InternalErrorResponse
|
|
416
|
+
}
|
|
417
|
+
});
|
|
418
|
+
const exportConfigRoute = createRoute({
|
|
419
|
+
method: "get",
|
|
420
|
+
path: "/agent/config/export",
|
|
421
|
+
summary: "Export Agent Configuration",
|
|
422
|
+
description: "Exports the effective agent configuration with sensitive values redacted",
|
|
423
|
+
tags: ["agent"],
|
|
424
|
+
request: {
|
|
425
|
+
query: ExportConfigQuerySchema
|
|
426
|
+
},
|
|
427
|
+
responses: {
|
|
428
|
+
200: {
|
|
429
|
+
description: "Exported configuration",
|
|
430
|
+
content: { "application/x-yaml": { schema: z.string() } }
|
|
375
431
|
}
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
sessionId: z.string().optional().describe("Session identifier to export session-specific configuration")
|
|
386
|
-
})
|
|
387
|
-
},
|
|
388
|
-
responses: {
|
|
389
|
-
200: {
|
|
390
|
-
description: "Exported configuration",
|
|
391
|
-
content: { "application/x-yaml": { schema: z.string() } }
|
|
392
|
-
}
|
|
432
|
+
}
|
|
433
|
+
});
|
|
434
|
+
function createAgentsRouter(getAgent, context, getAgentConfigPath) {
|
|
435
|
+
const app = new OpenAPIHono();
|
|
436
|
+
const { switchAgentById, switchAgentByPath, resolveAgentInfo, getActiveAgentId } = context;
|
|
437
|
+
const resolveAgentConfigPath = async (ctx) => {
|
|
438
|
+
const configPath = await getAgentConfigPath(ctx);
|
|
439
|
+
if (!configPath) {
|
|
440
|
+
throw AgentError.noConfigPath();
|
|
393
441
|
}
|
|
394
|
-
|
|
442
|
+
return configPath;
|
|
443
|
+
};
|
|
395
444
|
return app.openapi(listRoute, async (ctx) => {
|
|
396
445
|
const agents = await AgentFactory.listAgents();
|
|
397
446
|
const currentId = getActiveAgentId() ?? null;
|
|
398
|
-
return ctx.json(
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
447
|
+
return ctx.json(
|
|
448
|
+
{
|
|
449
|
+
installed: agents.installed,
|
|
450
|
+
available: agents.available,
|
|
451
|
+
current: currentId ? await resolveAgentInfo(currentId) : { id: null, name: null }
|
|
452
|
+
},
|
|
453
|
+
200
|
|
454
|
+
);
|
|
403
455
|
}).openapi(currentRoute, async (ctx) => {
|
|
404
456
|
const currentId = getActiveAgentId() ?? null;
|
|
405
457
|
if (!currentId) {
|
|
406
|
-
return ctx.json({ id: null, name: null });
|
|
458
|
+
return ctx.json({ id: null, name: null }, 200);
|
|
407
459
|
}
|
|
408
|
-
return ctx.json(await resolveAgentInfo(currentId));
|
|
460
|
+
return ctx.json(await resolveAgentInfo(currentId), 200);
|
|
409
461
|
}).openapi(installRoute, async (ctx) => {
|
|
410
462
|
const body = ctx.req.valid("json");
|
|
411
463
|
if ("sourcePath" in body && "metadata" in body) {
|
|
@@ -436,53 +488,68 @@ function createAgentsRouter(getAgent, context, getAgentConfigPath) {
|
|
|
436
488
|
}).openapi(switchRoute, async (ctx) => {
|
|
437
489
|
const { id, path: filePath } = ctx.req.valid("json");
|
|
438
490
|
const result = filePath ? await switchAgentByPath(filePath) : await switchAgentById(id);
|
|
439
|
-
return ctx.json({ switched: true, ...result });
|
|
491
|
+
return ctx.json({ switched: true, ...result }, 200);
|
|
440
492
|
}).openapi(validateNameRoute, async (ctx) => {
|
|
441
493
|
const { id } = ctx.req.valid("json");
|
|
442
494
|
const agents = await AgentFactory.listAgents();
|
|
443
495
|
const installedAgent = agents.installed.find((a) => a.id === id);
|
|
444
496
|
if (installedAgent) {
|
|
445
|
-
return ctx.json(
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
497
|
+
return ctx.json(
|
|
498
|
+
{
|
|
499
|
+
valid: false,
|
|
500
|
+
conflict: installedAgent.type,
|
|
501
|
+
message: `Agent id '${id}' already exists (${installedAgent.type})`
|
|
502
|
+
},
|
|
503
|
+
200
|
|
504
|
+
);
|
|
450
505
|
}
|
|
451
506
|
const availableAgent = agents.available.find((a) => a.id === id);
|
|
452
507
|
if (availableAgent) {
|
|
453
|
-
return ctx.json(
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
508
|
+
return ctx.json(
|
|
509
|
+
{
|
|
510
|
+
valid: false,
|
|
511
|
+
conflict: availableAgent.type,
|
|
512
|
+
message: `Agent id '${id}' conflicts with ${availableAgent.type} agent`
|
|
513
|
+
},
|
|
514
|
+
200
|
|
515
|
+
);
|
|
458
516
|
}
|
|
459
|
-
return ctx.json({ valid: true });
|
|
517
|
+
return ctx.json({ valid: true }, 200);
|
|
460
518
|
}).openapi(uninstallRoute, async (ctx) => {
|
|
461
519
|
const { id, force } = ctx.req.valid("json");
|
|
462
520
|
await AgentFactory.uninstallAgent(id, force);
|
|
463
|
-
return ctx.json({ uninstalled: true, id });
|
|
521
|
+
return ctx.json({ uninstalled: true, id }, 200);
|
|
464
522
|
}).openapi(customCreateRoute, async (ctx) => {
|
|
465
523
|
const { id, name, description, author, tags, config } = ctx.req.valid("json");
|
|
466
|
-
const
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
524
|
+
const configResult = AgentConfigSchema.safeParse(config);
|
|
525
|
+
if (!configResult.success) {
|
|
526
|
+
throw new DextoValidationError(zodToIssues(configResult.error));
|
|
527
|
+
}
|
|
528
|
+
const validatedConfig = configResult.data;
|
|
529
|
+
const provider = validatedConfig.llm.provider;
|
|
530
|
+
let agentConfig = validatedConfig;
|
|
531
|
+
if (validatedConfig.llm.apiKey && !validatedConfig.llm.apiKey.startsWith("$")) {
|
|
532
|
+
const meta = await saveProviderApiKey(
|
|
533
|
+
provider,
|
|
534
|
+
validatedConfig.llm.apiKey,
|
|
535
|
+
process.cwd()
|
|
536
|
+
);
|
|
470
537
|
const apiKeyRef = `$${meta.envVar}`;
|
|
471
538
|
logger.info(
|
|
472
539
|
`Stored API key securely for ${provider}, using env var: ${meta.envVar}`
|
|
473
540
|
);
|
|
474
541
|
agentConfig = {
|
|
475
|
-
...
|
|
542
|
+
...validatedConfig,
|
|
476
543
|
llm: {
|
|
477
|
-
...
|
|
544
|
+
...validatedConfig.llm,
|
|
478
545
|
apiKey: apiKeyRef
|
|
479
546
|
}
|
|
480
547
|
};
|
|
481
|
-
} else if (!
|
|
548
|
+
} else if (!validatedConfig.llm.apiKey) {
|
|
482
549
|
agentConfig = {
|
|
483
|
-
...
|
|
550
|
+
...validatedConfig,
|
|
484
551
|
llm: {
|
|
485
|
-
...
|
|
552
|
+
...validatedConfig.llm,
|
|
486
553
|
apiKey: `$${getPrimaryApiKeyEnvVar(provider)}`
|
|
487
554
|
}
|
|
488
555
|
};
|
|
@@ -514,26 +581,32 @@ function createAgentsRouter(getAgent, context, getAgentConfigPath) {
|
|
|
514
581
|
const relativePath = path.basename(agentPath);
|
|
515
582
|
const ext = path.extname(agentPath);
|
|
516
583
|
const name = path.basename(agentPath, ext);
|
|
517
|
-
return ctx.json(
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
584
|
+
return ctx.json(
|
|
585
|
+
{
|
|
586
|
+
path: agentPath,
|
|
587
|
+
relativePath,
|
|
588
|
+
name,
|
|
589
|
+
isDefault: name === "coding-agent"
|
|
590
|
+
},
|
|
591
|
+
200
|
|
592
|
+
);
|
|
523
593
|
}).openapi(getConfigRoute, async (ctx) => {
|
|
524
594
|
const agentPath = await resolveAgentConfigPath(ctx);
|
|
525
595
|
const yamlContent = await fs.readFile(agentPath, "utf-8");
|
|
526
596
|
const stats = await fs.stat(agentPath);
|
|
527
|
-
return ctx.json(
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
597
|
+
return ctx.json(
|
|
598
|
+
{
|
|
599
|
+
yaml: yamlContent,
|
|
600
|
+
path: agentPath,
|
|
601
|
+
relativePath: path.basename(agentPath),
|
|
602
|
+
lastModified: stats.mtime,
|
|
603
|
+
warnings: [
|
|
604
|
+
"Environment variables ($VAR) will be resolved at runtime",
|
|
605
|
+
"API keys should use environment variables"
|
|
606
|
+
]
|
|
607
|
+
},
|
|
608
|
+
200
|
|
609
|
+
);
|
|
537
610
|
}).openapi(validateConfigRoute, async (ctx) => {
|
|
538
611
|
const { yaml } = ctx.req.valid("json");
|
|
539
612
|
let parsed;
|
|
@@ -542,32 +615,38 @@ function createAgentsRouter(getAgent, context, getAgentConfigPath) {
|
|
|
542
615
|
} catch (parseError) {
|
|
543
616
|
const message = parseError instanceof Error ? parseError.message : String(parseError);
|
|
544
617
|
const linePos = typeof parseError === "object" && parseError !== null && "linePos" in parseError ? parseError.linePos : void 0;
|
|
545
|
-
return ctx.json(
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
618
|
+
return ctx.json(
|
|
619
|
+
{
|
|
620
|
+
valid: false,
|
|
621
|
+
errors: [
|
|
622
|
+
{
|
|
623
|
+
line: linePos?.[0]?.line ?? 1,
|
|
624
|
+
column: linePos?.[0]?.col ?? 1,
|
|
625
|
+
message,
|
|
626
|
+
code: "YAML_PARSE_ERROR"
|
|
627
|
+
}
|
|
628
|
+
],
|
|
629
|
+
warnings: []
|
|
630
|
+
},
|
|
631
|
+
200
|
|
632
|
+
);
|
|
557
633
|
}
|
|
558
634
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
559
|
-
return ctx.json(
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
635
|
+
return ctx.json(
|
|
636
|
+
{
|
|
637
|
+
valid: false,
|
|
638
|
+
errors: [
|
|
639
|
+
{
|
|
640
|
+
line: 1,
|
|
641
|
+
column: 1,
|
|
642
|
+
message: "Configuration must be a valid YAML object",
|
|
643
|
+
code: "INVALID_CONFIG_TYPE"
|
|
644
|
+
}
|
|
645
|
+
],
|
|
646
|
+
warnings: []
|
|
647
|
+
},
|
|
648
|
+
200
|
|
649
|
+
);
|
|
571
650
|
}
|
|
572
651
|
const enriched = enrichAgentConfig(parsed, void 0);
|
|
573
652
|
const result = AgentConfigSchema.safeParse(enriched);
|
|
@@ -578,11 +657,14 @@ function createAgentsRouter(getAgent, context, getAgentConfigPath) {
|
|
|
578
657
|
message: issue.message,
|
|
579
658
|
code: "SCHEMA_VALIDATION_ERROR"
|
|
580
659
|
}));
|
|
581
|
-
return ctx.json(
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
660
|
+
return ctx.json(
|
|
661
|
+
{
|
|
662
|
+
valid: false,
|
|
663
|
+
errors,
|
|
664
|
+
warnings: []
|
|
665
|
+
},
|
|
666
|
+
200
|
|
667
|
+
);
|
|
586
668
|
}
|
|
587
669
|
const warnings = [];
|
|
588
670
|
if (parsed.llm?.apiKey && !parsed.llm.apiKey.startsWith("$")) {
|
|
@@ -592,11 +674,14 @@ function createAgentsRouter(getAgent, context, getAgentConfigPath) {
|
|
|
592
674
|
code: "SECURITY_WARNING"
|
|
593
675
|
});
|
|
594
676
|
}
|
|
595
|
-
return ctx.json(
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
677
|
+
return ctx.json(
|
|
678
|
+
{
|
|
679
|
+
valid: true,
|
|
680
|
+
errors: [],
|
|
681
|
+
warnings
|
|
682
|
+
},
|
|
683
|
+
200
|
|
684
|
+
);
|
|
600
685
|
}).openapi(saveConfigRoute, async (ctx) => {
|
|
601
686
|
const { yaml } = ctx.req.valid("json");
|
|
602
687
|
let parsed;
|
|
@@ -647,14 +732,17 @@ function createAgentsRouter(getAgent, context, getAgentConfigPath) {
|
|
|
647
732
|
await fs.unlink(backupPath).catch(() => {
|
|
648
733
|
});
|
|
649
734
|
logger.info(`Agent configuration saved and applied: ${agentPath}`);
|
|
650
|
-
return ctx.json(
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
735
|
+
return ctx.json(
|
|
736
|
+
{
|
|
737
|
+
ok: true,
|
|
738
|
+
path: agentPath,
|
|
739
|
+
reloaded: true,
|
|
740
|
+
restarted: true,
|
|
741
|
+
changesApplied: ["restart"],
|
|
742
|
+
message: "Configuration saved and applied successfully (agent restarted)"
|
|
743
|
+
},
|
|
744
|
+
200
|
|
745
|
+
);
|
|
658
746
|
} catch (error) {
|
|
659
747
|
await fs.copyFile(backupPath, agentPath).catch(() => {
|
|
660
748
|
});
|