@dexto/server 1.4.0 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/dist/hono/__tests__/test-fixtures.cjs +1 -1
  2. package/dist/hono/__tests__/test-fixtures.d.ts.map +1 -1
  3. package/dist/hono/__tests__/test-fixtures.js +1 -1
  4. package/dist/hono/index.cjs +41 -5
  5. package/dist/hono/index.d.ts +470 -456
  6. package/dist/hono/index.d.ts.map +1 -1
  7. package/dist/hono/index.js +41 -5
  8. package/dist/hono/routes/a2a-jsonrpc.cjs +3 -3
  9. package/dist/hono/routes/a2a-jsonrpc.d.ts +4 -1
  10. package/dist/hono/routes/a2a-jsonrpc.d.ts.map +1 -1
  11. package/dist/hono/routes/a2a-jsonrpc.js +3 -3
  12. package/dist/hono/routes/a2a-tasks.cjs +5 -5
  13. package/dist/hono/routes/a2a-tasks.d.ts +13 -10
  14. package/dist/hono/routes/a2a-tasks.d.ts.map +1 -1
  15. package/dist/hono/routes/a2a-tasks.js +5 -5
  16. package/dist/hono/routes/agents.cjs +25 -35
  17. package/dist/hono/routes/agents.d.ts +6 -407
  18. package/dist/hono/routes/agents.d.ts.map +1 -1
  19. package/dist/hono/routes/agents.js +25 -35
  20. package/dist/hono/routes/approvals.cjs +2 -2
  21. package/dist/hono/routes/approvals.d.ts +4 -1
  22. package/dist/hono/routes/approvals.d.ts.map +1 -1
  23. package/dist/hono/routes/approvals.js +2 -2
  24. package/dist/hono/routes/discovery.cjs +68 -0
  25. package/dist/hono/routes/discovery.d.ts +53 -0
  26. package/dist/hono/routes/discovery.d.ts.map +1 -0
  27. package/dist/hono/routes/discovery.js +44 -0
  28. package/dist/hono/routes/greeting.cjs +2 -2
  29. package/dist/hono/routes/greeting.d.ts +2 -2
  30. package/dist/hono/routes/greeting.d.ts.map +1 -1
  31. package/dist/hono/routes/greeting.js +2 -2
  32. package/dist/hono/routes/health.d.ts +2 -2
  33. package/dist/hono/routes/health.d.ts.map +1 -1
  34. package/dist/hono/routes/key.cjs +110 -0
  35. package/dist/hono/routes/key.d.ts +48 -0
  36. package/dist/hono/routes/key.d.ts.map +1 -0
  37. package/dist/hono/routes/key.js +90 -0
  38. package/dist/hono/routes/llm.cjs +12 -34
  39. package/dist/hono/routes/llm.d.ts +179 -25
  40. package/dist/hono/routes/llm.d.ts.map +1 -1
  41. package/dist/hono/routes/llm.js +12 -35
  42. package/dist/hono/routes/mcp.cjs +8 -8
  43. package/dist/hono/routes/mcp.d.ts +2 -2
  44. package/dist/hono/routes/mcp.d.ts.map +1 -1
  45. package/dist/hono/routes/mcp.js +8 -8
  46. package/dist/hono/routes/memory.cjs +5 -5
  47. package/dist/hono/routes/memory.d.ts +8 -5
  48. package/dist/hono/routes/memory.d.ts.map +1 -1
  49. package/dist/hono/routes/memory.js +5 -5
  50. package/dist/hono/routes/messages.cjs +4 -4
  51. package/dist/hono/routes/messages.d.ts +12 -12
  52. package/dist/hono/routes/messages.d.ts.map +1 -1
  53. package/dist/hono/routes/messages.js +4 -4
  54. package/dist/hono/routes/models.cjs +319 -0
  55. package/dist/hono/routes/models.d.ts +107 -0
  56. package/dist/hono/routes/models.d.ts.map +1 -0
  57. package/dist/hono/routes/models.js +305 -0
  58. package/dist/hono/routes/openrouter.cjs +153 -0
  59. package/dist/hono/routes/openrouter.d.ts +54 -0
  60. package/dist/hono/routes/openrouter.d.ts.map +1 -0
  61. package/dist/hono/routes/openrouter.js +134 -0
  62. package/dist/hono/routes/prompts.cjs +5 -5
  63. package/dist/hono/routes/prompts.d.ts +4 -1
  64. package/dist/hono/routes/prompts.d.ts.map +1 -1
  65. package/dist/hono/routes/prompts.js +5 -5
  66. package/dist/hono/routes/queue.cjs +4 -4
  67. package/dist/hono/routes/queue.d.ts +4 -1
  68. package/dist/hono/routes/queue.d.ts.map +1 -1
  69. package/dist/hono/routes/queue.js +4 -4
  70. package/dist/hono/routes/resources.cjs +3 -3
  71. package/dist/hono/routes/resources.d.ts +2 -2
  72. package/dist/hono/routes/resources.d.ts.map +1 -1
  73. package/dist/hono/routes/resources.js +3 -3
  74. package/dist/hono/routes/search.cjs +2 -2
  75. package/dist/hono/routes/search.d.ts +6 -3
  76. package/dist/hono/routes/search.d.ts.map +1 -1
  77. package/dist/hono/routes/search.js +2 -2
  78. package/dist/hono/routes/sessions.cjs +9 -9
  79. package/dist/hono/routes/sessions.d.ts +3 -3
  80. package/dist/hono/routes/sessions.d.ts.map +1 -1
  81. package/dist/hono/routes/sessions.js +9 -9
  82. package/dist/hono/routes/tools.cjs +126 -0
  83. package/dist/hono/routes/tools.d.ts +42 -0
  84. package/dist/hono/routes/tools.d.ts.map +1 -0
  85. package/dist/hono/routes/tools.js +102 -0
  86. package/dist/hono/routes/webhooks.cjs +4 -4
  87. package/dist/hono/routes/webhooks.d.ts +4 -1
  88. package/dist/hono/routes/webhooks.d.ts.map +1 -1
  89. package/dist/hono/routes/webhooks.js +4 -4
  90. package/dist/hono/schemas/responses.d.ts +47 -41
  91. package/dist/hono/schemas/responses.d.ts.map +1 -1
  92. package/dist/hono/start-server.cjs +102 -0
  93. package/dist/hono/start-server.d.ts +61 -0
  94. package/dist/hono/start-server.d.ts.map +1 -0
  95. package/dist/hono/start-server.js +78 -0
  96. package/dist/index.cjs +2 -0
  97. package/dist/index.d.ts +1 -0
  98. package/dist/index.d.ts.map +1 -1
  99. package/dist/index.js +1 -0
  100. package/package.json +5 -4
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var discovery_exports = {};
20
+ __export(discovery_exports, {
21
+ createDiscoveryRouter: () => createDiscoveryRouter
22
+ });
23
+ module.exports = __toCommonJS(discovery_exports);
24
+ var import_zod_openapi = require("@hono/zod-openapi");
25
+ var import_core = require("@dexto/core");
26
+ const DiscoveredProviderSchema = import_zod_openapi.z.object({
27
+ type: import_zod_openapi.z.string().describe("Provider type identifier"),
28
+ category: import_zod_openapi.z.enum(["blob", "database", "compaction", "customTools"]).describe("Provider category"),
29
+ metadata: import_zod_openapi.z.object({
30
+ displayName: import_zod_openapi.z.string().optional().describe("Human-readable display name"),
31
+ description: import_zod_openapi.z.string().optional().describe("Provider description")
32
+ }).passthrough().optional().describe("Optional metadata about the provider")
33
+ }).describe("Information about a registered provider");
34
+ const InternalToolSchema = import_zod_openapi.z.object({
35
+ name: import_zod_openapi.z.string().describe('Internal tool name identifier (e.g., "search_history", "ask_user")'),
36
+ description: import_zod_openapi.z.string().describe("Human-readable description of what the tool does")
37
+ }).describe("Information about an internal tool");
38
+ const DiscoveryResponseSchema = import_zod_openapi.z.object({
39
+ blob: import_zod_openapi.z.array(DiscoveredProviderSchema).describe("Blob storage providers"),
40
+ database: import_zod_openapi.z.array(DiscoveredProviderSchema).describe("Database providers"),
41
+ compaction: import_zod_openapi.z.array(DiscoveredProviderSchema).describe("Compaction strategy providers"),
42
+ customTools: import_zod_openapi.z.array(DiscoveredProviderSchema).describe("Custom tool providers"),
43
+ internalTools: import_zod_openapi.z.array(InternalToolSchema).describe("Internal tools available for configuration")
44
+ }).describe("Discovery response with providers grouped by category");
45
+ function createDiscoveryRouter() {
46
+ const app = new import_zod_openapi.OpenAPIHono();
47
+ const discoveryRoute = (0, import_zod_openapi.createRoute)({
48
+ method: "get",
49
+ path: "/discovery",
50
+ summary: "Discover Available Providers and Tools",
51
+ description: "Returns all registered providers (blob storage, database, compaction, custom tools) and available internal tools. Useful for building UIs that need to display configurable options.",
52
+ tags: ["discovery"],
53
+ responses: {
54
+ 200: {
55
+ description: "Available providers grouped by category",
56
+ content: { "application/json": { schema: DiscoveryResponseSchema } }
57
+ }
58
+ }
59
+ });
60
+ return app.openapi(discoveryRoute, async (ctx) => {
61
+ const providers = (0, import_core.listAllProviders)();
62
+ return ctx.json(providers);
63
+ });
64
+ }
65
+ // Annotate the CommonJS export names for ESM import in node:
66
+ 0 && (module.exports = {
67
+ createDiscoveryRouter
68
+ });
@@ -0,0 +1,53 @@
1
+ import { OpenAPIHono } from '@hono/zod-openapi';
2
+ export declare function createDiscoveryRouter(): OpenAPIHono<import("hono").Env, {
3
+ "/discovery": {
4
+ $get: {
5
+ input: {};
6
+ output: {
7
+ internalTools: {
8
+ description: string;
9
+ name: string;
10
+ }[];
11
+ customTools: {
12
+ type: string;
13
+ category: "customTools" | "compaction" | "blob" | "database";
14
+ metadata?: {
15
+ [x: string]: import("hono/utils/types").JSONValue;
16
+ description?: string | undefined;
17
+ displayName?: string | undefined;
18
+ } | undefined;
19
+ }[];
20
+ compaction: {
21
+ type: string;
22
+ category: "customTools" | "compaction" | "blob" | "database";
23
+ metadata?: {
24
+ [x: string]: import("hono/utils/types").JSONValue;
25
+ description?: string | undefined;
26
+ displayName?: string | undefined;
27
+ } | undefined;
28
+ }[];
29
+ blob: {
30
+ type: string;
31
+ category: "customTools" | "compaction" | "blob" | "database";
32
+ metadata?: {
33
+ [x: string]: import("hono/utils/types").JSONValue;
34
+ description?: string | undefined;
35
+ displayName?: string | undefined;
36
+ } | undefined;
37
+ }[];
38
+ database: {
39
+ type: string;
40
+ category: "customTools" | "compaction" | "blob" | "database";
41
+ metadata?: {
42
+ [x: string]: import("hono/utils/types").JSONValue;
43
+ description?: string | undefined;
44
+ displayName?: string | undefined;
45
+ } | undefined;
46
+ }[];
47
+ };
48
+ outputFormat: "json";
49
+ status: 200;
50
+ };
51
+ };
52
+ }, "/">;
53
+ //# sourceMappingURL=discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAyChE,wBAAgB,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAsBpC"}
@@ -0,0 +1,44 @@
1
+ import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
2
+ import { listAllProviders } from "@dexto/core";
3
+ const DiscoveredProviderSchema = z.object({
4
+ type: z.string().describe("Provider type identifier"),
5
+ category: z.enum(["blob", "database", "compaction", "customTools"]).describe("Provider category"),
6
+ metadata: z.object({
7
+ displayName: z.string().optional().describe("Human-readable display name"),
8
+ description: z.string().optional().describe("Provider description")
9
+ }).passthrough().optional().describe("Optional metadata about the provider")
10
+ }).describe("Information about a registered provider");
11
+ const InternalToolSchema = z.object({
12
+ name: z.string().describe('Internal tool name identifier (e.g., "search_history", "ask_user")'),
13
+ description: z.string().describe("Human-readable description of what the tool does")
14
+ }).describe("Information about an internal tool");
15
+ const DiscoveryResponseSchema = z.object({
16
+ blob: z.array(DiscoveredProviderSchema).describe("Blob storage providers"),
17
+ database: z.array(DiscoveredProviderSchema).describe("Database providers"),
18
+ compaction: z.array(DiscoveredProviderSchema).describe("Compaction strategy providers"),
19
+ customTools: z.array(DiscoveredProviderSchema).describe("Custom tool providers"),
20
+ internalTools: z.array(InternalToolSchema).describe("Internal tools available for configuration")
21
+ }).describe("Discovery response with providers grouped by category");
22
+ function createDiscoveryRouter() {
23
+ const app = new OpenAPIHono();
24
+ const discoveryRoute = createRoute({
25
+ method: "get",
26
+ path: "/discovery",
27
+ summary: "Discover Available Providers and Tools",
28
+ description: "Returns all registered providers (blob storage, database, compaction, custom tools) and available internal tools. Useful for building UIs that need to display configurable options.",
29
+ tags: ["discovery"],
30
+ responses: {
31
+ 200: {
32
+ description: "Available providers grouped by category",
33
+ content: { "application/json": { schema: DiscoveryResponseSchema } }
34
+ }
35
+ }
36
+ });
37
+ return app.openapi(discoveryRoute, async (ctx) => {
38
+ const providers = listAllProviders();
39
+ return ctx.json(providers);
40
+ });
41
+ }
42
+ export {
43
+ createDiscoveryRouter
44
+ };
@@ -47,8 +47,8 @@ function createGreetingRouter(getAgent) {
47
47
  }
48
48
  }
49
49
  });
50
- return app.openapi(greetingRoute, (ctx) => {
51
- const agent = getAgent();
50
+ return app.openapi(greetingRoute, async (ctx) => {
51
+ const agent = await getAgent(ctx);
52
52
  const { sessionId } = ctx.req.valid("query");
53
53
  const cfg = agent.getEffectiveConfig(sessionId);
54
54
  return ctx.json({ greeting: cfg.greeting });
@@ -1,6 +1,6 @@
1
1
  import { OpenAPIHono } from '@hono/zod-openapi';
2
- import type { DextoAgent } from '@dexto/core';
3
- export declare function createGreetingRouter(getAgent: () => DextoAgent): OpenAPIHono<import("hono").Env, {
2
+ import type { GetAgentFn } from '../index.js';
3
+ export declare function createGreetingRouter(getAgent: GetAgentFn): OpenAPIHono<import("hono").Env, {
4
4
  "/greeting": {
5
5
  $get: {
6
6
  input: {
@@ -1 +1 @@
1
- {"version":3,"file":"greeting.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/greeting.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAW9C,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,UAAU;;;;;;;;;;;;;;;QAmC9D"}
1
+ {"version":3,"file":"greeting.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/greeting.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAW9C,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,UAAU;;;;;;;;;;;;;;;QAmCxD"}
@@ -24,8 +24,8 @@ function createGreetingRouter(getAgent) {
24
24
  }
25
25
  }
26
26
  });
27
- return app.openapi(greetingRoute, (ctx) => {
28
- const agent = getAgent();
27
+ return app.openapi(greetingRoute, async (ctx) => {
28
+ const agent = await getAgent(ctx);
29
29
  const { sessionId } = ctx.req.valid("query");
30
30
  const cfg = agent.getEffectiveConfig(sessionId);
31
31
  return ctx.json({ greeting: cfg.greeting });
@@ -1,10 +1,10 @@
1
1
  import { OpenAPIHono } from '@hono/zod-openapi';
2
- import type { DextoAgent } from '@dexto/core';
2
+ import type { GetAgentFn } from '../index.js';
3
3
  /**
4
4
  * NOTE: If we introduce a transport-agnostic handler layer later, the logic in this module can move
5
5
  * into that layer. For now we keep the implementation inline for simplicity.
6
6
  */
7
- export declare function createHealthRouter(_getAgent: () => DextoAgent): OpenAPIHono<import("hono").Env, {
7
+ export declare function createHealthRouter(_getAgent: GetAgentFn): OpenAPIHono<import("hono").Env, {
8
8
  "/": {
9
9
  $get: {
10
10
  input: {};
@@ -1 +1 @@
1
- {"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/health.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,UAAU;;;;;;;;;QAiB7D"}
1
+ {"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/health.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,UAAU;;;;;;;;;QAiBvD"}
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var key_exports = {};
20
+ __export(key_exports, {
21
+ createKeyRouter: () => createKeyRouter
22
+ });
23
+ module.exports = __toCommonJS(key_exports);
24
+ var import_zod_openapi = require("@hono/zod-openapi");
25
+ var import_core = require("@dexto/core");
26
+ var import_agent_management = require("@dexto/agent-management");
27
+ function maskApiKey(key) {
28
+ if (!key) return "";
29
+ if (key.length < 12) {
30
+ return key.slice(0, 4) + "..." + key.slice(-4);
31
+ }
32
+ return key.slice(0, 7) + "..." + key.slice(-4);
33
+ }
34
+ const GetKeyParamsSchema = import_zod_openapi.z.object({
35
+ provider: import_zod_openapi.z.enum(import_core.LLM_PROVIDERS).describe("LLM provider identifier")
36
+ }).describe("Path parameters for API key operations");
37
+ const SaveKeySchema = import_zod_openapi.z.object({
38
+ provider: import_zod_openapi.z.enum(import_core.LLM_PROVIDERS).describe("LLM provider identifier (e.g., openai, anthropic)"),
39
+ 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 })
40
+ }).describe("Request body for saving a provider API key");
41
+ function createKeyRouter() {
42
+ const app = new import_zod_openapi.OpenAPIHono();
43
+ const getKeyRoute = (0, import_zod_openapi.createRoute)({
44
+ method: "get",
45
+ path: "/llm/key/{provider}",
46
+ summary: "Get Provider API Key Status",
47
+ description: "Retrieves the API key status for a provider. Returns a masked key value (e.g., sk-proj...xyz4) for UI display purposes.",
48
+ tags: ["llm"],
49
+ request: { params: GetKeyParamsSchema },
50
+ responses: {
51
+ 200: {
52
+ description: "API key status and value",
53
+ content: {
54
+ "application/json": {
55
+ schema: import_zod_openapi.z.object({
56
+ provider: import_zod_openapi.z.enum(import_core.LLM_PROVIDERS).describe("Provider identifier"),
57
+ envVar: import_zod_openapi.z.string().describe("Environment variable name"),
58
+ hasKey: import_zod_openapi.z.boolean().describe("Whether API key is configured"),
59
+ keyValue: import_zod_openapi.z.string().optional().describe(
60
+ "Masked API key value if configured (e.g., sk-proj...xyz4)"
61
+ )
62
+ }).strict().describe("API key status response")
63
+ }
64
+ }
65
+ }
66
+ }
67
+ });
68
+ const saveKeyRoute = (0, import_zod_openapi.createRoute)({
69
+ method: "post",
70
+ path: "/llm/key",
71
+ summary: "Save Provider API Key",
72
+ description: "Stores an API key for a provider in .env and makes it available immediately",
73
+ tags: ["llm"],
74
+ request: { body: { content: { "application/json": { schema: SaveKeySchema } } } },
75
+ responses: {
76
+ 200: {
77
+ description: "API key saved",
78
+ content: {
79
+ "application/json": {
80
+ schema: import_zod_openapi.z.object({
81
+ ok: import_zod_openapi.z.literal(true).describe("Operation success indicator"),
82
+ provider: import_zod_openapi.z.enum(import_core.LLM_PROVIDERS).describe("Provider for which the key was saved"),
83
+ envVar: import_zod_openapi.z.string().describe("Environment variable name where key was stored")
84
+ }).strict().describe("API key save response")
85
+ }
86
+ }
87
+ }
88
+ }
89
+ });
90
+ return app.openapi(getKeyRoute, (ctx) => {
91
+ const { provider } = ctx.req.valid("param");
92
+ const keyStatus = (0, import_agent_management.getProviderKeyStatus)(provider);
93
+ const apiKey = (0, import_agent_management.resolveApiKeyForProvider)(provider);
94
+ const maskedKey = apiKey ? maskApiKey(apiKey) : void 0;
95
+ return ctx.json({
96
+ provider,
97
+ envVar: keyStatus.envVar,
98
+ hasKey: keyStatus.hasApiKey,
99
+ ...maskedKey && { keyValue: maskedKey }
100
+ });
101
+ }).openapi(saveKeyRoute, async (ctx) => {
102
+ const { provider, apiKey } = ctx.req.valid("json");
103
+ const meta = await (0, import_agent_management.saveProviderApiKey)(provider, apiKey);
104
+ return ctx.json({ ok: true, provider, envVar: meta.envVar });
105
+ });
106
+ }
107
+ // Annotate the CommonJS export names for ESM import in node:
108
+ 0 && (module.exports = {
109
+ createKeyRouter
110
+ });
@@ -0,0 +1,48 @@
1
+ /**
2
+ * API Key Management Routes
3
+ *
4
+ * Endpoints for managing LLM provider API keys.
5
+ *
6
+ * TODO: For hosted deployments, these endpoints should integrate with a secure
7
+ * key management service (e.g., AWS Secrets Manager, HashiCorp Vault) rather
8
+ * than storing keys in local .env files.
9
+ */
10
+ import { OpenAPIHono } from '@hono/zod-openapi';
11
+ export declare function createKeyRouter(): OpenAPIHono<import("hono").Env, {
12
+ "/llm/key/:provider": {
13
+ $get: {
14
+ input: {
15
+ param: {
16
+ provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama";
17
+ };
18
+ };
19
+ output: {
20
+ provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama";
21
+ hasKey: boolean;
22
+ envVar: string;
23
+ keyValue?: string | undefined;
24
+ };
25
+ outputFormat: "json";
26
+ status: 200;
27
+ };
28
+ };
29
+ } & {
30
+ "/llm/key": {
31
+ $post: {
32
+ input: {
33
+ json: {
34
+ provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama";
35
+ apiKey: string;
36
+ };
37
+ };
38
+ output: {
39
+ provider: "openai" | "openai-compatible" | "anthropic" | "google" | "groq" | "xai" | "cohere" | "openrouter" | "litellm" | "glama" | "vertex" | "bedrock" | "local" | "ollama";
40
+ ok: true;
41
+ envVar: string;
42
+ };
43
+ outputFormat: "json";
44
+ status: 200;
45
+ };
46
+ };
47
+ }, "/">;
48
+ //# sourceMappingURL=key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/key.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAuChE,wBAAgB,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAsF9B"}
@@ -0,0 +1,90 @@
1
+ import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
2
+ import { LLM_PROVIDERS } from "@dexto/core";
3
+ import {
4
+ getProviderKeyStatus,
5
+ saveProviderApiKey,
6
+ resolveApiKeyForProvider
7
+ } from "@dexto/agent-management";
8
+ function maskApiKey(key) {
9
+ if (!key) return "";
10
+ if (key.length < 12) {
11
+ return key.slice(0, 4) + "..." + key.slice(-4);
12
+ }
13
+ return key.slice(0, 7) + "..." + key.slice(-4);
14
+ }
15
+ const GetKeyParamsSchema = z.object({
16
+ provider: z.enum(LLM_PROVIDERS).describe("LLM provider identifier")
17
+ }).describe("Path parameters for API key operations");
18
+ const SaveKeySchema = z.object({
19
+ provider: z.enum(LLM_PROVIDERS).describe("LLM provider identifier (e.g., openai, anthropic)"),
20
+ apiKey: z.string().min(1, "API key is required").describe("API key for the provider (writeOnly - never returned in responses)").openapi({ writeOnly: true })
21
+ }).describe("Request body for saving a provider API key");
22
+ function createKeyRouter() {
23
+ const app = new OpenAPIHono();
24
+ const getKeyRoute = createRoute({
25
+ method: "get",
26
+ path: "/llm/key/{provider}",
27
+ summary: "Get Provider API Key Status",
28
+ description: "Retrieves the API key status for a provider. Returns a masked key value (e.g., sk-proj...xyz4) for UI display purposes.",
29
+ tags: ["llm"],
30
+ request: { params: GetKeyParamsSchema },
31
+ responses: {
32
+ 200: {
33
+ description: "API key status and value",
34
+ content: {
35
+ "application/json": {
36
+ schema: z.object({
37
+ provider: z.enum(LLM_PROVIDERS).describe("Provider identifier"),
38
+ envVar: z.string().describe("Environment variable name"),
39
+ hasKey: z.boolean().describe("Whether API key is configured"),
40
+ keyValue: z.string().optional().describe(
41
+ "Masked API key value if configured (e.g., sk-proj...xyz4)"
42
+ )
43
+ }).strict().describe("API key status response")
44
+ }
45
+ }
46
+ }
47
+ }
48
+ });
49
+ const saveKeyRoute = createRoute({
50
+ method: "post",
51
+ path: "/llm/key",
52
+ summary: "Save Provider API Key",
53
+ description: "Stores an API key for a provider in .env and makes it available immediately",
54
+ tags: ["llm"],
55
+ request: { body: { content: { "application/json": { schema: SaveKeySchema } } } },
56
+ responses: {
57
+ 200: {
58
+ description: "API key saved",
59
+ content: {
60
+ "application/json": {
61
+ schema: z.object({
62
+ ok: z.literal(true).describe("Operation success indicator"),
63
+ provider: z.enum(LLM_PROVIDERS).describe("Provider for which the key was saved"),
64
+ envVar: z.string().describe("Environment variable name where key was stored")
65
+ }).strict().describe("API key save response")
66
+ }
67
+ }
68
+ }
69
+ }
70
+ });
71
+ return app.openapi(getKeyRoute, (ctx) => {
72
+ const { provider } = ctx.req.valid("param");
73
+ const keyStatus = getProviderKeyStatus(provider);
74
+ const apiKey = resolveApiKeyForProvider(provider);
75
+ const maskedKey = apiKey ? maskApiKey(apiKey) : void 0;
76
+ return ctx.json({
77
+ provider,
78
+ envVar: keyStatus.envVar,
79
+ hasKey: keyStatus.hasApiKey,
80
+ ...maskedKey && { keyValue: maskedKey }
81
+ });
82
+ }).openapi(saveKeyRoute, async (ctx) => {
83
+ const { provider, apiKey } = ctx.req.valid("json");
84
+ const meta = await saveProviderApiKey(provider, apiKey);
85
+ return ctx.json({ ok: true, provider, envVar: meta.envVar });
86
+ });
87
+ }
88
+ export {
89
+ createKeyRouter
90
+ };
@@ -42,10 +42,6 @@ const CatalogQuerySchema = import_zod_openapi.z.object({
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
- const SaveKeySchema = import_zod_openapi.z.object({
46
- provider: import_zod_openapi.z.enum(import_core2.LLM_PROVIDERS).describe("LLM provider identifier (e.g., openai, anthropic)"),
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
- }).describe("Request body for saving a provider API key");
49
45
  const SwitchLLMBodySchema = import_core2.LLMUpdatesSchema.and(
50
46
  import_zod_openapi.z.object({
51
47
  sessionId: import_zod_openapi.z.string().optional().describe("Session identifier for session-specific LLM configuration")
@@ -108,28 +104,6 @@ function createLlmRouter(getAgent) {
108
104
  }
109
105
  }
110
106
  });
111
- const saveKeyRoute = (0, import_zod_openapi.createRoute)({
112
- method: "post",
113
- path: "/llm/key",
114
- summary: "Save Provider API Key",
115
- description: "Stores an API key for a provider in .env and makes it available immediately",
116
- tags: ["llm"],
117
- request: { body: { content: { "application/json": { schema: SaveKeySchema } } } },
118
- responses: {
119
- 200: {
120
- description: "API key saved",
121
- content: {
122
- "application/json": {
123
- schema: import_zod_openapi.z.object({
124
- ok: import_zod_openapi.z.literal(true).describe("Operation success indicator"),
125
- provider: import_zod_openapi.z.enum(import_core2.LLM_PROVIDERS).describe("Provider for which the key was saved"),
126
- envVar: import_zod_openapi.z.string().describe("Environment variable name where key was stored")
127
- }).strict().describe("API key save response")
128
- }
129
- }
130
- }
131
- }
132
- });
133
107
  const switchRoute = (0, import_zod_openapi.createRoute)({
134
108
  method: "post",
135
109
  path: "/llm/switch",
@@ -239,8 +213,8 @@ function createLlmRouter(getAgent) {
239
213
  }
240
214
  }
241
215
  });
242
- return app.openapi(currentRoute, (ctx) => {
243
- const agent = getAgent();
216
+ return app.openapi(currentRoute, async (ctx) => {
217
+ const agent = await getAgent(ctx);
244
218
  const { sessionId } = ctx.req.valid("query");
245
219
  const currentConfig = sessionId ? agent.getEffectiveConfig(sessionId).llm : agent.getCurrentLLMConfig();
246
220
  let displayName;
@@ -249,6 +223,13 @@ function createLlmRouter(getAgent) {
249
223
  (m) => m.name.toLowerCase() === String(currentConfig.model).toLowerCase()
250
224
  );
251
225
  displayName = model?.displayName || void 0;
226
+ if (!displayName) {
227
+ const customModels = await (0, import_agent_management.loadCustomModels)();
228
+ const customModel = customModels.find(
229
+ (cm) => cm.name.toLowerCase() === String(currentConfig.model).toLowerCase()
230
+ );
231
+ displayName = customModel?.displayName || void 0;
232
+ }
252
233
  } catch {
253
234
  }
254
235
  const { apiKey, ...configWithoutKey } = currentConfig;
@@ -332,12 +313,8 @@ function createLlmRouter(getAgent) {
332
313
  return ctx.json({ models: flat });
333
314
  }
334
315
  return ctx.json({ providers: filtered });
335
- }).openapi(saveKeyRoute, async (ctx) => {
336
- const { provider, apiKey } = ctx.req.valid("json");
337
- const meta = await (0, import_agent_management.saveProviderApiKey)(provider, apiKey, process.cwd());
338
- return ctx.json({ ok: true, provider, envVar: meta.envVar });
339
316
  }).openapi(switchRoute, async (ctx) => {
340
- const agent = getAgent();
317
+ const agent = await getAgent(ctx);
341
318
  const raw = ctx.req.valid("json");
342
319
  const { sessionId, ...llmUpdates } = raw;
343
320
  const config = await agent.switchLLM(llmUpdates, sessionId);
@@ -357,7 +334,8 @@ function createLlmRouter(getAgent) {
357
334
  await (0, import_agent_management.saveCustomModel)(model);
358
335
  return ctx.json({ ok: true, model });
359
336
  }).openapi(deleteCustomModelRoute, async (ctx) => {
360
- const { name } = ctx.req.valid("param");
337
+ const { name: encodedName } = ctx.req.valid("param");
338
+ const name = decodeURIComponent(encodedName);
361
339
  const deleted = await (0, import_agent_management.deleteCustomModel)(name);
362
340
  if (!deleted) {
363
341
  throw new import_core.DextoRuntimeError(