@dexto/server 1.5.6 → 1.5.8
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/hono/index.cjs +6 -1
- package/dist/hono/index.d.ts +127 -22
- package/dist/hono/index.d.ts.map +1 -1
- package/dist/hono/index.js +6 -1
- package/dist/hono/middleware/error.cjs +6 -2
- package/dist/hono/middleware/error.d.ts.map +1 -1
- package/dist/hono/middleware/error.js +6 -2
- package/dist/hono/routes/a2a-tasks.d.ts +5 -5
- package/dist/hono/routes/dexto-auth.cjs +72 -0
- package/dist/hono/routes/dexto-auth.d.ts +21 -0
- package/dist/hono/routes/dexto-auth.d.ts.map +1 -0
- package/dist/hono/routes/dexto-auth.js +52 -0
- package/dist/hono/routes/key.d.ts +4 -4
- package/dist/hono/routes/llm.cjs +75 -5
- package/dist/hono/routes/llm.d.ts +97 -8
- package/dist/hono/routes/llm.d.ts.map +1 -1
- package/dist/hono/routes/llm.js +80 -6
- package/dist/hono/routes/mcp.d.ts +1 -1
- package/dist/hono/routes/messages.d.ts +1 -1
- package/dist/hono/routes/queue.cjs +9 -3
- package/dist/hono/routes/queue.d.ts +3 -0
- package/dist/hono/routes/queue.d.ts.map +1 -1
- package/dist/hono/routes/queue.js +9 -3
- package/dist/hono/routes/search.d.ts +2 -2
- package/dist/hono/routes/sessions.d.ts +1 -1
- package/dist/hono/schemas/responses.d.ts +41 -41
- package/dist/hono/start-server.cjs +1 -0
- package/dist/hono/start-server.d.ts.map +1 -1
- package/dist/hono/start-server.js +2 -1
- package/dist/mcp/mcp-handler.cjs +0 -1
- package/dist/mcp/mcp-handler.d.ts.map +1 -1
- package/dist/mcp/mcp-handler.js +0 -1
- package/package.json +4 -4
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
|
|
2
|
+
import {
|
|
3
|
+
isDextoAuthEnabled,
|
|
4
|
+
isDextoAuthenticated,
|
|
5
|
+
canUseDextoProvider
|
|
6
|
+
} from "@dexto/agent-management";
|
|
7
|
+
function createDextoAuthRouter(_getAgent) {
|
|
8
|
+
const app = new OpenAPIHono();
|
|
9
|
+
const statusRoute = createRoute({
|
|
10
|
+
method: "get",
|
|
11
|
+
path: "/dexto-auth/status",
|
|
12
|
+
summary: "Dexto Auth Status",
|
|
13
|
+
description: "Returns dexto authentication status. Used by Web UI to check if user can use dexto features.",
|
|
14
|
+
tags: ["auth"],
|
|
15
|
+
responses: {
|
|
16
|
+
200: {
|
|
17
|
+
description: "Dexto auth status",
|
|
18
|
+
content: {
|
|
19
|
+
"application/json": {
|
|
20
|
+
schema: z.object({
|
|
21
|
+
enabled: z.boolean().describe("Whether dexto auth feature is enabled"),
|
|
22
|
+
authenticated: z.boolean().describe("Whether user is authenticated with dexto"),
|
|
23
|
+
canUse: z.boolean().describe(
|
|
24
|
+
"Whether user can use dexto (authenticated AND has API key)"
|
|
25
|
+
)
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
return app.openapi(statusRoute, async (c) => {
|
|
33
|
+
const enabled = isDextoAuthEnabled();
|
|
34
|
+
if (!enabled) {
|
|
35
|
+
return c.json({
|
|
36
|
+
enabled: false,
|
|
37
|
+
authenticated: false,
|
|
38
|
+
canUse: false
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
const authenticated = await isDextoAuthenticated();
|
|
42
|
+
const canUse = await canUseDextoProvider();
|
|
43
|
+
return c.json({
|
|
44
|
+
enabled,
|
|
45
|
+
authenticated,
|
|
46
|
+
canUse
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
export {
|
|
51
|
+
createDextoAuthRouter
|
|
52
|
+
};
|
|
@@ -13,11 +13,11 @@ export declare function createKeyRouter(): OpenAPIHono<import("hono").Env, {
|
|
|
13
13
|
$get: {
|
|
14
14
|
input: {
|
|
15
15
|
param: {
|
|
16
|
-
provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama";
|
|
16
|
+
provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "minimax" | "glm" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama" | "dexto-nova";
|
|
17
17
|
};
|
|
18
18
|
};
|
|
19
19
|
output: {
|
|
20
|
-
provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama";
|
|
20
|
+
provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "minimax" | "glm" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama" | "dexto-nova";
|
|
21
21
|
hasKey: boolean;
|
|
22
22
|
envVar: string;
|
|
23
23
|
keyValue?: string | undefined;
|
|
@@ -31,12 +31,12 @@ export declare function createKeyRouter(): OpenAPIHono<import("hono").Env, {
|
|
|
31
31
|
$post: {
|
|
32
32
|
input: {
|
|
33
33
|
json: {
|
|
34
|
-
provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama";
|
|
34
|
+
provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "minimax" | "glm" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama" | "dexto-nova";
|
|
35
35
|
apiKey: string;
|
|
36
36
|
};
|
|
37
37
|
};
|
|
38
38
|
output: {
|
|
39
|
-
provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama";
|
|
39
|
+
provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "minimax" | "glm" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama" | "dexto-nova";
|
|
40
40
|
ok: true;
|
|
41
41
|
envVar: string;
|
|
42
42
|
};
|
package/dist/hono/routes/llm.cjs
CHANGED
|
@@ -28,11 +28,17 @@ var import_agent_management = require("@dexto/agent-management");
|
|
|
28
28
|
var import_responses = require("../schemas/responses.js");
|
|
29
29
|
const CurrentQuerySchema = import_zod_openapi.z.object({
|
|
30
30
|
sessionId: import_zod_openapi.z.string().optional().describe("Session identifier to retrieve session-specific LLM configuration")
|
|
31
|
-
}).describe("Query parameters for getting current LLM configuration");
|
|
31
|
+
}).strict().describe("Query parameters for getting current LLM configuration");
|
|
32
32
|
const CatalogQuerySchema = import_zod_openapi.z.object({
|
|
33
|
+
scope: import_zod_openapi.z.enum(["curated", "all"]).default("all").describe(
|
|
34
|
+
"Catalog scope: 'curated' returns a small, UI-friendly set of models; 'all' returns the full registry (can be large)"
|
|
35
|
+
),
|
|
33
36
|
provider: import_zod_openapi.z.union([import_zod_openapi.z.string(), import_zod_openapi.z.array(import_zod_openapi.z.string())]).optional().transform(
|
|
34
37
|
(value) => Array.isArray(value) ? value : value ? value.split(",") : void 0
|
|
35
38
|
).describe("Comma-separated list of LLM providers to filter by"),
|
|
39
|
+
includeModels: 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(
|
|
40
|
+
(raw) => raw === "true" || raw === "1" ? true : raw === "false" || raw === "0" ? false : void 0
|
|
41
|
+
).describe("Include models list in the response (true or false)"),
|
|
36
42
|
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(
|
|
37
43
|
(raw) => raw === "true" || raw === "1" ? true : raw === "false" || raw === "0" ? false : void 0
|
|
38
44
|
).describe("Filter by API key presence (true or false)"),
|
|
@@ -41,7 +47,7 @@ const CatalogQuerySchema = import_zod_openapi.z.object({
|
|
|
41
47
|
(raw) => raw === "true" || raw === "1" ? true : raw === "false" || raw === "0" ? false : void 0
|
|
42
48
|
).describe("Include only default models (true or false)"),
|
|
43
49
|
mode: import_zod_openapi.z.enum(["grouped", "flat"]).default("grouped").describe("Response format mode (grouped by provider or flat list)")
|
|
44
|
-
}).describe("Query parameters for filtering and formatting the LLM catalog");
|
|
50
|
+
}).strict().describe("Query parameters for filtering and formatting the LLM catalog");
|
|
45
51
|
const SwitchLLMBodySchema = import_core2.LLMUpdatesSchema.and(
|
|
46
52
|
import_zod_openapi.z.object({
|
|
47
53
|
sessionId: import_zod_openapi.z.string().optional().describe("Session identifier for session-specific LLM configuration")
|
|
@@ -66,7 +72,14 @@ function createLlmRouter(getAgent) {
|
|
|
66
72
|
maxIterations: true
|
|
67
73
|
}).extend({
|
|
68
74
|
displayName: import_zod_openapi.z.string().optional().describe("Human-readable model display name")
|
|
69
|
-
})
|
|
75
|
+
}),
|
|
76
|
+
routing: import_zod_openapi.z.object({
|
|
77
|
+
viaDexto: import_zod_openapi.z.boolean().describe(
|
|
78
|
+
"Whether requests route through Dexto gateway"
|
|
79
|
+
)
|
|
80
|
+
}).describe(
|
|
81
|
+
"Routing information for the current LLM configuration"
|
|
82
|
+
)
|
|
70
83
|
}).describe("Response containing current LLM configuration")
|
|
71
84
|
}
|
|
72
85
|
}
|
|
@@ -213,6 +226,33 @@ function createLlmRouter(getAgent) {
|
|
|
213
226
|
}
|
|
214
227
|
}
|
|
215
228
|
});
|
|
229
|
+
const capabilitiesRoute = (0, import_zod_openapi.createRoute)({
|
|
230
|
+
method: "get",
|
|
231
|
+
path: "/llm/capabilities",
|
|
232
|
+
summary: "Get Model Capabilities",
|
|
233
|
+
description: "Returns the capabilities (supported file types) for a specific provider/model combination. Handles gateway providers (dexto-nova, openrouter) by resolving to the underlying model capabilities.",
|
|
234
|
+
tags: ["llm"],
|
|
235
|
+
request: {
|
|
236
|
+
query: import_zod_openapi.z.object({
|
|
237
|
+
provider: import_zod_openapi.z.enum(import_core2.LLM_PROVIDERS).describe("LLM provider name"),
|
|
238
|
+
model: import_zod_openapi.z.string().min(1).describe("Model name (supports both native and OpenRouter format)")
|
|
239
|
+
})
|
|
240
|
+
},
|
|
241
|
+
responses: {
|
|
242
|
+
200: {
|
|
243
|
+
description: "Model capabilities",
|
|
244
|
+
content: {
|
|
245
|
+
"application/json": {
|
|
246
|
+
schema: import_zod_openapi.z.object({
|
|
247
|
+
provider: import_zod_openapi.z.enum(import_core2.LLM_PROVIDERS).describe("Provider name"),
|
|
248
|
+
model: import_zod_openapi.z.string().describe("Model name as provided"),
|
|
249
|
+
supportedFileTypes: import_zod_openapi.z.array(import_zod_openapi.z.enum(import_core2.SUPPORTED_FILE_TYPES)).describe("File types supported by this model")
|
|
250
|
+
})
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
});
|
|
216
256
|
return app.openapi(currentRoute, async (ctx) => {
|
|
217
257
|
const agent = await getAgent(ctx);
|
|
218
258
|
const { sessionId } = ctx.req.valid("query");
|
|
@@ -233,26 +273,42 @@ function createLlmRouter(getAgent) {
|
|
|
233
273
|
} catch {
|
|
234
274
|
}
|
|
235
275
|
const { apiKey, ...configWithoutKey } = currentConfig;
|
|
276
|
+
const viaDexto = (0, import_agent_management.isDextoAuthEnabled)() && currentConfig.provider === "dexto-nova";
|
|
236
277
|
return ctx.json({
|
|
237
278
|
config: {
|
|
238
279
|
...configWithoutKey,
|
|
239
280
|
hasApiKey: !!apiKey,
|
|
240
281
|
...displayName && { displayName }
|
|
282
|
+
},
|
|
283
|
+
routing: {
|
|
284
|
+
viaDexto
|
|
241
285
|
}
|
|
242
286
|
});
|
|
243
287
|
}).openapi(catalogRoute, (ctx) => {
|
|
244
288
|
const queryParams = ctx.req.valid("query");
|
|
289
|
+
const includeModels = queryParams.includeModels ?? true;
|
|
290
|
+
const scope = queryParams.scope ?? "all";
|
|
245
291
|
const providers = {};
|
|
246
292
|
for (const provider of import_core2.LLM_PROVIDERS) {
|
|
293
|
+
if (provider === "dexto-nova" && !(0, import_agent_management.isDextoAuthEnabled)()) {
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
247
296
|
const info = import_core2.LLM_REGISTRY[provider];
|
|
248
|
-
const displayName = provider.charAt(0).toUpperCase() + provider.slice(1);
|
|
297
|
+
const displayName = provider === "dexto-nova" ? "Dexto Nova" : provider.charAt(0).toUpperCase() + provider.slice(1);
|
|
249
298
|
const keyStatus = (0, import_agent_management.getProviderKeyStatus)(provider);
|
|
299
|
+
const models = (() => {
|
|
300
|
+
if (!includeModels) return [];
|
|
301
|
+
if (scope === "all") {
|
|
302
|
+
return (0, import_core2.getAllModelsForProvider)(provider);
|
|
303
|
+
}
|
|
304
|
+
return (0, import_core2.getCuratedModelsForProvider)(provider);
|
|
305
|
+
})();
|
|
250
306
|
providers[provider] = {
|
|
251
307
|
name: displayName,
|
|
252
308
|
hasApiKey: keyStatus.hasApiKey,
|
|
253
309
|
primaryEnvVar: keyStatus.envVar,
|
|
254
310
|
supportsBaseURL: (0, import_core2.supportsBaseURL)(provider),
|
|
255
|
-
models
|
|
311
|
+
models,
|
|
256
312
|
supportedFileTypes: info.supportedFileTypes
|
|
257
313
|
};
|
|
258
314
|
}
|
|
@@ -347,6 +403,20 @@ function createLlmRouter(getAgent) {
|
|
|
347
403
|
);
|
|
348
404
|
}
|
|
349
405
|
return ctx.json({ ok: true, deleted: name }, 200);
|
|
406
|
+
}).openapi(capabilitiesRoute, (ctx) => {
|
|
407
|
+
const { provider, model } = ctx.req.valid("query");
|
|
408
|
+
let supportedFileTypes;
|
|
409
|
+
try {
|
|
410
|
+
supportedFileTypes = (0, import_core2.getSupportedFileTypesForModel)(provider, model);
|
|
411
|
+
} catch {
|
|
412
|
+
const providerInfo = import_core2.LLM_REGISTRY[provider];
|
|
413
|
+
supportedFileTypes = providerInfo?.supportedFileTypes ?? [];
|
|
414
|
+
}
|
|
415
|
+
return ctx.json({
|
|
416
|
+
provider,
|
|
417
|
+
model,
|
|
418
|
+
supportedFileTypes
|
|
419
|
+
});
|
|
350
420
|
});
|
|
351
421
|
}
|
|
352
422
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -13,7 +13,7 @@ export declare function createLlmRouter(getAgent: GetAgentFn): OpenAPIHono<impor
|
|
|
13
13
|
output: {
|
|
14
14
|
config: {
|
|
15
15
|
model: string;
|
|
16
|
-
provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama";
|
|
16
|
+
provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "minimax" | "glm" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama" | "dexto-nova";
|
|
17
17
|
maxIterations?: number | undefined;
|
|
18
18
|
baseURL?: string | undefined;
|
|
19
19
|
maxInputTokens?: number | undefined;
|
|
@@ -24,6 +24,9 @@ export declare function createLlmRouter(getAgent: GetAgentFn): OpenAPIHono<impor
|
|
|
24
24
|
hasApiKey?: boolean | undefined;
|
|
25
25
|
displayName?: string | undefined;
|
|
26
26
|
};
|
|
27
|
+
routing: {
|
|
28
|
+
viaDexto: boolean;
|
|
29
|
+
};
|
|
27
30
|
};
|
|
28
31
|
outputFormat: "json";
|
|
29
32
|
status: 200;
|
|
@@ -35,6 +38,8 @@ export declare function createLlmRouter(getAgent: GetAgentFn): OpenAPIHono<impor
|
|
|
35
38
|
input: {
|
|
36
39
|
query: {
|
|
37
40
|
provider?: string | string[] | undefined;
|
|
41
|
+
scope?: "curated" | "all" | undefined;
|
|
42
|
+
includeModels?: "0" | "1" | "true" | "false" | undefined;
|
|
38
43
|
hasKey?: "0" | "1" | "true" | "false" | undefined;
|
|
39
44
|
fileType?: "image" | "audio" | "pdf" | undefined;
|
|
40
45
|
defaultOnly?: "0" | "1" | "true" | "false" | undefined;
|
|
@@ -197,6 +202,50 @@ export declare function createLlmRouter(getAgent: GetAgentFn): OpenAPIHono<impor
|
|
|
197
202
|
} | undefined;
|
|
198
203
|
}[];
|
|
199
204
|
} | undefined;
|
|
205
|
+
minimax?: {
|
|
206
|
+
name: string;
|
|
207
|
+
hasApiKey: boolean;
|
|
208
|
+
supportedFileTypes: ("image" | "audio" | "pdf")[];
|
|
209
|
+
primaryEnvVar: string;
|
|
210
|
+
supportsBaseURL: boolean;
|
|
211
|
+
models: {
|
|
212
|
+
name: string;
|
|
213
|
+
maxInputTokens: number;
|
|
214
|
+
supportedFileTypes: ("image" | "audio" | "pdf")[];
|
|
215
|
+
default?: boolean | undefined;
|
|
216
|
+
displayName?: string | undefined;
|
|
217
|
+
pricing?: {
|
|
218
|
+
inputPerM: number;
|
|
219
|
+
outputPerM: number;
|
|
220
|
+
cacheReadPerM?: number | undefined;
|
|
221
|
+
cacheWritePerM?: number | undefined;
|
|
222
|
+
currency?: "USD" | undefined;
|
|
223
|
+
unit?: "per_million_tokens" | undefined;
|
|
224
|
+
} | undefined;
|
|
225
|
+
}[];
|
|
226
|
+
} | undefined;
|
|
227
|
+
glm?: {
|
|
228
|
+
name: string;
|
|
229
|
+
hasApiKey: boolean;
|
|
230
|
+
supportedFileTypes: ("image" | "audio" | "pdf")[];
|
|
231
|
+
primaryEnvVar: string;
|
|
232
|
+
supportsBaseURL: boolean;
|
|
233
|
+
models: {
|
|
234
|
+
name: string;
|
|
235
|
+
maxInputTokens: number;
|
|
236
|
+
supportedFileTypes: ("image" | "audio" | "pdf")[];
|
|
237
|
+
default?: boolean | undefined;
|
|
238
|
+
displayName?: string | undefined;
|
|
239
|
+
pricing?: {
|
|
240
|
+
inputPerM: number;
|
|
241
|
+
outputPerM: number;
|
|
242
|
+
cacheReadPerM?: number | undefined;
|
|
243
|
+
cacheWritePerM?: number | undefined;
|
|
244
|
+
currency?: "USD" | undefined;
|
|
245
|
+
unit?: "per_million_tokens" | undefined;
|
|
246
|
+
} | undefined;
|
|
247
|
+
}[];
|
|
248
|
+
} | undefined;
|
|
200
249
|
openrouter?: {
|
|
201
250
|
name: string;
|
|
202
251
|
hasApiKey: boolean;
|
|
@@ -351,6 +400,28 @@ export declare function createLlmRouter(getAgent: GetAgentFn): OpenAPIHono<impor
|
|
|
351
400
|
} | undefined;
|
|
352
401
|
}[];
|
|
353
402
|
} | undefined;
|
|
403
|
+
"dexto-nova"?: {
|
|
404
|
+
name: string;
|
|
405
|
+
hasApiKey: boolean;
|
|
406
|
+
supportedFileTypes: ("image" | "audio" | "pdf")[];
|
|
407
|
+
primaryEnvVar: string;
|
|
408
|
+
supportsBaseURL: boolean;
|
|
409
|
+
models: {
|
|
410
|
+
name: string;
|
|
411
|
+
maxInputTokens: number;
|
|
412
|
+
supportedFileTypes: ("image" | "audio" | "pdf")[];
|
|
413
|
+
default?: boolean | undefined;
|
|
414
|
+
displayName?: string | undefined;
|
|
415
|
+
pricing?: {
|
|
416
|
+
inputPerM: number;
|
|
417
|
+
outputPerM: number;
|
|
418
|
+
cacheReadPerM?: number | undefined;
|
|
419
|
+
cacheWritePerM?: number | undefined;
|
|
420
|
+
currency?: "USD" | undefined;
|
|
421
|
+
unit?: "per_million_tokens" | undefined;
|
|
422
|
+
} | undefined;
|
|
423
|
+
}[];
|
|
424
|
+
} | undefined;
|
|
354
425
|
};
|
|
355
426
|
} | {
|
|
356
427
|
models: {
|
|
@@ -380,15 +451,15 @@ export declare function createLlmRouter(getAgent: GetAgentFn): OpenAPIHono<impor
|
|
|
380
451
|
input: {
|
|
381
452
|
json: {
|
|
382
453
|
model?: string | undefined;
|
|
383
|
-
provider?: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama" | undefined;
|
|
454
|
+
provider?: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "minimax" | "glm" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama" | "dexto-nova" | undefined;
|
|
384
455
|
apiKey?: string | undefined;
|
|
456
|
+
maxInputTokens?: number | undefined;
|
|
385
457
|
maxIterations?: number | undefined;
|
|
386
458
|
baseURL?: string | undefined;
|
|
387
|
-
maxInputTokens?: number | undefined;
|
|
388
459
|
maxOutputTokens?: number | undefined;
|
|
389
460
|
temperature?: number | undefined;
|
|
390
461
|
allowedMediaTypes?: string[] | undefined;
|
|
391
|
-
reasoningEffort?: "
|
|
462
|
+
reasoningEffort?: "low" | "none" | "minimal" | "medium" | "high" | "xhigh" | undefined;
|
|
392
463
|
} & {
|
|
393
464
|
sessionId?: string | undefined;
|
|
394
465
|
};
|
|
@@ -396,7 +467,7 @@ export declare function createLlmRouter(getAgent: GetAgentFn): OpenAPIHono<impor
|
|
|
396
467
|
output: {
|
|
397
468
|
config: {
|
|
398
469
|
model: string;
|
|
399
|
-
provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama";
|
|
470
|
+
provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "minimax" | "glm" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama" | "dexto-nova";
|
|
400
471
|
maxIterations?: number | undefined;
|
|
401
472
|
baseURL?: string | undefined;
|
|
402
473
|
maxInputTokens?: number | undefined;
|
|
@@ -419,7 +490,7 @@ export declare function createLlmRouter(getAgent: GetAgentFn): OpenAPIHono<impor
|
|
|
419
490
|
output: {
|
|
420
491
|
models: {
|
|
421
492
|
name: string;
|
|
422
|
-
provider: "openai-compatible" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama";
|
|
493
|
+
provider: "openai-compatible" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama" | "dexto-nova";
|
|
423
494
|
apiKey?: string | undefined | undefined;
|
|
424
495
|
baseURL?: string | undefined | undefined;
|
|
425
496
|
reasoningEffort?: "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | undefined | undefined;
|
|
@@ -439,7 +510,7 @@ export declare function createLlmRouter(getAgent: GetAgentFn): OpenAPIHono<impor
|
|
|
439
510
|
input: {
|
|
440
511
|
json: {
|
|
441
512
|
name: string;
|
|
442
|
-
provider?: "openai-compatible" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama" | undefined;
|
|
513
|
+
provider?: "openai-compatible" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama" | "dexto-nova" | undefined;
|
|
443
514
|
apiKey?: string | undefined;
|
|
444
515
|
baseURL?: string | undefined;
|
|
445
516
|
reasoningEffort?: "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | undefined;
|
|
@@ -452,7 +523,7 @@ export declare function createLlmRouter(getAgent: GetAgentFn): OpenAPIHono<impor
|
|
|
452
523
|
output: {
|
|
453
524
|
model: {
|
|
454
525
|
name: string;
|
|
455
|
-
provider: "openai-compatible" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama";
|
|
526
|
+
provider: "openai-compatible" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama" | "dexto-nova";
|
|
456
527
|
apiKey?: string | undefined | undefined;
|
|
457
528
|
baseURL?: string | undefined | undefined;
|
|
458
529
|
reasoningEffort?: "none" | "minimal" | "low" | "medium" | "high" | "xhigh" | undefined | undefined;
|
|
@@ -495,6 +566,24 @@ export declare function createLlmRouter(getAgent: GetAgentFn): OpenAPIHono<impor
|
|
|
495
566
|
status: 404;
|
|
496
567
|
};
|
|
497
568
|
};
|
|
569
|
+
} & {
|
|
570
|
+
"/llm/capabilities": {
|
|
571
|
+
$get: {
|
|
572
|
+
input: {
|
|
573
|
+
query: {
|
|
574
|
+
model: string;
|
|
575
|
+
provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "minimax" | "glm" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama" | "dexto-nova";
|
|
576
|
+
};
|
|
577
|
+
};
|
|
578
|
+
output: {
|
|
579
|
+
model: string;
|
|
580
|
+
provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "minimax" | "glm" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama" | "dexto-nova";
|
|
581
|
+
supportedFileTypes: ("image" | "audio" | "pdf")[];
|
|
582
|
+
};
|
|
583
|
+
outputFormat: "json";
|
|
584
|
+
status: 200;
|
|
585
|
+
};
|
|
586
|
+
};
|
|
498
587
|
}, "/">;
|
|
499
588
|
export {};
|
|
500
589
|
//# 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;AAuB9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAOpC,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAmFrE,wBAAgB,eAAe,CAAC,QAAQ,EAAE,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAwdnD"}
|
package/dist/hono/routes/llm.js
CHANGED
|
@@ -5,6 +5,9 @@ import {
|
|
|
5
5
|
LLM_PROVIDERS,
|
|
6
6
|
SUPPORTED_FILE_TYPES,
|
|
7
7
|
supportsBaseURL,
|
|
8
|
+
getAllModelsForProvider,
|
|
9
|
+
getCuratedModelsForProvider,
|
|
10
|
+
getSupportedFileTypesForModel,
|
|
8
11
|
LLMUpdatesSchema
|
|
9
12
|
} from "@dexto/core";
|
|
10
13
|
import {
|
|
@@ -12,7 +15,8 @@ import {
|
|
|
12
15
|
loadCustomModels,
|
|
13
16
|
saveCustomModel,
|
|
14
17
|
deleteCustomModel,
|
|
15
|
-
CustomModelSchema
|
|
18
|
+
CustomModelSchema,
|
|
19
|
+
isDextoAuthEnabled
|
|
16
20
|
} from "@dexto/agent-management";
|
|
17
21
|
import {
|
|
18
22
|
ProviderCatalogSchema,
|
|
@@ -21,11 +25,17 @@ import {
|
|
|
21
25
|
} from "../schemas/responses.js";
|
|
22
26
|
const CurrentQuerySchema = z.object({
|
|
23
27
|
sessionId: z.string().optional().describe("Session identifier to retrieve session-specific LLM configuration")
|
|
24
|
-
}).describe("Query parameters for getting current LLM configuration");
|
|
28
|
+
}).strict().describe("Query parameters for getting current LLM configuration");
|
|
25
29
|
const CatalogQuerySchema = z.object({
|
|
30
|
+
scope: z.enum(["curated", "all"]).default("all").describe(
|
|
31
|
+
"Catalog scope: 'curated' returns a small, UI-friendly set of models; 'all' returns the full registry (can be large)"
|
|
32
|
+
),
|
|
26
33
|
provider: z.union([z.string(), z.array(z.string())]).optional().transform(
|
|
27
34
|
(value) => Array.isArray(value) ? value : value ? value.split(",") : void 0
|
|
28
35
|
).describe("Comma-separated list of LLM providers to filter by"),
|
|
36
|
+
includeModels: z.union([z.literal("true"), z.literal("false"), z.literal("1"), z.literal("0")]).optional().transform(
|
|
37
|
+
(raw) => raw === "true" || raw === "1" ? true : raw === "false" || raw === "0" ? false : void 0
|
|
38
|
+
).describe("Include models list in the response (true or false)"),
|
|
29
39
|
hasKey: z.union([z.literal("true"), z.literal("false"), z.literal("1"), z.literal("0")]).optional().transform(
|
|
30
40
|
(raw) => raw === "true" || raw === "1" ? true : raw === "false" || raw === "0" ? false : void 0
|
|
31
41
|
).describe("Filter by API key presence (true or false)"),
|
|
@@ -34,7 +44,7 @@ const CatalogQuerySchema = z.object({
|
|
|
34
44
|
(raw) => raw === "true" || raw === "1" ? true : raw === "false" || raw === "0" ? false : void 0
|
|
35
45
|
).describe("Include only default models (true or false)"),
|
|
36
46
|
mode: z.enum(["grouped", "flat"]).default("grouped").describe("Response format mode (grouped by provider or flat list)")
|
|
37
|
-
}).describe("Query parameters for filtering and formatting the LLM catalog");
|
|
47
|
+
}).strict().describe("Query parameters for filtering and formatting the LLM catalog");
|
|
38
48
|
const SwitchLLMBodySchema = LLMUpdatesSchema.and(
|
|
39
49
|
z.object({
|
|
40
50
|
sessionId: z.string().optional().describe("Session identifier for session-specific LLM configuration")
|
|
@@ -59,7 +69,14 @@ function createLlmRouter(getAgent) {
|
|
|
59
69
|
maxIterations: true
|
|
60
70
|
}).extend({
|
|
61
71
|
displayName: z.string().optional().describe("Human-readable model display name")
|
|
62
|
-
})
|
|
72
|
+
}),
|
|
73
|
+
routing: z.object({
|
|
74
|
+
viaDexto: z.boolean().describe(
|
|
75
|
+
"Whether requests route through Dexto gateway"
|
|
76
|
+
)
|
|
77
|
+
}).describe(
|
|
78
|
+
"Routing information for the current LLM configuration"
|
|
79
|
+
)
|
|
63
80
|
}).describe("Response containing current LLM configuration")
|
|
64
81
|
}
|
|
65
82
|
}
|
|
@@ -206,6 +223,33 @@ function createLlmRouter(getAgent) {
|
|
|
206
223
|
}
|
|
207
224
|
}
|
|
208
225
|
});
|
|
226
|
+
const capabilitiesRoute = createRoute({
|
|
227
|
+
method: "get",
|
|
228
|
+
path: "/llm/capabilities",
|
|
229
|
+
summary: "Get Model Capabilities",
|
|
230
|
+
description: "Returns the capabilities (supported file types) for a specific provider/model combination. Handles gateway providers (dexto-nova, openrouter) by resolving to the underlying model capabilities.",
|
|
231
|
+
tags: ["llm"],
|
|
232
|
+
request: {
|
|
233
|
+
query: z.object({
|
|
234
|
+
provider: z.enum(LLM_PROVIDERS).describe("LLM provider name"),
|
|
235
|
+
model: z.string().min(1).describe("Model name (supports both native and OpenRouter format)")
|
|
236
|
+
})
|
|
237
|
+
},
|
|
238
|
+
responses: {
|
|
239
|
+
200: {
|
|
240
|
+
description: "Model capabilities",
|
|
241
|
+
content: {
|
|
242
|
+
"application/json": {
|
|
243
|
+
schema: z.object({
|
|
244
|
+
provider: z.enum(LLM_PROVIDERS).describe("Provider name"),
|
|
245
|
+
model: z.string().describe("Model name as provided"),
|
|
246
|
+
supportedFileTypes: z.array(z.enum(SUPPORTED_FILE_TYPES)).describe("File types supported by this model")
|
|
247
|
+
})
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
});
|
|
209
253
|
return app.openapi(currentRoute, async (ctx) => {
|
|
210
254
|
const agent = await getAgent(ctx);
|
|
211
255
|
const { sessionId } = ctx.req.valid("query");
|
|
@@ -226,26 +270,42 @@ function createLlmRouter(getAgent) {
|
|
|
226
270
|
} catch {
|
|
227
271
|
}
|
|
228
272
|
const { apiKey, ...configWithoutKey } = currentConfig;
|
|
273
|
+
const viaDexto = isDextoAuthEnabled() && currentConfig.provider === "dexto-nova";
|
|
229
274
|
return ctx.json({
|
|
230
275
|
config: {
|
|
231
276
|
...configWithoutKey,
|
|
232
277
|
hasApiKey: !!apiKey,
|
|
233
278
|
...displayName && { displayName }
|
|
279
|
+
},
|
|
280
|
+
routing: {
|
|
281
|
+
viaDexto
|
|
234
282
|
}
|
|
235
283
|
});
|
|
236
284
|
}).openapi(catalogRoute, (ctx) => {
|
|
237
285
|
const queryParams = ctx.req.valid("query");
|
|
286
|
+
const includeModels = queryParams.includeModels ?? true;
|
|
287
|
+
const scope = queryParams.scope ?? "all";
|
|
238
288
|
const providers = {};
|
|
239
289
|
for (const provider of LLM_PROVIDERS) {
|
|
290
|
+
if (provider === "dexto-nova" && !isDextoAuthEnabled()) {
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
240
293
|
const info = LLM_REGISTRY[provider];
|
|
241
|
-
const displayName = provider.charAt(0).toUpperCase() + provider.slice(1);
|
|
294
|
+
const displayName = provider === "dexto-nova" ? "Dexto Nova" : provider.charAt(0).toUpperCase() + provider.slice(1);
|
|
242
295
|
const keyStatus = getProviderKeyStatus(provider);
|
|
296
|
+
const models = (() => {
|
|
297
|
+
if (!includeModels) return [];
|
|
298
|
+
if (scope === "all") {
|
|
299
|
+
return getAllModelsForProvider(provider);
|
|
300
|
+
}
|
|
301
|
+
return getCuratedModelsForProvider(provider);
|
|
302
|
+
})();
|
|
243
303
|
providers[provider] = {
|
|
244
304
|
name: displayName,
|
|
245
305
|
hasApiKey: keyStatus.hasApiKey,
|
|
246
306
|
primaryEnvVar: keyStatus.envVar,
|
|
247
307
|
supportsBaseURL: supportsBaseURL(provider),
|
|
248
|
-
models
|
|
308
|
+
models,
|
|
249
309
|
supportedFileTypes: info.supportedFileTypes
|
|
250
310
|
};
|
|
251
311
|
}
|
|
@@ -340,6 +400,20 @@ function createLlmRouter(getAgent) {
|
|
|
340
400
|
);
|
|
341
401
|
}
|
|
342
402
|
return ctx.json({ ok: true, deleted: name }, 200);
|
|
403
|
+
}).openapi(capabilitiesRoute, (ctx) => {
|
|
404
|
+
const { provider, model } = ctx.req.valid("query");
|
|
405
|
+
let supportedFileTypes;
|
|
406
|
+
try {
|
|
407
|
+
supportedFileTypes = getSupportedFileTypesForModel(provider, model);
|
|
408
|
+
} catch {
|
|
409
|
+
const providerInfo = LLM_REGISTRY[provider];
|
|
410
|
+
supportedFileTypes = providerInfo?.supportedFileTypes ?? [];
|
|
411
|
+
}
|
|
412
|
+
return ctx.json({
|
|
413
|
+
provider,
|
|
414
|
+
model,
|
|
415
|
+
supportedFileTypes
|
|
416
|
+
});
|
|
343
417
|
});
|
|
344
418
|
}
|
|
345
419
|
export {
|
|
@@ -46,7 +46,7 @@ export declare function createMcpRouter(getAgent: GetAgentFn): OpenAPIHono<impor
|
|
|
46
46
|
input: {};
|
|
47
47
|
output: {
|
|
48
48
|
servers: {
|
|
49
|
-
status: "error" | "connected" | "disconnected";
|
|
49
|
+
status: "error" | "connected" | "disconnected" | "auth-required";
|
|
50
50
|
id: string;
|
|
51
51
|
name: string;
|
|
52
52
|
}[];
|
|
@@ -106,7 +106,7 @@ export declare function createMessagesRouter(getAgent: GetAgentFn, approvalCoord
|
|
|
106
106
|
totalTokens?: number | undefined;
|
|
107
107
|
} | undefined;
|
|
108
108
|
model?: string | undefined;
|
|
109
|
-
provider?: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama" | undefined;
|
|
109
|
+
provider?: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "minimax" | "glm" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama" | "dexto-nova" | undefined;
|
|
110
110
|
};
|
|
111
111
|
outputFormat: "json";
|
|
112
112
|
status: 200;
|
|
@@ -27,7 +27,8 @@ const QueuedMessageSchema = import_zod_openapi.z.object({
|
|
|
27
27
|
id: import_zod_openapi.z.string().describe("Unique identifier for the queued message"),
|
|
28
28
|
content: import_zod_openapi.z.array(import_responses.ContentPartSchema).describe("Message content parts"),
|
|
29
29
|
queuedAt: import_zod_openapi.z.number().describe("Unix timestamp when message was queued"),
|
|
30
|
-
metadata: import_zod_openapi.z.record(import_zod_openapi.z.unknown()).optional().describe("Optional metadata")
|
|
30
|
+
metadata: import_zod_openapi.z.record(import_zod_openapi.z.unknown()).optional().describe("Optional metadata"),
|
|
31
|
+
kind: import_zod_openapi.z.enum(["default", "background"]).optional().describe("Optional queued message kind")
|
|
31
32
|
}).strict().describe("A message waiting in the queue");
|
|
32
33
|
const TextPartSchema = import_zod_openapi.z.object({
|
|
33
34
|
type: import_zod_openapi.z.literal("text").describe("Content type identifier"),
|
|
@@ -46,7 +47,8 @@ const FilePartSchema = import_zod_openapi.z.object({
|
|
|
46
47
|
}).describe("File content part");
|
|
47
48
|
const QueueContentPartSchema = import_zod_openapi.z.discriminatedUnion("type", [TextPartSchema, ImagePartSchema, FilePartSchema]).describe("Content part - text, image, or file");
|
|
48
49
|
const QueueMessageBodySchema = import_zod_openapi.z.object({
|
|
49
|
-
content: import_zod_openapi.z.union([import_zod_openapi.z.string(), import_zod_openapi.z.array(QueueContentPartSchema)]).describe("Message content - string for text, or ContentPart[] for multimodal")
|
|
50
|
+
content: import_zod_openapi.z.union([import_zod_openapi.z.string(), import_zod_openapi.z.array(QueueContentPartSchema)]).describe("Message content - string for text, or ContentPart[] for multimodal"),
|
|
51
|
+
kind: import_zod_openapi.z.enum(["default", "background"]).optional().describe("Optional queued message kind")
|
|
50
52
|
}).describe("Request body for queueing a message");
|
|
51
53
|
function createQueueRouter(getAgent) {
|
|
52
54
|
const app = new import_zod_openapi.OpenAPIHono();
|
|
@@ -172,7 +174,11 @@ function createQueueRouter(getAgent) {
|
|
|
172
174
|
const { sessionId } = ctx.req.valid("param");
|
|
173
175
|
const { content: rawContent } = ctx.req.valid("json");
|
|
174
176
|
const content = typeof rawContent === "string" ? [{ type: "text", text: rawContent }] : rawContent;
|
|
175
|
-
const
|
|
177
|
+
const { kind } = ctx.req.valid("json");
|
|
178
|
+
const result = await agent.queueMessage(sessionId, {
|
|
179
|
+
content,
|
|
180
|
+
...kind !== void 0 && { kind }
|
|
181
|
+
});
|
|
176
182
|
return ctx.json(
|
|
177
183
|
{
|
|
178
184
|
queued: result.queued,
|