@dexto/server 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/approval/manual-approval-handler.cjs +23 -15
- package/dist/approval/manual-approval-handler.d.ts.map +1 -1
- package/dist/approval/manual-approval-handler.js +23 -15
- package/dist/events/webhook-subscriber.cjs +1 -1
- package/dist/events/webhook-subscriber.d.ts.map +1 -1
- package/dist/events/webhook-subscriber.js +1 -1
- package/dist/hono/__tests__/test-fixtures.cjs +2 -2
- package/dist/hono/__tests__/test-fixtures.d.ts.map +1 -1
- package/dist/hono/__tests__/test-fixtures.js +2 -2
- package/dist/hono/index.cjs +6 -1
- package/dist/hono/index.d.ts +433 -88
- package/dist/hono/index.d.ts.map +1 -1
- package/dist/hono/index.js +6 -1
- package/dist/hono/middleware/error.d.ts.map +1 -1
- package/dist/hono/routes/agents.cjs +8 -10
- package/dist/hono/routes/agents.d.ts +15 -8
- package/dist/hono/routes/agents.d.ts.map +1 -1
- package/dist/hono/routes/agents.js +10 -10
- package/dist/hono/routes/approvals.cjs +52 -1
- package/dist/hono/routes/approvals.d.ts +25 -0
- package/dist/hono/routes/approvals.d.ts.map +1 -1
- package/dist/hono/routes/approvals.js +52 -1
- package/dist/hono/routes/llm.cjs +110 -31
- package/dist/hono/routes/llm.d.ts +72 -20
- package/dist/hono/routes/llm.d.ts.map +1 -1
- package/dist/hono/routes/llm.js +108 -25
- package/dist/hono/routes/mcp.cjs +8 -4
- package/dist/hono/routes/mcp.d.ts +4 -1
- package/dist/hono/routes/mcp.d.ts.map +1 -1
- package/dist/hono/routes/mcp.js +9 -5
- package/dist/hono/routes/memory.d.ts +1 -1
- package/dist/hono/routes/messages.cjs +54 -62
- package/dist/hono/routes/messages.d.ts +87 -43
- package/dist/hono/routes/messages.d.ts.map +1 -1
- package/dist/hono/routes/messages.js +55 -63
- package/dist/hono/routes/prompts.d.ts +6 -6
- package/dist/hono/routes/queue.cjs +202 -0
- package/dist/hono/routes/queue.d.ts +171 -0
- package/dist/hono/routes/queue.d.ts.map +1 -0
- package/dist/hono/routes/queue.js +178 -0
- package/dist/hono/routes/resources.d.ts +1 -1
- package/dist/hono/routes/search.d.ts +33 -7
- package/dist/hono/routes/search.d.ts.map +1 -1
- package/dist/hono/routes/sessions.cjs +65 -11
- package/dist/hono/routes/sessions.d.ts +22 -1
- package/dist/hono/routes/sessions.d.ts.map +1 -1
- package/dist/hono/routes/sessions.js +65 -11
- package/dist/hono/schemas/responses.cjs +24 -5
- package/dist/hono/schemas/responses.d.ts +799 -81
- package/dist/hono/schemas/responses.d.ts.map +1 -1
- package/dist/hono/schemas/responses.js +24 -10
- package/package.json +3 -3
package/dist/hono/routes/llm.cjs
CHANGED
|
@@ -23,6 +23,7 @@ __export(llm_exports, {
|
|
|
23
23
|
module.exports = __toCommonJS(llm_exports);
|
|
24
24
|
var import_zod_openapi = require("@hono/zod-openapi");
|
|
25
25
|
var import_core = require("@dexto/core");
|
|
26
|
+
var import_core2 = require("@dexto/core");
|
|
26
27
|
var import_agent_management = require("@dexto/agent-management");
|
|
27
28
|
var import_responses = require("../schemas/responses.js");
|
|
28
29
|
const CurrentQuerySchema = import_zod_openapi.z.object({
|
|
@@ -35,18 +36,17 @@ const CatalogQuerySchema = import_zod_openapi.z.object({
|
|
|
35
36
|
hasKey: import_zod_openapi.z.union([import_zod_openapi.z.literal("true"), import_zod_openapi.z.literal("false"), import_zod_openapi.z.literal("1"), import_zod_openapi.z.literal("0")]).optional().transform(
|
|
36
37
|
(raw) => raw === "true" || raw === "1" ? true : raw === "false" || raw === "0" ? false : void 0
|
|
37
38
|
).describe("Filter by API key presence (true or false)"),
|
|
38
|
-
|
|
39
|
-
fileType: import_zod_openapi.z.enum(import_core.SUPPORTED_FILE_TYPES).optional().describe("Filter by supported file type (audio, pdf, or image)"),
|
|
39
|
+
fileType: import_zod_openapi.z.enum(import_core2.SUPPORTED_FILE_TYPES).optional().describe("Filter by supported file type (audio, pdf, or image)"),
|
|
40
40
|
defaultOnly: import_zod_openapi.z.union([import_zod_openapi.z.literal("true"), import_zod_openapi.z.literal("false"), import_zod_openapi.z.literal("1"), import_zod_openapi.z.literal("0")]).optional().transform(
|
|
41
41
|
(raw) => raw === "true" || raw === "1" ? true : raw === "false" || raw === "0" ? false : void 0
|
|
42
42
|
).describe("Include only default models (true or false)"),
|
|
43
43
|
mode: import_zod_openapi.z.enum(["grouped", "flat"]).default("grouped").describe("Response format mode (grouped by provider or flat list)")
|
|
44
44
|
}).describe("Query parameters for filtering and formatting the LLM catalog");
|
|
45
45
|
const SaveKeySchema = import_zod_openapi.z.object({
|
|
46
|
-
provider: import_zod_openapi.z.enum(
|
|
46
|
+
provider: import_zod_openapi.z.enum(import_core2.LLM_PROVIDERS).describe("LLM provider identifier (e.g., openai, anthropic)"),
|
|
47
47
|
apiKey: import_zod_openapi.z.string().min(1, "API key is required").describe("API key for the provider (writeOnly - never returned in responses)").openapi({ writeOnly: true })
|
|
48
48
|
}).describe("Request body for saving a provider API key");
|
|
49
|
-
const SwitchLLMBodySchema =
|
|
49
|
+
const SwitchLLMBodySchema = import_core2.LLMUpdatesSchema.and(
|
|
50
50
|
import_zod_openapi.z.object({
|
|
51
51
|
sessionId: import_zod_openapi.z.string().optional().describe("Session identifier for session-specific LLM configuration")
|
|
52
52
|
})
|
|
@@ -67,8 +67,7 @@ function createLlmRouter(getAgent) {
|
|
|
67
67
|
"application/json": {
|
|
68
68
|
schema: import_zod_openapi.z.object({
|
|
69
69
|
config: import_responses.LLMConfigResponseSchema.partial({
|
|
70
|
-
maxIterations: true
|
|
71
|
-
router: true
|
|
70
|
+
maxIterations: true
|
|
72
71
|
}).extend({
|
|
73
72
|
displayName: import_zod_openapi.z.string().optional().describe("Human-readable model display name")
|
|
74
73
|
})
|
|
@@ -92,7 +91,7 @@ function createLlmRouter(getAgent) {
|
|
|
92
91
|
"application/json": {
|
|
93
92
|
schema: import_zod_openapi.z.union([
|
|
94
93
|
import_zod_openapi.z.object({
|
|
95
|
-
providers: import_zod_openapi.z.record(import_zod_openapi.z.enum(
|
|
94
|
+
providers: import_zod_openapi.z.record(import_zod_openapi.z.enum(import_core2.LLM_PROVIDERS), import_responses.ProviderCatalogSchema).describe(
|
|
96
95
|
"Providers grouped by ID with their models and capabilities"
|
|
97
96
|
)
|
|
98
97
|
}).strict().describe("Grouped catalog response (mode=grouped)"),
|
|
@@ -123,7 +122,7 @@ function createLlmRouter(getAgent) {
|
|
|
123
122
|
"application/json": {
|
|
124
123
|
schema: import_zod_openapi.z.object({
|
|
125
124
|
ok: import_zod_openapi.z.literal(true).describe("Operation success indicator"),
|
|
126
|
-
provider: import_zod_openapi.z.enum(
|
|
125
|
+
provider: import_zod_openapi.z.enum(import_core2.LLM_PROVIDERS).describe("Provider for which the key was saved"),
|
|
127
126
|
envVar: import_zod_openapi.z.string().describe("Environment variable name where key was stored")
|
|
128
127
|
}).strict().describe("API key save response")
|
|
129
128
|
}
|
|
@@ -162,13 +161,91 @@ function createLlmRouter(getAgent) {
|
|
|
162
161
|
}
|
|
163
162
|
}
|
|
164
163
|
});
|
|
164
|
+
const listCustomModelsRoute = (0, import_zod_openapi.createRoute)({
|
|
165
|
+
method: "get",
|
|
166
|
+
path: "/llm/custom-models",
|
|
167
|
+
summary: "List Custom Models",
|
|
168
|
+
description: "Returns all saved custom openai-compatible model configurations",
|
|
169
|
+
tags: ["llm"],
|
|
170
|
+
responses: {
|
|
171
|
+
200: {
|
|
172
|
+
description: "List of custom models",
|
|
173
|
+
content: {
|
|
174
|
+
"application/json": {
|
|
175
|
+
schema: import_zod_openapi.z.object({
|
|
176
|
+
models: import_zod_openapi.z.array(import_agent_management.CustomModelSchema).describe("List of custom models")
|
|
177
|
+
})
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
const createCustomModelRoute = (0, import_zod_openapi.createRoute)({
|
|
184
|
+
method: "post",
|
|
185
|
+
path: "/llm/custom-models",
|
|
186
|
+
summary: "Create Custom Model",
|
|
187
|
+
description: "Saves a new custom openai-compatible model configuration",
|
|
188
|
+
tags: ["llm"],
|
|
189
|
+
request: {
|
|
190
|
+
body: { content: { "application/json": { schema: import_agent_management.CustomModelSchema } } }
|
|
191
|
+
},
|
|
192
|
+
responses: {
|
|
193
|
+
200: {
|
|
194
|
+
description: "Custom model saved",
|
|
195
|
+
content: {
|
|
196
|
+
"application/json": {
|
|
197
|
+
schema: import_zod_openapi.z.object({
|
|
198
|
+
ok: import_zod_openapi.z.literal(true).describe("Success indicator"),
|
|
199
|
+
model: import_agent_management.CustomModelSchema
|
|
200
|
+
})
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
const deleteCustomModelRoute = (0, import_zod_openapi.createRoute)({
|
|
207
|
+
method: "delete",
|
|
208
|
+
path: "/llm/custom-models/{name}",
|
|
209
|
+
summary: "Delete Custom Model",
|
|
210
|
+
description: "Deletes a custom model by name",
|
|
211
|
+
tags: ["llm"],
|
|
212
|
+
request: {
|
|
213
|
+
params: import_zod_openapi.z.object({
|
|
214
|
+
name: import_zod_openapi.z.string().min(1).describe("Model name to delete")
|
|
215
|
+
})
|
|
216
|
+
},
|
|
217
|
+
responses: {
|
|
218
|
+
200: {
|
|
219
|
+
description: "Custom model deleted",
|
|
220
|
+
content: {
|
|
221
|
+
"application/json": {
|
|
222
|
+
schema: import_zod_openapi.z.object({
|
|
223
|
+
ok: import_zod_openapi.z.literal(true).describe("Success indicator"),
|
|
224
|
+
deleted: import_zod_openapi.z.string().describe("Name of the deleted model")
|
|
225
|
+
})
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
},
|
|
229
|
+
404: {
|
|
230
|
+
description: "Custom model not found",
|
|
231
|
+
content: {
|
|
232
|
+
"application/json": {
|
|
233
|
+
schema: import_zod_openapi.z.object({
|
|
234
|
+
ok: import_zod_openapi.z.literal(false).describe("Failure indicator"),
|
|
235
|
+
error: import_zod_openapi.z.string().describe("Error message")
|
|
236
|
+
})
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
});
|
|
165
242
|
return app.openapi(currentRoute, (ctx) => {
|
|
166
243
|
const agent = getAgent();
|
|
167
244
|
const { sessionId } = ctx.req.valid("query");
|
|
168
245
|
const currentConfig = sessionId ? agent.getEffectiveConfig(sessionId).llm : agent.getCurrentLLMConfig();
|
|
169
246
|
let displayName;
|
|
170
247
|
try {
|
|
171
|
-
const model =
|
|
248
|
+
const model = import_core2.LLM_REGISTRY[currentConfig.provider]?.models.find(
|
|
172
249
|
(m) => m.name.toLowerCase() === String(currentConfig.model).toLowerCase()
|
|
173
250
|
);
|
|
174
251
|
displayName = model?.displayName || void 0;
|
|
@@ -185,16 +262,15 @@ function createLlmRouter(getAgent) {
|
|
|
185
262
|
}).openapi(catalogRoute, (ctx) => {
|
|
186
263
|
const queryParams = ctx.req.valid("query");
|
|
187
264
|
const providers = {};
|
|
188
|
-
for (const provider of
|
|
189
|
-
const info =
|
|
265
|
+
for (const provider of import_core2.LLM_PROVIDERS) {
|
|
266
|
+
const info = import_core2.LLM_REGISTRY[provider];
|
|
190
267
|
const displayName = provider.charAt(0).toUpperCase() + provider.slice(1);
|
|
191
268
|
const keyStatus = (0, import_agent_management.getProviderKeyStatus)(provider);
|
|
192
269
|
providers[provider] = {
|
|
193
270
|
name: displayName,
|
|
194
271
|
hasApiKey: keyStatus.hasApiKey,
|
|
195
272
|
primaryEnvVar: keyStatus.envVar,
|
|
196
|
-
|
|
197
|
-
supportsBaseURL: (0, import_core.supportsBaseURL)(provider),
|
|
273
|
+
supportsBaseURL: (0, import_core2.supportsBaseURL)(provider),
|
|
198
274
|
models: info.models,
|
|
199
275
|
supportedFileTypes: info.supportedFileTypes
|
|
200
276
|
};
|
|
@@ -203,7 +279,7 @@ function createLlmRouter(getAgent) {
|
|
|
203
279
|
if (queryParams.provider && queryParams.provider.length > 0) {
|
|
204
280
|
const allowed = new Set(
|
|
205
281
|
queryParams.provider.filter(
|
|
206
|
-
(p) =>
|
|
282
|
+
(p) => import_core2.LLM_PROVIDERS.includes(p)
|
|
207
283
|
)
|
|
208
284
|
);
|
|
209
285
|
const filteredByProvider = {};
|
|
@@ -223,23 +299,6 @@ function createLlmRouter(getAgent) {
|
|
|
223
299
|
}
|
|
224
300
|
filtered = byKey;
|
|
225
301
|
}
|
|
226
|
-
if (queryParams.router) {
|
|
227
|
-
const byRouter = {};
|
|
228
|
-
for (const [id, catalog] of Object.entries(filtered)) {
|
|
229
|
-
if (!catalog.supportedRouters.includes(queryParams.router)) continue;
|
|
230
|
-
const models = catalog.models.filter(
|
|
231
|
-
(model) => (0, import_core.isRouterSupportedForModel)(
|
|
232
|
-
id,
|
|
233
|
-
model.name,
|
|
234
|
-
queryParams.router
|
|
235
|
-
)
|
|
236
|
-
);
|
|
237
|
-
if (models.length > 0) {
|
|
238
|
-
byRouter[id] = { ...catalog, models };
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
filtered = byRouter;
|
|
242
|
-
}
|
|
243
302
|
if (queryParams.fileType) {
|
|
244
303
|
const byFileType = {};
|
|
245
304
|
for (const [id, catalog] of Object.entries(filtered)) {
|
|
@@ -290,6 +349,26 @@ function createLlmRouter(getAgent) {
|
|
|
290
349
|
},
|
|
291
350
|
sessionId
|
|
292
351
|
});
|
|
352
|
+
}).openapi(listCustomModelsRoute, async (ctx) => {
|
|
353
|
+
const models = await (0, import_agent_management.loadCustomModels)();
|
|
354
|
+
return ctx.json({ models });
|
|
355
|
+
}).openapi(createCustomModelRoute, async (ctx) => {
|
|
356
|
+
const model = ctx.req.valid("json");
|
|
357
|
+
await (0, import_agent_management.saveCustomModel)(model);
|
|
358
|
+
return ctx.json({ ok: true, model });
|
|
359
|
+
}).openapi(deleteCustomModelRoute, async (ctx) => {
|
|
360
|
+
const { name } = ctx.req.valid("param");
|
|
361
|
+
const deleted = await (0, import_agent_management.deleteCustomModel)(name);
|
|
362
|
+
if (!deleted) {
|
|
363
|
+
throw new import_core.DextoRuntimeError(
|
|
364
|
+
"custom_model_not_found",
|
|
365
|
+
import_core.ErrorScope.LLM,
|
|
366
|
+
import_core.ErrorType.NOT_FOUND,
|
|
367
|
+
`Custom model '${name}' not found`,
|
|
368
|
+
{ modelName: name }
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
return ctx.json({ ok: true, deleted: name }, 200);
|
|
293
372
|
});
|
|
294
373
|
}
|
|
295
374
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -12,7 +12,6 @@ export declare function createLlmRouter(getAgent: () => DextoAgent): OpenAPIHono
|
|
|
12
12
|
config: {
|
|
13
13
|
model: string;
|
|
14
14
|
provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere";
|
|
15
|
-
router?: "vercel" | "in-built" | undefined;
|
|
16
15
|
maxIterations?: number | undefined;
|
|
17
16
|
baseURL?: string | undefined;
|
|
18
17
|
maxInputTokens?: number | undefined;
|
|
@@ -33,7 +32,6 @@ export declare function createLlmRouter(getAgent: () => DextoAgent): OpenAPIHono
|
|
|
33
32
|
input: {
|
|
34
33
|
query: {
|
|
35
34
|
provider?: string | string[] | undefined;
|
|
36
|
-
router?: "vercel" | "in-built" | undefined;
|
|
37
35
|
hasKey?: "0" | "1" | "true" | "false" | undefined;
|
|
38
36
|
fileType?: "image" | "audio" | "pdf" | undefined;
|
|
39
37
|
defaultOnly?: "0" | "1" | "true" | "false" | undefined;
|
|
@@ -46,7 +44,6 @@ export declare function createLlmRouter(getAgent: () => DextoAgent): OpenAPIHono
|
|
|
46
44
|
name: string;
|
|
47
45
|
hasApiKey: boolean;
|
|
48
46
|
supportedFileTypes: ("image" | "audio" | "pdf")[];
|
|
49
|
-
supportedRouters: ("vercel" | "in-built")[];
|
|
50
47
|
primaryEnvVar: string;
|
|
51
48
|
supportsBaseURL: boolean;
|
|
52
49
|
models: {
|
|
@@ -54,7 +51,6 @@ export declare function createLlmRouter(getAgent: () => DextoAgent): OpenAPIHono
|
|
|
54
51
|
maxInputTokens: number;
|
|
55
52
|
supportedFileTypes: ("image" | "audio" | "pdf")[];
|
|
56
53
|
default?: boolean | undefined;
|
|
57
|
-
supportedRouters?: ("vercel" | "in-built")[] | undefined;
|
|
58
54
|
displayName?: string | undefined;
|
|
59
55
|
pricing?: {
|
|
60
56
|
inputPerM: number;
|
|
@@ -70,7 +66,6 @@ export declare function createLlmRouter(getAgent: () => DextoAgent): OpenAPIHono
|
|
|
70
66
|
name: string;
|
|
71
67
|
hasApiKey: boolean;
|
|
72
68
|
supportedFileTypes: ("image" | "audio" | "pdf")[];
|
|
73
|
-
supportedRouters: ("vercel" | "in-built")[];
|
|
74
69
|
primaryEnvVar: string;
|
|
75
70
|
supportsBaseURL: boolean;
|
|
76
71
|
models: {
|
|
@@ -78,7 +73,6 @@ export declare function createLlmRouter(getAgent: () => DextoAgent): OpenAPIHono
|
|
|
78
73
|
maxInputTokens: number;
|
|
79
74
|
supportedFileTypes: ("image" | "audio" | "pdf")[];
|
|
80
75
|
default?: boolean | undefined;
|
|
81
|
-
supportedRouters?: ("vercel" | "in-built")[] | undefined;
|
|
82
76
|
displayName?: string | undefined;
|
|
83
77
|
pricing?: {
|
|
84
78
|
inputPerM: number;
|
|
@@ -94,7 +88,6 @@ export declare function createLlmRouter(getAgent: () => DextoAgent): OpenAPIHono
|
|
|
94
88
|
name: string;
|
|
95
89
|
hasApiKey: boolean;
|
|
96
90
|
supportedFileTypes: ("image" | "audio" | "pdf")[];
|
|
97
|
-
supportedRouters: ("vercel" | "in-built")[];
|
|
98
91
|
primaryEnvVar: string;
|
|
99
92
|
supportsBaseURL: boolean;
|
|
100
93
|
models: {
|
|
@@ -102,7 +95,6 @@ export declare function createLlmRouter(getAgent: () => DextoAgent): OpenAPIHono
|
|
|
102
95
|
maxInputTokens: number;
|
|
103
96
|
supportedFileTypes: ("image" | "audio" | "pdf")[];
|
|
104
97
|
default?: boolean | undefined;
|
|
105
|
-
supportedRouters?: ("vercel" | "in-built")[] | undefined;
|
|
106
98
|
displayName?: string | undefined;
|
|
107
99
|
pricing?: {
|
|
108
100
|
inputPerM: number;
|
|
@@ -118,7 +110,6 @@ export declare function createLlmRouter(getAgent: () => DextoAgent): OpenAPIHono
|
|
|
118
110
|
name: string;
|
|
119
111
|
hasApiKey: boolean;
|
|
120
112
|
supportedFileTypes: ("image" | "audio" | "pdf")[];
|
|
121
|
-
supportedRouters: ("vercel" | "in-built")[];
|
|
122
113
|
primaryEnvVar: string;
|
|
123
114
|
supportsBaseURL: boolean;
|
|
124
115
|
models: {
|
|
@@ -126,7 +117,6 @@ export declare function createLlmRouter(getAgent: () => DextoAgent): OpenAPIHono
|
|
|
126
117
|
maxInputTokens: number;
|
|
127
118
|
supportedFileTypes: ("image" | "audio" | "pdf")[];
|
|
128
119
|
default?: boolean | undefined;
|
|
129
|
-
supportedRouters?: ("vercel" | "in-built")[] | undefined;
|
|
130
120
|
displayName?: string | undefined;
|
|
131
121
|
pricing?: {
|
|
132
122
|
inputPerM: number;
|
|
@@ -142,7 +132,6 @@ export declare function createLlmRouter(getAgent: () => DextoAgent): OpenAPIHono
|
|
|
142
132
|
name: string;
|
|
143
133
|
hasApiKey: boolean;
|
|
144
134
|
supportedFileTypes: ("image" | "audio" | "pdf")[];
|
|
145
|
-
supportedRouters: ("vercel" | "in-built")[];
|
|
146
135
|
primaryEnvVar: string;
|
|
147
136
|
supportsBaseURL: boolean;
|
|
148
137
|
models: {
|
|
@@ -150,7 +139,6 @@ export declare function createLlmRouter(getAgent: () => DextoAgent): OpenAPIHono
|
|
|
150
139
|
maxInputTokens: number;
|
|
151
140
|
supportedFileTypes: ("image" | "audio" | "pdf")[];
|
|
152
141
|
default?: boolean | undefined;
|
|
153
|
-
supportedRouters?: ("vercel" | "in-built")[] | undefined;
|
|
154
142
|
displayName?: string | undefined;
|
|
155
143
|
pricing?: {
|
|
156
144
|
inputPerM: number;
|
|
@@ -166,7 +154,6 @@ export declare function createLlmRouter(getAgent: () => DextoAgent): OpenAPIHono
|
|
|
166
154
|
name: string;
|
|
167
155
|
hasApiKey: boolean;
|
|
168
156
|
supportedFileTypes: ("image" | "audio" | "pdf")[];
|
|
169
|
-
supportedRouters: ("vercel" | "in-built")[];
|
|
170
157
|
primaryEnvVar: string;
|
|
171
158
|
supportsBaseURL: boolean;
|
|
172
159
|
models: {
|
|
@@ -174,7 +161,6 @@ export declare function createLlmRouter(getAgent: () => DextoAgent): OpenAPIHono
|
|
|
174
161
|
maxInputTokens: number;
|
|
175
162
|
supportedFileTypes: ("image" | "audio" | "pdf")[];
|
|
176
163
|
default?: boolean | undefined;
|
|
177
|
-
supportedRouters?: ("vercel" | "in-built")[] | undefined;
|
|
178
164
|
displayName?: string | undefined;
|
|
179
165
|
pricing?: {
|
|
180
166
|
inputPerM: number;
|
|
@@ -190,7 +176,6 @@ export declare function createLlmRouter(getAgent: () => DextoAgent): OpenAPIHono
|
|
|
190
176
|
name: string;
|
|
191
177
|
hasApiKey: boolean;
|
|
192
178
|
supportedFileTypes: ("image" | "audio" | "pdf")[];
|
|
193
|
-
supportedRouters: ("vercel" | "in-built")[];
|
|
194
179
|
primaryEnvVar: string;
|
|
195
180
|
supportsBaseURL: boolean;
|
|
196
181
|
models: {
|
|
@@ -198,7 +183,6 @@ export declare function createLlmRouter(getAgent: () => DextoAgent): OpenAPIHono
|
|
|
198
183
|
maxInputTokens: number;
|
|
199
184
|
supportedFileTypes: ("image" | "audio" | "pdf")[];
|
|
200
185
|
default?: boolean | undefined;
|
|
201
|
-
supportedRouters?: ("vercel" | "in-built")[] | undefined;
|
|
202
186
|
displayName?: string | undefined;
|
|
203
187
|
pricing?: {
|
|
204
188
|
inputPerM: number;
|
|
@@ -218,7 +202,6 @@ export declare function createLlmRouter(getAgent: () => DextoAgent): OpenAPIHono
|
|
|
218
202
|
maxInputTokens: number;
|
|
219
203
|
supportedFileTypes: ("image" | "audio" | "pdf")[];
|
|
220
204
|
default?: boolean | undefined;
|
|
221
|
-
supportedRouters?: ("vercel" | "in-built")[] | undefined;
|
|
222
205
|
displayName?: string | undefined;
|
|
223
206
|
pricing?: {
|
|
224
207
|
inputPerM: number;
|
|
@@ -257,10 +240,9 @@ export declare function createLlmRouter(getAgent: () => DextoAgent): OpenAPIHono
|
|
|
257
240
|
$post: {
|
|
258
241
|
input: {
|
|
259
242
|
json: {
|
|
260
|
-
apiKey?: string | undefined;
|
|
261
243
|
model?: string | undefined;
|
|
262
244
|
provider?: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | undefined;
|
|
263
|
-
|
|
245
|
+
apiKey?: string | undefined;
|
|
264
246
|
maxIterations?: number | undefined;
|
|
265
247
|
baseURL?: string | undefined;
|
|
266
248
|
maxInputTokens?: number | undefined;
|
|
@@ -275,7 +257,6 @@ export declare function createLlmRouter(getAgent: () => DextoAgent): OpenAPIHono
|
|
|
275
257
|
config: {
|
|
276
258
|
model: string;
|
|
277
259
|
provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere";
|
|
278
|
-
router: "vercel" | "in-built";
|
|
279
260
|
maxIterations: number;
|
|
280
261
|
baseURL?: string | undefined;
|
|
281
262
|
maxInputTokens?: number | undefined;
|
|
@@ -290,5 +271,76 @@ export declare function createLlmRouter(getAgent: () => DextoAgent): OpenAPIHono
|
|
|
290
271
|
status: 200;
|
|
291
272
|
};
|
|
292
273
|
};
|
|
274
|
+
} & {
|
|
275
|
+
"/llm/custom-models": {
|
|
276
|
+
$get: {
|
|
277
|
+
input: {};
|
|
278
|
+
output: {
|
|
279
|
+
models: {
|
|
280
|
+
name: string;
|
|
281
|
+
baseURL: string;
|
|
282
|
+
displayName?: string | undefined | undefined;
|
|
283
|
+
maxInputTokens?: number | undefined | undefined;
|
|
284
|
+
maxOutputTokens?: number | undefined | undefined;
|
|
285
|
+
}[];
|
|
286
|
+
};
|
|
287
|
+
outputFormat: "json";
|
|
288
|
+
status: 200;
|
|
289
|
+
};
|
|
290
|
+
};
|
|
291
|
+
} & {
|
|
292
|
+
"/llm/custom-models": {
|
|
293
|
+
$post: {
|
|
294
|
+
input: {
|
|
295
|
+
json: {
|
|
296
|
+
name: string;
|
|
297
|
+
baseURL: string;
|
|
298
|
+
displayName?: string | undefined;
|
|
299
|
+
maxInputTokens?: number | undefined;
|
|
300
|
+
maxOutputTokens?: number | undefined;
|
|
301
|
+
};
|
|
302
|
+
};
|
|
303
|
+
output: {
|
|
304
|
+
model: {
|
|
305
|
+
name: string;
|
|
306
|
+
baseURL: string;
|
|
307
|
+
displayName?: string | undefined | undefined;
|
|
308
|
+
maxInputTokens?: number | undefined | undefined;
|
|
309
|
+
maxOutputTokens?: number | undefined | undefined;
|
|
310
|
+
};
|
|
311
|
+
ok: true;
|
|
312
|
+
};
|
|
313
|
+
outputFormat: "json";
|
|
314
|
+
status: 200;
|
|
315
|
+
};
|
|
316
|
+
};
|
|
317
|
+
} & {
|
|
318
|
+
"/llm/custom-models/:name": {
|
|
319
|
+
$delete: {
|
|
320
|
+
input: {
|
|
321
|
+
param: {
|
|
322
|
+
name: string;
|
|
323
|
+
};
|
|
324
|
+
};
|
|
325
|
+
output: {
|
|
326
|
+
ok: true;
|
|
327
|
+
deleted: string;
|
|
328
|
+
};
|
|
329
|
+
outputFormat: "json";
|
|
330
|
+
status: 200;
|
|
331
|
+
} | {
|
|
332
|
+
input: {
|
|
333
|
+
param: {
|
|
334
|
+
name: string;
|
|
335
|
+
};
|
|
336
|
+
};
|
|
337
|
+
output: {
|
|
338
|
+
ok: false;
|
|
339
|
+
error: string;
|
|
340
|
+
};
|
|
341
|
+
outputFormat: "json";
|
|
342
|
+
status: 404;
|
|
343
|
+
};
|
|
344
|
+
};
|
|
293
345
|
}, "/">;
|
|
294
346
|
//# sourceMappingURL=llm.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/llm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/llm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAoG9C,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA2YzD"}
|
package/dist/hono/routes/llm.js
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
|
|
2
|
+
import { DextoRuntimeError, ErrorScope, ErrorType } from "@dexto/core";
|
|
2
3
|
import {
|
|
3
4
|
LLM_REGISTRY,
|
|
4
5
|
LLM_PROVIDERS,
|
|
5
|
-
LLM_ROUTERS,
|
|
6
6
|
SUPPORTED_FILE_TYPES,
|
|
7
|
-
getSupportedRoutersForProvider,
|
|
8
7
|
supportsBaseURL,
|
|
9
|
-
isRouterSupportedForModel,
|
|
10
8
|
LLMUpdatesSchema
|
|
11
9
|
} from "@dexto/core";
|
|
12
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
getProviderKeyStatus,
|
|
12
|
+
saveProviderApiKey,
|
|
13
|
+
loadCustomModels,
|
|
14
|
+
saveCustomModel,
|
|
15
|
+
deleteCustomModel,
|
|
16
|
+
CustomModelSchema
|
|
17
|
+
} from "@dexto/agent-management";
|
|
13
18
|
import {
|
|
14
19
|
ProviderCatalogSchema,
|
|
15
20
|
ModelFlatSchema,
|
|
@@ -25,7 +30,6 @@ const CatalogQuerySchema = z.object({
|
|
|
25
30
|
hasKey: z.union([z.literal("true"), z.literal("false"), z.literal("1"), z.literal("0")]).optional().transform(
|
|
26
31
|
(raw) => raw === "true" || raw === "1" ? true : raw === "false" || raw === "0" ? false : void 0
|
|
27
32
|
).describe("Filter by API key presence (true or false)"),
|
|
28
|
-
router: z.enum(LLM_ROUTERS).optional().describe("Filter by router type (vercel or in-built)"),
|
|
29
33
|
fileType: z.enum(SUPPORTED_FILE_TYPES).optional().describe("Filter by supported file type (audio, pdf, or image)"),
|
|
30
34
|
defaultOnly: z.union([z.literal("true"), z.literal("false"), z.literal("1"), z.literal("0")]).optional().transform(
|
|
31
35
|
(raw) => raw === "true" || raw === "1" ? true : raw === "false" || raw === "0" ? false : void 0
|
|
@@ -57,8 +61,7 @@ function createLlmRouter(getAgent) {
|
|
|
57
61
|
"application/json": {
|
|
58
62
|
schema: z.object({
|
|
59
63
|
config: LLMConfigResponseSchema.partial({
|
|
60
|
-
maxIterations: true
|
|
61
|
-
router: true
|
|
64
|
+
maxIterations: true
|
|
62
65
|
}).extend({
|
|
63
66
|
displayName: z.string().optional().describe("Human-readable model display name")
|
|
64
67
|
})
|
|
@@ -152,6 +155,84 @@ function createLlmRouter(getAgent) {
|
|
|
152
155
|
}
|
|
153
156
|
}
|
|
154
157
|
});
|
|
158
|
+
const listCustomModelsRoute = createRoute({
|
|
159
|
+
method: "get",
|
|
160
|
+
path: "/llm/custom-models",
|
|
161
|
+
summary: "List Custom Models",
|
|
162
|
+
description: "Returns all saved custom openai-compatible model configurations",
|
|
163
|
+
tags: ["llm"],
|
|
164
|
+
responses: {
|
|
165
|
+
200: {
|
|
166
|
+
description: "List of custom models",
|
|
167
|
+
content: {
|
|
168
|
+
"application/json": {
|
|
169
|
+
schema: z.object({
|
|
170
|
+
models: z.array(CustomModelSchema).describe("List of custom models")
|
|
171
|
+
})
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
const createCustomModelRoute = createRoute({
|
|
178
|
+
method: "post",
|
|
179
|
+
path: "/llm/custom-models",
|
|
180
|
+
summary: "Create Custom Model",
|
|
181
|
+
description: "Saves a new custom openai-compatible model configuration",
|
|
182
|
+
tags: ["llm"],
|
|
183
|
+
request: {
|
|
184
|
+
body: { content: { "application/json": { schema: CustomModelSchema } } }
|
|
185
|
+
},
|
|
186
|
+
responses: {
|
|
187
|
+
200: {
|
|
188
|
+
description: "Custom model saved",
|
|
189
|
+
content: {
|
|
190
|
+
"application/json": {
|
|
191
|
+
schema: z.object({
|
|
192
|
+
ok: z.literal(true).describe("Success indicator"),
|
|
193
|
+
model: CustomModelSchema
|
|
194
|
+
})
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
const deleteCustomModelRoute = createRoute({
|
|
201
|
+
method: "delete",
|
|
202
|
+
path: "/llm/custom-models/{name}",
|
|
203
|
+
summary: "Delete Custom Model",
|
|
204
|
+
description: "Deletes a custom model by name",
|
|
205
|
+
tags: ["llm"],
|
|
206
|
+
request: {
|
|
207
|
+
params: z.object({
|
|
208
|
+
name: z.string().min(1).describe("Model name to delete")
|
|
209
|
+
})
|
|
210
|
+
},
|
|
211
|
+
responses: {
|
|
212
|
+
200: {
|
|
213
|
+
description: "Custom model deleted",
|
|
214
|
+
content: {
|
|
215
|
+
"application/json": {
|
|
216
|
+
schema: z.object({
|
|
217
|
+
ok: z.literal(true).describe("Success indicator"),
|
|
218
|
+
deleted: z.string().describe("Name of the deleted model")
|
|
219
|
+
})
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
404: {
|
|
224
|
+
description: "Custom model not found",
|
|
225
|
+
content: {
|
|
226
|
+
"application/json": {
|
|
227
|
+
schema: z.object({
|
|
228
|
+
ok: z.literal(false).describe("Failure indicator"),
|
|
229
|
+
error: z.string().describe("Error message")
|
|
230
|
+
})
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
});
|
|
155
236
|
return app.openapi(currentRoute, (ctx) => {
|
|
156
237
|
const agent = getAgent();
|
|
157
238
|
const { sessionId } = ctx.req.valid("query");
|
|
@@ -183,7 +264,6 @@ function createLlmRouter(getAgent) {
|
|
|
183
264
|
name: displayName,
|
|
184
265
|
hasApiKey: keyStatus.hasApiKey,
|
|
185
266
|
primaryEnvVar: keyStatus.envVar,
|
|
186
|
-
supportedRouters: getSupportedRoutersForProvider(provider),
|
|
187
267
|
supportsBaseURL: supportsBaseURL(provider),
|
|
188
268
|
models: info.models,
|
|
189
269
|
supportedFileTypes: info.supportedFileTypes
|
|
@@ -213,23 +293,6 @@ function createLlmRouter(getAgent) {
|
|
|
213
293
|
}
|
|
214
294
|
filtered = byKey;
|
|
215
295
|
}
|
|
216
|
-
if (queryParams.router) {
|
|
217
|
-
const byRouter = {};
|
|
218
|
-
for (const [id, catalog] of Object.entries(filtered)) {
|
|
219
|
-
if (!catalog.supportedRouters.includes(queryParams.router)) continue;
|
|
220
|
-
const models = catalog.models.filter(
|
|
221
|
-
(model) => isRouterSupportedForModel(
|
|
222
|
-
id,
|
|
223
|
-
model.name,
|
|
224
|
-
queryParams.router
|
|
225
|
-
)
|
|
226
|
-
);
|
|
227
|
-
if (models.length > 0) {
|
|
228
|
-
byRouter[id] = { ...catalog, models };
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
filtered = byRouter;
|
|
232
|
-
}
|
|
233
296
|
if (queryParams.fileType) {
|
|
234
297
|
const byFileType = {};
|
|
235
298
|
for (const [id, catalog] of Object.entries(filtered)) {
|
|
@@ -280,6 +343,26 @@ function createLlmRouter(getAgent) {
|
|
|
280
343
|
},
|
|
281
344
|
sessionId
|
|
282
345
|
});
|
|
346
|
+
}).openapi(listCustomModelsRoute, async (ctx) => {
|
|
347
|
+
const models = await loadCustomModels();
|
|
348
|
+
return ctx.json({ models });
|
|
349
|
+
}).openapi(createCustomModelRoute, async (ctx) => {
|
|
350
|
+
const model = ctx.req.valid("json");
|
|
351
|
+
await saveCustomModel(model);
|
|
352
|
+
return ctx.json({ ok: true, model });
|
|
353
|
+
}).openapi(deleteCustomModelRoute, async (ctx) => {
|
|
354
|
+
const { name } = ctx.req.valid("param");
|
|
355
|
+
const deleted = await deleteCustomModel(name);
|
|
356
|
+
if (!deleted) {
|
|
357
|
+
throw new DextoRuntimeError(
|
|
358
|
+
"custom_model_not_found",
|
|
359
|
+
ErrorScope.LLM,
|
|
360
|
+
ErrorType.NOT_FOUND,
|
|
361
|
+
`Custom model '${name}' not found`,
|
|
362
|
+
{ modelName: name }
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
return ctx.json({ ok: true, deleted: name }, 200);
|
|
283
366
|
});
|
|
284
367
|
}
|
|
285
368
|
export {
|
package/dist/hono/routes/mcp.cjs
CHANGED
|
@@ -40,7 +40,7 @@ const ServerStatusResponseSchema = import_zod_openapi.z.object({
|
|
|
40
40
|
const ServerInfoSchema = import_zod_openapi.z.object({
|
|
41
41
|
id: import_zod_openapi.z.string().describe("Server identifier"),
|
|
42
42
|
name: import_zod_openapi.z.string().describe("Server name"),
|
|
43
|
-
status: import_zod_openapi.z.enum(
|
|
43
|
+
status: import_zod_openapi.z.enum(import_core.MCP_CONNECTION_STATUSES).describe("Server status")
|
|
44
44
|
}).strict().describe("MCP server information");
|
|
45
45
|
const ServersListResponseSchema = import_zod_openapi.z.object({
|
|
46
46
|
servers: import_zod_openapi.z.array(ServerInfoSchema).describe("Array of server information")
|
|
@@ -230,8 +230,11 @@ function createMcpRouter(getAgent) {
|
|
|
230
230
|
return app.openapi(addServerRoute, async (ctx) => {
|
|
231
231
|
const agent = getAgent();
|
|
232
232
|
const { name, config, persistToAgent } = ctx.req.valid("json");
|
|
233
|
-
await agent.
|
|
234
|
-
|
|
233
|
+
await agent.addMcpServer(name, config);
|
|
234
|
+
const isConnected = config.enabled !== false;
|
|
235
|
+
import_core.logger.info(
|
|
236
|
+
isConnected ? `Successfully connected to new server '${name}' via API request.` : `Registered server '${name}' (disabled) via API request.`
|
|
237
|
+
);
|
|
235
238
|
if (persistToAgent === true) {
|
|
236
239
|
try {
|
|
237
240
|
const currentConfig = agent.getEffectiveConfig();
|
|
@@ -262,7 +265,8 @@ function createMcpRouter(getAgent) {
|
|
|
262
265
|
);
|
|
263
266
|
}
|
|
264
267
|
}
|
|
265
|
-
|
|
268
|
+
const status = isConnected ? "connected" : "registered";
|
|
269
|
+
return ctx.json({ status, name }, 200);
|
|
266
270
|
}).openapi(listServersRoute, async (ctx) => {
|
|
267
271
|
const agent = getAgent();
|
|
268
272
|
const clientsMap = agent.getMcpClients();
|