@dexto/server 1.2.5
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/LICENSE +44 -0
- package/dist/a2a/adapters/index.cjs +42 -0
- package/dist/a2a/adapters/index.d.ts +10 -0
- package/dist/a2a/adapters/index.d.ts.map +1 -0
- package/dist/a2a/adapters/index.js +12 -0
- package/dist/a2a/adapters/message.cjs +193 -0
- package/dist/a2a/adapters/message.d.ts +50 -0
- package/dist/a2a/adapters/message.d.ts.map +1 -0
- package/dist/a2a/adapters/message.js +167 -0
- package/dist/a2a/adapters/state.cjs +57 -0
- package/dist/a2a/adapters/state.d.ts +36 -0
- package/dist/a2a/adapters/state.d.ts.map +1 -0
- package/dist/a2a/adapters/state.js +32 -0
- package/dist/a2a/adapters/task-view.cjs +85 -0
- package/dist/a2a/adapters/task-view.d.ts +58 -0
- package/dist/a2a/adapters/task-view.d.ts.map +1 -0
- package/dist/a2a/adapters/task-view.js +60 -0
- package/dist/a2a/index.cjs +51 -0
- package/dist/a2a/index.d.ts +15 -0
- package/dist/a2a/index.d.ts.map +1 -0
- package/dist/a2a/index.js +30 -0
- package/dist/a2a/jsonrpc/index.cjs +38 -0
- package/dist/a2a/jsonrpc/index.d.ts +11 -0
- package/dist/a2a/jsonrpc/index.d.ts.map +1 -0
- package/dist/a2a/jsonrpc/index.js +10 -0
- package/dist/a2a/jsonrpc/methods.cjs +183 -0
- package/dist/a2a/jsonrpc/methods.d.ts +110 -0
- package/dist/a2a/jsonrpc/methods.d.ts.map +1 -0
- package/dist/a2a/jsonrpc/methods.js +159 -0
- package/dist/a2a/jsonrpc/server.cjs +199 -0
- package/dist/a2a/jsonrpc/server.d.ts +100 -0
- package/dist/a2a/jsonrpc/server.d.ts.map +1 -0
- package/dist/a2a/jsonrpc/server.js +175 -0
- package/dist/a2a/jsonrpc/types.cjs +47 -0
- package/dist/a2a/jsonrpc/types.d.ts +91 -0
- package/dist/a2a/jsonrpc/types.d.ts.map +1 -0
- package/dist/a2a/jsonrpc/types.js +21 -0
- package/dist/a2a/types.cjs +16 -0
- package/dist/a2a/types.d.ts +250 -0
- package/dist/a2a/types.d.ts.map +1 -0
- package/dist/a2a/types.js +0 -0
- package/dist/approval/approval-coordinator.cjs +87 -0
- package/dist/approval/approval-coordinator.d.ts +52 -0
- package/dist/approval/approval-coordinator.d.ts.map +1 -0
- package/dist/approval/approval-coordinator.js +63 -0
- package/dist/approval/manual-approval-handler.cjs +100 -0
- package/dist/approval/manual-approval-handler.d.ts +32 -0
- package/dist/approval/manual-approval-handler.d.ts.map +1 -0
- package/dist/approval/manual-approval-handler.js +76 -0
- package/dist/events/a2a-sse-subscriber.cjs +271 -0
- package/dist/events/a2a-sse-subscriber.d.ts +94 -0
- package/dist/events/a2a-sse-subscriber.d.ts.map +1 -0
- package/dist/events/a2a-sse-subscriber.js +247 -0
- package/dist/events/types.cjs +16 -0
- package/dist/events/types.d.ts +15 -0
- package/dist/events/types.d.ts.map +1 -0
- package/dist/events/types.js +0 -0
- package/dist/events/webhook-subscriber.cjs +301 -0
- package/dist/events/webhook-subscriber.d.ts +64 -0
- package/dist/events/webhook-subscriber.d.ts.map +1 -0
- package/dist/events/webhook-subscriber.js +269 -0
- package/dist/events/webhook-types.cjs +16 -0
- package/dist/events/webhook-types.d.ts +91 -0
- package/dist/events/webhook-types.d.ts.map +1 -0
- package/dist/events/webhook-types.js +0 -0
- package/dist/hono/__tests__/test-fixtures.cjs +236 -0
- package/dist/hono/__tests__/test-fixtures.d.ts +65 -0
- package/dist/hono/__tests__/test-fixtures.d.ts.map +1 -0
- package/dist/hono/__tests__/test-fixtures.js +197 -0
- package/dist/hono/index.cjs +166 -0
- package/dist/hono/index.d.ts +2783 -0
- package/dist/hono/index.d.ts.map +1 -0
- package/dist/hono/index.js +141 -0
- package/dist/hono/middleware/auth.cjs +75 -0
- package/dist/hono/middleware/auth.d.ts +3 -0
- package/dist/hono/middleware/auth.d.ts.map +1 -0
- package/dist/hono/middleware/auth.js +51 -0
- package/dist/hono/middleware/cors.cjs +57 -0
- package/dist/hono/middleware/cors.d.ts +9 -0
- package/dist/hono/middleware/cors.d.ts.map +1 -0
- package/dist/hono/middleware/cors.js +33 -0
- package/dist/hono/middleware/error.cjs +131 -0
- package/dist/hono/middleware/error.d.ts +5 -0
- package/dist/hono/middleware/error.d.ts.map +1 -0
- package/dist/hono/middleware/error.js +105 -0
- package/dist/hono/middleware/redaction.cjs +45 -0
- package/dist/hono/middleware/redaction.d.ts +4 -0
- package/dist/hono/middleware/redaction.d.ts.map +1 -0
- package/dist/hono/middleware/redaction.js +20 -0
- package/dist/hono/node/index.cjs +139 -0
- package/dist/hono/node/index.d.ts +19 -0
- package/dist/hono/node/index.d.ts.map +1 -0
- package/dist/hono/node/index.js +115 -0
- package/dist/hono/routes/a2a-jsonrpc.cjs +119 -0
- package/dist/hono/routes/a2a-jsonrpc.d.ts +46 -0
- package/dist/hono/routes/a2a-jsonrpc.d.ts.map +1 -0
- package/dist/hono/routes/a2a-jsonrpc.js +95 -0
- package/dist/hono/routes/a2a-tasks.cjs +315 -0
- package/dist/hono/routes/a2a-tasks.d.ts +530 -0
- package/dist/hono/routes/a2a-tasks.d.ts.map +1 -0
- package/dist/hono/routes/a2a-tasks.js +291 -0
- package/dist/hono/routes/a2a.cjs +36 -0
- package/dist/hono/routes/a2a.d.ts +4 -0
- package/dist/hono/routes/a2a.d.ts.map +1 -0
- package/dist/hono/routes/a2a.js +12 -0
- package/dist/hono/routes/agents.cjs +735 -0
- package/dist/hono/routes/agents.d.ts +650 -0
- package/dist/hono/routes/agents.d.ts.map +1 -0
- package/dist/hono/routes/agents.js +711 -0
- package/dist/hono/routes/approvals.cjs +125 -0
- package/dist/hono/routes/approvals.d.ts +89 -0
- package/dist/hono/routes/approvals.d.ts.map +1 -0
- package/dist/hono/routes/approvals.js +101 -0
- package/dist/hono/routes/greeting.cjs +60 -0
- package/dist/hono/routes/greeting.d.ts +19 -0
- package/dist/hono/routes/greeting.d.ts.map +1 -0
- package/dist/hono/routes/greeting.js +36 -0
- package/dist/hono/routes/health.cjs +45 -0
- package/dist/hono/routes/health.d.ts +17 -0
- package/dist/hono/routes/health.d.ts.map +1 -0
- package/dist/hono/routes/health.js +21 -0
- package/dist/hono/routes/llm.cjs +298 -0
- package/dist/hono/routes/llm.d.ts +294 -0
- package/dist/hono/routes/llm.d.ts.map +1 -0
- package/dist/hono/routes/llm.js +287 -0
- package/dist/hono/routes/mcp.cjs +356 -0
- package/dist/hono/routes/mcp.d.ts +246 -0
- package/dist/hono/routes/mcp.d.ts.map +1 -0
- package/dist/hono/routes/mcp.js +332 -0
- package/dist/hono/routes/memory.cjs +192 -0
- package/dist/hono/routes/memory.d.ts +146 -0
- package/dist/hono/routes/memory.d.ts.map +1 -0
- package/dist/hono/routes/memory.js +168 -0
- package/dist/hono/routes/messages.cjs +320 -0
- package/dist/hono/routes/messages.d.ts +163 -0
- package/dist/hono/routes/messages.d.ts.map +1 -0
- package/dist/hono/routes/messages.js +296 -0
- package/dist/hono/routes/prompts.cjs +228 -0
- package/dist/hono/routes/prompts.d.ts +150 -0
- package/dist/hono/routes/prompts.d.ts.map +1 -0
- package/dist/hono/routes/prompts.js +204 -0
- package/dist/hono/routes/resources.cjs +110 -0
- package/dist/hono/routes/resources.d.ts +76 -0
- package/dist/hono/routes/resources.d.ts.map +1 -0
- package/dist/hono/routes/resources.js +86 -0
- package/dist/hono/routes/search.cjs +109 -0
- package/dist/hono/routes/search.d.ts +137 -0
- package/dist/hono/routes/search.d.ts.map +1 -0
- package/dist/hono/routes/search.js +85 -0
- package/dist/hono/routes/sessions.cjs +366 -0
- package/dist/hono/routes/sessions.d.ts +229 -0
- package/dist/hono/routes/sessions.d.ts.map +1 -0
- package/dist/hono/routes/sessions.js +342 -0
- package/dist/hono/routes/webhooks.cjs +228 -0
- package/dist/hono/routes/webhooks.d.ts +127 -0
- package/dist/hono/routes/webhooks.d.ts.map +1 -0
- package/dist/hono/routes/webhooks.js +204 -0
- package/dist/hono/schemas/responses.cjs +276 -0
- package/dist/hono/schemas/responses.d.ts +1418 -0
- package/dist/hono/schemas/responses.d.ts.map +1 -0
- package/dist/hono/schemas/responses.js +227 -0
- package/dist/hono/types.cjs +16 -0
- package/dist/hono/types.d.ts +6 -0
- package/dist/hono/types.d.ts.map +1 -0
- package/dist/hono/types.js +0 -0
- package/dist/index.cjs +38 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/mcp/mcp-handler.cjs +145 -0
- package/dist/mcp/mcp-handler.d.ts +14 -0
- package/dist/mcp/mcp-handler.d.ts.map +1 -0
- package/dist/mcp/mcp-handler.js +118 -0
- package/package.json +59 -0
|
@@ -0,0 +1,735 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var agents_exports = {};
|
|
30
|
+
__export(agents_exports, {
|
|
31
|
+
createAgentsRouter: () => createAgentsRouter
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(agents_exports);
|
|
34
|
+
var import_zod_openapi = require("@hono/zod-openapi");
|
|
35
|
+
var import_core = require("@dexto/core");
|
|
36
|
+
var import_agent_management = require("@dexto/agent-management");
|
|
37
|
+
var import_agent_management2 = require("@dexto/agent-management");
|
|
38
|
+
var import_yaml = require("yaml");
|
|
39
|
+
var import_os = __toESM(require("os"), 1);
|
|
40
|
+
var import_path = __toESM(require("path"), 1);
|
|
41
|
+
var import_fs = require("fs");
|
|
42
|
+
var import_core2 = require("@dexto/core");
|
|
43
|
+
var import_responses = require("../schemas/responses.js");
|
|
44
|
+
const AgentIdentifierSchema = import_zod_openapi.z.object({
|
|
45
|
+
id: import_zod_openapi.z.string().min(1, "Agent id is required").describe('Unique agent identifier (e.g., "database-agent")'),
|
|
46
|
+
path: import_zod_openapi.z.string().optional().describe(
|
|
47
|
+
'Optional absolute file path for file-based agents (e.g., "/path/to/agent.yml")'
|
|
48
|
+
)
|
|
49
|
+
}).strict().describe("Agent identifier for switching agents by ID or file path");
|
|
50
|
+
const UninstallAgentSchema = import_zod_openapi.z.object({
|
|
51
|
+
id: import_zod_openapi.z.string().min(1, "Agent id is required").describe("Unique agent identifier to uninstall"),
|
|
52
|
+
force: import_zod_openapi.z.boolean().default(false).describe("Force uninstall even if agent is currently active")
|
|
53
|
+
}).strict().describe("Request body for uninstalling an agent");
|
|
54
|
+
const CustomAgentInstallSchema = import_zod_openapi.z.object({
|
|
55
|
+
id: import_zod_openapi.z.string().min(1, "Agent id is required").describe("Unique agent identifier"),
|
|
56
|
+
name: import_zod_openapi.z.string().optional().describe("Display name (defaults to derived from id)"),
|
|
57
|
+
sourcePath: import_zod_openapi.z.string().min(1).describe("Path to agent configuration file or directory"),
|
|
58
|
+
metadata: import_zod_openapi.z.object({
|
|
59
|
+
description: import_zod_openapi.z.string().min(1).describe("Human-readable description of the agent"),
|
|
60
|
+
author: import_zod_openapi.z.string().min(1).describe("Agent author or organization name"),
|
|
61
|
+
tags: import_zod_openapi.z.array(import_zod_openapi.z.string()).describe("Tags for categorizing the agent"),
|
|
62
|
+
main: import_zod_openapi.z.string().optional().describe("Main configuration file name within source directory")
|
|
63
|
+
}).strict().describe("Agent metadata including description, author, and tags"),
|
|
64
|
+
injectPreferences: import_zod_openapi.z.boolean().default(true).describe("Whether to inject user preferences into agent config")
|
|
65
|
+
}).strict().describe("Request body for installing a custom agent from file system").transform((value) => {
|
|
66
|
+
const displayName = value.name?.trim() || (0, import_agent_management2.deriveDisplayName)(value.id);
|
|
67
|
+
return {
|
|
68
|
+
id: value.id,
|
|
69
|
+
displayName,
|
|
70
|
+
sourcePath: value.sourcePath,
|
|
71
|
+
metadata: value.metadata,
|
|
72
|
+
injectPreferences: value.injectPreferences
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
const CustomAgentCreateSchema = import_zod_openapi.z.object({
|
|
76
|
+
// Registry metadata
|
|
77
|
+
id: import_zod_openapi.z.string().min(1, "Agent ID is required").regex(
|
|
78
|
+
/^[a-z0-9-]+$/,
|
|
79
|
+
"Agent ID must contain only lowercase letters, numbers, and hyphens"
|
|
80
|
+
).describe("Unique agent identifier"),
|
|
81
|
+
name: import_zod_openapi.z.string().min(1, "Agent name is required").describe("Display name for the agent"),
|
|
82
|
+
description: import_zod_openapi.z.string().min(1, "Description is required").describe("One-line description of the agent"),
|
|
83
|
+
author: import_zod_openapi.z.string().optional().describe("Author or organization"),
|
|
84
|
+
tags: import_zod_openapi.z.array(import_zod_openapi.z.string()).default([]).describe("Tags for discovery"),
|
|
85
|
+
// Full agent configuration
|
|
86
|
+
config: import_core.AgentConfigSchema.describe("Complete agent configuration")
|
|
87
|
+
}).strict().describe("Request body for creating a new custom agent with full configuration");
|
|
88
|
+
const AgentConfigValidateSchema = import_zod_openapi.z.object({
|
|
89
|
+
yaml: import_zod_openapi.z.string().describe("YAML agent configuration content to validate")
|
|
90
|
+
}).describe("Request body for validating agent configuration YAML");
|
|
91
|
+
const AgentConfigSaveSchema = import_zod_openapi.z.object({
|
|
92
|
+
yaml: import_zod_openapi.z.string().min(1, "YAML content is required").describe("YAML agent configuration content to save")
|
|
93
|
+
}).describe("Request body for saving agent configuration YAML");
|
|
94
|
+
const AgentInfoNullableSchema = import_zod_openapi.z.object({
|
|
95
|
+
id: import_zod_openapi.z.string().nullable().describe("Agent identifier (null if no active agent)"),
|
|
96
|
+
name: import_zod_openapi.z.string().nullable().describe("Agent display name (null if no active agent)")
|
|
97
|
+
}).strict().describe("Basic agent information (nullable)");
|
|
98
|
+
const ListAgentsResponseSchema = import_zod_openapi.z.object({
|
|
99
|
+
installed: import_zod_openapi.z.array(import_responses.AgentRegistryEntrySchema).describe("Agents installed locally"),
|
|
100
|
+
available: import_zod_openapi.z.array(import_responses.AgentRegistryEntrySchema).describe("Agents available from registry"),
|
|
101
|
+
current: AgentInfoNullableSchema.describe("Currently active agent")
|
|
102
|
+
}).strict().describe("List of all agents");
|
|
103
|
+
const InstallAgentResponseSchema = import_zod_openapi.z.object({
|
|
104
|
+
installed: import_zod_openapi.z.literal(true).describe("Indicates successful installation"),
|
|
105
|
+
id: import_zod_openapi.z.string().describe("Installed agent ID"),
|
|
106
|
+
name: import_zod_openapi.z.string().describe("Installed agent name"),
|
|
107
|
+
type: import_zod_openapi.z.enum(["builtin", "custom"]).describe("Type of agent installed")
|
|
108
|
+
}).strict().describe("Agent installation response");
|
|
109
|
+
const SwitchAgentResponseSchema = import_zod_openapi.z.object({
|
|
110
|
+
switched: import_zod_openapi.z.literal(true).describe("Indicates successful agent switch"),
|
|
111
|
+
id: import_zod_openapi.z.string().describe("New active agent ID"),
|
|
112
|
+
name: import_zod_openapi.z.string().describe("New active agent name")
|
|
113
|
+
}).strict().describe("Agent switch response");
|
|
114
|
+
const ValidateNameResponseSchema = import_zod_openapi.z.object({
|
|
115
|
+
valid: import_zod_openapi.z.boolean().describe("Whether the agent name is valid"),
|
|
116
|
+
conflict: import_zod_openapi.z.string().optional().describe("Type of conflict if name is invalid"),
|
|
117
|
+
message: import_zod_openapi.z.string().optional().describe("Validation message")
|
|
118
|
+
}).strict().describe("Agent name validation result");
|
|
119
|
+
const UninstallAgentResponseSchema = import_zod_openapi.z.object({
|
|
120
|
+
uninstalled: import_zod_openapi.z.literal(true).describe("Indicates successful uninstallation"),
|
|
121
|
+
id: import_zod_openapi.z.string().describe("Uninstalled agent ID")
|
|
122
|
+
}).strict().describe("Agent uninstallation response");
|
|
123
|
+
const AgentPathResponseSchema = import_zod_openapi.z.object({
|
|
124
|
+
path: import_zod_openapi.z.string().describe("Absolute path to agent configuration file"),
|
|
125
|
+
relativePath: import_zod_openapi.z.string().describe("Relative path or basename"),
|
|
126
|
+
name: import_zod_openapi.z.string().describe("Agent configuration filename without extension"),
|
|
127
|
+
isDefault: import_zod_openapi.z.boolean().describe("Whether this is the default agent")
|
|
128
|
+
}).strict().describe("Agent file path information");
|
|
129
|
+
const AgentConfigResponseSchema = import_zod_openapi.z.object({
|
|
130
|
+
yaml: import_zod_openapi.z.string().describe("Raw YAML configuration content"),
|
|
131
|
+
path: import_zod_openapi.z.string().describe("Absolute path to configuration file"),
|
|
132
|
+
relativePath: import_zod_openapi.z.string().describe("Relative path or basename"),
|
|
133
|
+
lastModified: import_zod_openapi.z.date().describe("Last modification timestamp"),
|
|
134
|
+
warnings: import_zod_openapi.z.array(import_zod_openapi.z.string()).describe("Configuration warnings")
|
|
135
|
+
}).strict().describe("Agent configuration content");
|
|
136
|
+
const SaveConfigResponseSchema = import_zod_openapi.z.object({
|
|
137
|
+
ok: import_zod_openapi.z.literal(true).describe("Indicates successful save"),
|
|
138
|
+
path: import_zod_openapi.z.string().describe("Path to saved configuration file"),
|
|
139
|
+
reloaded: import_zod_openapi.z.boolean().describe("Whether configuration was reloaded"),
|
|
140
|
+
restarted: import_zod_openapi.z.boolean().describe("Whether agent was restarted"),
|
|
141
|
+
changesApplied: import_zod_openapi.z.array(import_zod_openapi.z.string()).describe("List of changes that were applied"),
|
|
142
|
+
message: import_zod_openapi.z.string().describe("Success message")
|
|
143
|
+
}).strict().describe("Configuration save result");
|
|
144
|
+
function createAgentsRouter(getAgent, context) {
|
|
145
|
+
const app = new import_zod_openapi.OpenAPIHono();
|
|
146
|
+
const { switchAgentById, switchAgentByPath, resolveAgentInfo, getActiveAgentId } = context;
|
|
147
|
+
const listRoute = (0, import_zod_openapi.createRoute)({
|
|
148
|
+
method: "get",
|
|
149
|
+
path: "/agents",
|
|
150
|
+
summary: "List Agents",
|
|
151
|
+
description: "Retrieves all agents (installed, available, and current active agent)",
|
|
152
|
+
tags: ["agents"],
|
|
153
|
+
responses: {
|
|
154
|
+
200: {
|
|
155
|
+
description: "List all agents",
|
|
156
|
+
content: { "application/json": { schema: ListAgentsResponseSchema } }
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
const currentRoute = (0, import_zod_openapi.createRoute)({
|
|
161
|
+
method: "get",
|
|
162
|
+
path: "/agents/current",
|
|
163
|
+
summary: "Get Current Agent",
|
|
164
|
+
description: "Retrieves the currently active agent",
|
|
165
|
+
tags: ["agents"],
|
|
166
|
+
responses: {
|
|
167
|
+
200: {
|
|
168
|
+
description: "Current agent",
|
|
169
|
+
content: { "application/json": { schema: AgentInfoNullableSchema } }
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
const installRoute = (0, import_zod_openapi.createRoute)({
|
|
174
|
+
method: "post",
|
|
175
|
+
path: "/agents/install",
|
|
176
|
+
summary: "Install Agent",
|
|
177
|
+
description: "Installs an agent from the registry or from a custom source",
|
|
178
|
+
tags: ["agents"],
|
|
179
|
+
request: {
|
|
180
|
+
body: {
|
|
181
|
+
content: {
|
|
182
|
+
"application/json": {
|
|
183
|
+
schema: import_zod_openapi.z.union([CustomAgentInstallSchema, AgentIdentifierSchema])
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
responses: {
|
|
189
|
+
201: {
|
|
190
|
+
description: "Agent installed",
|
|
191
|
+
content: { "application/json": { schema: InstallAgentResponseSchema } }
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
const switchRoute = (0, import_zod_openapi.createRoute)({
|
|
196
|
+
method: "post",
|
|
197
|
+
path: "/agents/switch",
|
|
198
|
+
summary: "Switch Agent",
|
|
199
|
+
description: "Switches to a different agent by ID or file path",
|
|
200
|
+
tags: ["agents"],
|
|
201
|
+
request: {
|
|
202
|
+
body: {
|
|
203
|
+
content: {
|
|
204
|
+
"application/json": {
|
|
205
|
+
schema: AgentIdentifierSchema
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
responses: {
|
|
211
|
+
200: {
|
|
212
|
+
description: "Agent switched",
|
|
213
|
+
content: { "application/json": { schema: SwitchAgentResponseSchema } }
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
const validateNameRoute = (0, import_zod_openapi.createRoute)({
|
|
218
|
+
method: "post",
|
|
219
|
+
path: "/agents/validate-name",
|
|
220
|
+
summary: "Validate Agent Name",
|
|
221
|
+
description: "Checks if an agent ID conflicts with existing agents",
|
|
222
|
+
tags: ["agents"],
|
|
223
|
+
request: {
|
|
224
|
+
body: {
|
|
225
|
+
content: {
|
|
226
|
+
"application/json": {
|
|
227
|
+
schema: AgentIdentifierSchema
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
responses: {
|
|
233
|
+
200: {
|
|
234
|
+
description: "Name validation result",
|
|
235
|
+
content: { "application/json": { schema: ValidateNameResponseSchema } }
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
const uninstallRoute = (0, import_zod_openapi.createRoute)({
|
|
240
|
+
method: "post",
|
|
241
|
+
path: "/agents/uninstall",
|
|
242
|
+
summary: "Uninstall Agent",
|
|
243
|
+
description: "Removes an agent from the system. Custom agents are removed from registry; builtin agents can be reinstalled",
|
|
244
|
+
tags: ["agents"],
|
|
245
|
+
request: {
|
|
246
|
+
body: {
|
|
247
|
+
content: {
|
|
248
|
+
"application/json": {
|
|
249
|
+
schema: UninstallAgentSchema
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
},
|
|
254
|
+
responses: {
|
|
255
|
+
200: {
|
|
256
|
+
description: "Agent uninstalled",
|
|
257
|
+
content: { "application/json": { schema: UninstallAgentResponseSchema } }
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
const customCreateRoute = (0, import_zod_openapi.createRoute)({
|
|
262
|
+
method: "post",
|
|
263
|
+
path: "/agents/custom/create",
|
|
264
|
+
summary: "Create Custom Agent",
|
|
265
|
+
description: "Creates a new custom agent from scratch via the UI/API",
|
|
266
|
+
tags: ["agents"],
|
|
267
|
+
request: {
|
|
268
|
+
body: {
|
|
269
|
+
content: {
|
|
270
|
+
"application/json": {
|
|
271
|
+
schema: CustomAgentCreateSchema
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
responses: {
|
|
277
|
+
201: {
|
|
278
|
+
description: "Custom agent created",
|
|
279
|
+
content: {
|
|
280
|
+
"application/json": {
|
|
281
|
+
schema: import_zod_openapi.z.object({
|
|
282
|
+
created: import_zod_openapi.z.literal(true).describe("Creation success indicator"),
|
|
283
|
+
id: import_zod_openapi.z.string().describe("Agent identifier"),
|
|
284
|
+
name: import_zod_openapi.z.string().describe("Agent name")
|
|
285
|
+
}).strict()
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
const getPathRoute = (0, import_zod_openapi.createRoute)({
|
|
292
|
+
method: "get",
|
|
293
|
+
path: "/agent/path",
|
|
294
|
+
summary: "Get Agent File Path",
|
|
295
|
+
description: "Retrieves the file path of the currently active agent configuration",
|
|
296
|
+
tags: ["agent"],
|
|
297
|
+
responses: {
|
|
298
|
+
200: {
|
|
299
|
+
description: "Agent file path",
|
|
300
|
+
content: {
|
|
301
|
+
"application/json": {
|
|
302
|
+
schema: AgentPathResponseSchema
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
const getConfigRoute = (0, import_zod_openapi.createRoute)({
|
|
309
|
+
method: "get",
|
|
310
|
+
path: "/agent/config",
|
|
311
|
+
summary: "Get Agent Configuration",
|
|
312
|
+
description: "Retrieves the raw YAML configuration of the currently active agent",
|
|
313
|
+
tags: ["agent"],
|
|
314
|
+
responses: {
|
|
315
|
+
200: {
|
|
316
|
+
description: "Agent configuration",
|
|
317
|
+
content: {
|
|
318
|
+
"application/json": {
|
|
319
|
+
schema: AgentConfigResponseSchema
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
const validateConfigRoute = (0, import_zod_openapi.createRoute)({
|
|
326
|
+
method: "post",
|
|
327
|
+
path: "/agent/validate",
|
|
328
|
+
summary: "Validate Agent Configuration",
|
|
329
|
+
description: "Validates YAML agent configuration without saving it",
|
|
330
|
+
tags: ["agent"],
|
|
331
|
+
request: {
|
|
332
|
+
body: {
|
|
333
|
+
content: {
|
|
334
|
+
"application/json": {
|
|
335
|
+
schema: AgentConfigValidateSchema
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
},
|
|
340
|
+
responses: {
|
|
341
|
+
200: {
|
|
342
|
+
description: "Validation result",
|
|
343
|
+
content: {
|
|
344
|
+
"application/json": {
|
|
345
|
+
schema: import_zod_openapi.z.object({
|
|
346
|
+
valid: import_zod_openapi.z.boolean().describe("Whether configuration is valid"),
|
|
347
|
+
errors: import_zod_openapi.z.array(
|
|
348
|
+
import_zod_openapi.z.object({
|
|
349
|
+
line: import_zod_openapi.z.number().int().optional().describe("Line number"),
|
|
350
|
+
column: import_zod_openapi.z.number().int().optional().describe("Column number"),
|
|
351
|
+
path: import_zod_openapi.z.string().optional().describe("Configuration path"),
|
|
352
|
+
message: import_zod_openapi.z.string().describe("Error message"),
|
|
353
|
+
code: import_zod_openapi.z.string().describe("Error code")
|
|
354
|
+
}).passthrough()
|
|
355
|
+
).describe("Validation errors"),
|
|
356
|
+
warnings: import_zod_openapi.z.array(
|
|
357
|
+
import_zod_openapi.z.object({
|
|
358
|
+
path: import_zod_openapi.z.string().describe("Configuration path"),
|
|
359
|
+
message: import_zod_openapi.z.string().describe("Warning message"),
|
|
360
|
+
code: import_zod_openapi.z.string().describe("Warning code")
|
|
361
|
+
}).strict()
|
|
362
|
+
).describe("Configuration warnings")
|
|
363
|
+
}).strict()
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
const saveConfigRoute = (0, import_zod_openapi.createRoute)({
|
|
370
|
+
method: "post",
|
|
371
|
+
path: "/agent/config",
|
|
372
|
+
summary: "Save Agent Configuration",
|
|
373
|
+
description: "Saves and applies YAML agent configuration. Creates backup before saving",
|
|
374
|
+
tags: ["agent"],
|
|
375
|
+
request: {
|
|
376
|
+
body: {
|
|
377
|
+
content: {
|
|
378
|
+
"application/json": {
|
|
379
|
+
schema: AgentConfigSaveSchema
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
},
|
|
384
|
+
responses: {
|
|
385
|
+
200: {
|
|
386
|
+
description: "Configuration saved",
|
|
387
|
+
content: {
|
|
388
|
+
"application/json": {
|
|
389
|
+
schema: SaveConfigResponseSchema
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
const exportConfigRoute = (0, import_zod_openapi.createRoute)({
|
|
396
|
+
method: "get",
|
|
397
|
+
path: "/agent/config/export",
|
|
398
|
+
summary: "Export Agent Configuration",
|
|
399
|
+
description: "Exports the effective agent configuration with sensitive values redacted",
|
|
400
|
+
tags: ["agent"],
|
|
401
|
+
request: {
|
|
402
|
+
query: import_zod_openapi.z.object({
|
|
403
|
+
sessionId: import_zod_openapi.z.string().optional().describe("Session identifier to export session-specific configuration")
|
|
404
|
+
})
|
|
405
|
+
},
|
|
406
|
+
responses: {
|
|
407
|
+
200: {
|
|
408
|
+
description: "Exported configuration",
|
|
409
|
+
content: { "application/x-yaml": { schema: import_zod_openapi.z.string() } }
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
});
|
|
413
|
+
return app.openapi(listRoute, async (ctx) => {
|
|
414
|
+
const agents = await import_agent_management2.Dexto.listAgents();
|
|
415
|
+
const currentId = getActiveAgentId() ?? null;
|
|
416
|
+
return ctx.json({
|
|
417
|
+
installed: agents.installed,
|
|
418
|
+
available: agents.available,
|
|
419
|
+
current: currentId ? await resolveAgentInfo(currentId) : { id: null, name: null }
|
|
420
|
+
});
|
|
421
|
+
}).openapi(currentRoute, async (ctx) => {
|
|
422
|
+
const currentId = getActiveAgentId() ?? null;
|
|
423
|
+
if (!currentId) {
|
|
424
|
+
return ctx.json({ id: null, name: null });
|
|
425
|
+
}
|
|
426
|
+
return ctx.json(await resolveAgentInfo(currentId));
|
|
427
|
+
}).openapi(installRoute, async (ctx) => {
|
|
428
|
+
const body = ctx.req.valid("json");
|
|
429
|
+
if ("sourcePath" in body && "metadata" in body) {
|
|
430
|
+
const { id, displayName, sourcePath, metadata, injectPreferences } = body;
|
|
431
|
+
await import_agent_management2.Dexto.installCustomAgent(
|
|
432
|
+
id,
|
|
433
|
+
sourcePath,
|
|
434
|
+
{
|
|
435
|
+
name: displayName,
|
|
436
|
+
description: metadata.description,
|
|
437
|
+
author: metadata.author,
|
|
438
|
+
tags: metadata.tags,
|
|
439
|
+
...metadata.main ? { main: metadata.main } : {}
|
|
440
|
+
},
|
|
441
|
+
injectPreferences
|
|
442
|
+
);
|
|
443
|
+
return ctx.json(
|
|
444
|
+
{ installed: true, id, name: displayName, type: "custom" },
|
|
445
|
+
201
|
|
446
|
+
);
|
|
447
|
+
} else {
|
|
448
|
+
const { id } = body;
|
|
449
|
+
await import_agent_management2.Dexto.installAgent(id);
|
|
450
|
+
const agentInfo = await resolveAgentInfo(id);
|
|
451
|
+
return ctx.json(
|
|
452
|
+
{
|
|
453
|
+
installed: true,
|
|
454
|
+
...agentInfo,
|
|
455
|
+
type: "builtin"
|
|
456
|
+
},
|
|
457
|
+
201
|
|
458
|
+
);
|
|
459
|
+
}
|
|
460
|
+
}).openapi(switchRoute, async (ctx) => {
|
|
461
|
+
const { id, path: filePath } = ctx.req.valid("json");
|
|
462
|
+
const result = filePath ? await switchAgentByPath(filePath) : await switchAgentById(id);
|
|
463
|
+
return ctx.json({ switched: true, ...result });
|
|
464
|
+
}).openapi(validateNameRoute, async (ctx) => {
|
|
465
|
+
const { id } = ctx.req.valid("json");
|
|
466
|
+
const agents = await import_agent_management2.Dexto.listAgents();
|
|
467
|
+
const installedAgent = agents.installed.find((a) => a.id === id);
|
|
468
|
+
if (installedAgent) {
|
|
469
|
+
return ctx.json({
|
|
470
|
+
valid: false,
|
|
471
|
+
conflict: installedAgent.type,
|
|
472
|
+
message: `Agent id '${id}' already exists (${installedAgent.type})`
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
const availableAgent = agents.available.find((a) => a.id === id);
|
|
476
|
+
if (availableAgent) {
|
|
477
|
+
return ctx.json({
|
|
478
|
+
valid: false,
|
|
479
|
+
conflict: availableAgent.type,
|
|
480
|
+
message: `Agent id '${id}' conflicts with ${availableAgent.type} agent`
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
return ctx.json({ valid: true });
|
|
484
|
+
}).openapi(uninstallRoute, async (ctx) => {
|
|
485
|
+
const { id, force } = ctx.req.valid("json");
|
|
486
|
+
await import_agent_management2.Dexto.uninstallAgent(id, force);
|
|
487
|
+
return ctx.json({ uninstalled: true, id });
|
|
488
|
+
}).openapi(customCreateRoute, async (ctx) => {
|
|
489
|
+
const { id, name, description, author, tags, config } = ctx.req.valid("json");
|
|
490
|
+
const provider = config.llm.provider;
|
|
491
|
+
let agentConfig = config;
|
|
492
|
+
if (config.llm.apiKey && !config.llm.apiKey.startsWith("$")) {
|
|
493
|
+
const meta = await (0, import_agent_management.saveProviderApiKey)(provider, config.llm.apiKey, process.cwd());
|
|
494
|
+
const apiKeyRef = `$${meta.envVar}`;
|
|
495
|
+
import_core.logger.info(
|
|
496
|
+
`Stored API key securely for ${provider}, using env var: ${meta.envVar}`
|
|
497
|
+
);
|
|
498
|
+
agentConfig = {
|
|
499
|
+
...config,
|
|
500
|
+
llm: {
|
|
501
|
+
...config.llm,
|
|
502
|
+
apiKey: apiKeyRef
|
|
503
|
+
}
|
|
504
|
+
};
|
|
505
|
+
} else if (!config.llm.apiKey) {
|
|
506
|
+
agentConfig = {
|
|
507
|
+
...config,
|
|
508
|
+
llm: {
|
|
509
|
+
...config.llm,
|
|
510
|
+
apiKey: `$${(0, import_agent_management.getPrimaryApiKeyEnvVar)(provider)}`
|
|
511
|
+
}
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
const yamlContent = (0, import_yaml.stringify)(agentConfig);
|
|
515
|
+
import_core.logger.info(
|
|
516
|
+
`Creating agent config for ${id}: agentConfig=${(0, import_core.safeStringify)(agentConfig)}, yamlContent=${yamlContent}`
|
|
517
|
+
);
|
|
518
|
+
const tmpDir = import_os.default.tmpdir();
|
|
519
|
+
const tmpFile = import_path.default.join(tmpDir, `${id}-${Date.now()}.yml`);
|
|
520
|
+
await import_fs.promises.writeFile(tmpFile, yamlContent, "utf-8");
|
|
521
|
+
try {
|
|
522
|
+
await import_agent_management2.Dexto.installCustomAgent(
|
|
523
|
+
id,
|
|
524
|
+
tmpFile,
|
|
525
|
+
{
|
|
526
|
+
name,
|
|
527
|
+
description,
|
|
528
|
+
author: author || "Custom",
|
|
529
|
+
tags: tags || []
|
|
530
|
+
},
|
|
531
|
+
false
|
|
532
|
+
// Don't inject preferences
|
|
533
|
+
);
|
|
534
|
+
await import_fs.promises.unlink(tmpFile).catch(() => {
|
|
535
|
+
});
|
|
536
|
+
return ctx.json({ created: true, id, name }, 201);
|
|
537
|
+
} catch (installError) {
|
|
538
|
+
await import_fs.promises.unlink(tmpFile).catch(() => {
|
|
539
|
+
});
|
|
540
|
+
throw installError;
|
|
541
|
+
}
|
|
542
|
+
}).openapi(getPathRoute, (ctx) => {
|
|
543
|
+
const agent = getAgent();
|
|
544
|
+
const agentPath = agent.getAgentFilePath();
|
|
545
|
+
const relativePath = import_path.default.basename(agentPath);
|
|
546
|
+
const ext = import_path.default.extname(agentPath);
|
|
547
|
+
const name = import_path.default.basename(agentPath, ext);
|
|
548
|
+
return ctx.json({
|
|
549
|
+
path: agentPath,
|
|
550
|
+
relativePath,
|
|
551
|
+
name,
|
|
552
|
+
isDefault: name === "default-agent"
|
|
553
|
+
});
|
|
554
|
+
}).openapi(getConfigRoute, async (ctx) => {
|
|
555
|
+
const agent = getAgent();
|
|
556
|
+
const agentPath = agent.getAgentFilePath();
|
|
557
|
+
const yamlContent = await import_fs.promises.readFile(agentPath, "utf-8");
|
|
558
|
+
const stats = await import_fs.promises.stat(agentPath);
|
|
559
|
+
return ctx.json({
|
|
560
|
+
yaml: yamlContent,
|
|
561
|
+
path: agentPath,
|
|
562
|
+
relativePath: import_path.default.basename(agentPath),
|
|
563
|
+
lastModified: stats.mtime,
|
|
564
|
+
warnings: [
|
|
565
|
+
"Environment variables ($VAR) will be resolved at runtime",
|
|
566
|
+
"API keys should use environment variables"
|
|
567
|
+
]
|
|
568
|
+
});
|
|
569
|
+
}).openapi(validateConfigRoute, async (ctx) => {
|
|
570
|
+
const { yaml } = ctx.req.valid("json");
|
|
571
|
+
let parsed;
|
|
572
|
+
try {
|
|
573
|
+
parsed = (0, import_yaml.parse)(yaml);
|
|
574
|
+
} catch (parseError) {
|
|
575
|
+
return ctx.json({
|
|
576
|
+
valid: false,
|
|
577
|
+
errors: [
|
|
578
|
+
{
|
|
579
|
+
line: parseError.linePos?.[0]?.line || 1,
|
|
580
|
+
column: parseError.linePos?.[0]?.col || 1,
|
|
581
|
+
message: parseError.message,
|
|
582
|
+
code: "YAML_PARSE_ERROR"
|
|
583
|
+
}
|
|
584
|
+
],
|
|
585
|
+
warnings: []
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
589
|
+
return ctx.json({
|
|
590
|
+
valid: false,
|
|
591
|
+
errors: [
|
|
592
|
+
{
|
|
593
|
+
line: 1,
|
|
594
|
+
column: 1,
|
|
595
|
+
message: "Configuration must be a valid YAML object",
|
|
596
|
+
code: "INVALID_CONFIG_TYPE"
|
|
597
|
+
}
|
|
598
|
+
],
|
|
599
|
+
warnings: []
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
const enriched = (0, import_agent_management.enrichAgentConfig)(parsed, void 0);
|
|
603
|
+
const result = import_core.AgentConfigSchema.safeParse(enriched);
|
|
604
|
+
if (!result.success) {
|
|
605
|
+
const issues = (0, import_core.zodToIssues)(result.error);
|
|
606
|
+
const errors = issues.map((issue) => ({
|
|
607
|
+
path: issue.path?.join(".") ?? "root",
|
|
608
|
+
message: issue.message,
|
|
609
|
+
code: "SCHEMA_VALIDATION_ERROR"
|
|
610
|
+
}));
|
|
611
|
+
return ctx.json({
|
|
612
|
+
valid: false,
|
|
613
|
+
errors,
|
|
614
|
+
warnings: []
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
const warnings = [];
|
|
618
|
+
if (parsed.llm?.apiKey && !parsed.llm.apiKey.startsWith("$")) {
|
|
619
|
+
warnings.push({
|
|
620
|
+
path: "llm.apiKey",
|
|
621
|
+
message: "Consider using environment variable instead of plain text",
|
|
622
|
+
code: "SECURITY_WARNING"
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
return ctx.json({
|
|
626
|
+
valid: true,
|
|
627
|
+
errors: [],
|
|
628
|
+
warnings
|
|
629
|
+
});
|
|
630
|
+
}).openapi(saveConfigRoute, async (ctx) => {
|
|
631
|
+
const agent = getAgent();
|
|
632
|
+
const { yaml } = ctx.req.valid("json");
|
|
633
|
+
let parsed;
|
|
634
|
+
try {
|
|
635
|
+
parsed = (0, import_yaml.parse)(yaml);
|
|
636
|
+
} catch (parseError) {
|
|
637
|
+
throw new import_core2.DextoValidationError([
|
|
638
|
+
{
|
|
639
|
+
code: import_core2.AgentErrorCode.INVALID_CONFIG,
|
|
640
|
+
message: `Invalid YAML syntax: ${parseError.message}`,
|
|
641
|
+
scope: import_core2.ErrorScope.AGENT,
|
|
642
|
+
type: import_core2.ErrorType.USER,
|
|
643
|
+
severity: "error"
|
|
644
|
+
}
|
|
645
|
+
]);
|
|
646
|
+
}
|
|
647
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
648
|
+
throw new import_core2.DextoValidationError([
|
|
649
|
+
{
|
|
650
|
+
code: import_core2.AgentErrorCode.INVALID_CONFIG,
|
|
651
|
+
message: "Configuration must be a valid YAML object",
|
|
652
|
+
scope: import_core2.ErrorScope.AGENT,
|
|
653
|
+
type: import_core2.ErrorType.USER,
|
|
654
|
+
severity: "error"
|
|
655
|
+
}
|
|
656
|
+
]);
|
|
657
|
+
}
|
|
658
|
+
const agentPath = agent.getAgentFilePath();
|
|
659
|
+
const enriched = (0, import_agent_management.enrichAgentConfig)(parsed, agentPath);
|
|
660
|
+
const validationResult = import_core.AgentConfigSchema.safeParse(enriched);
|
|
661
|
+
if (!validationResult.success) {
|
|
662
|
+
throw new import_core2.DextoValidationError(
|
|
663
|
+
validationResult.error.errors.map((err) => ({
|
|
664
|
+
code: import_core2.AgentErrorCode.INVALID_CONFIG,
|
|
665
|
+
message: `${err.path.join(".")}: ${err.message}`,
|
|
666
|
+
scope: import_core2.ErrorScope.AGENT,
|
|
667
|
+
type: import_core2.ErrorType.USER,
|
|
668
|
+
severity: "error"
|
|
669
|
+
}))
|
|
670
|
+
);
|
|
671
|
+
}
|
|
672
|
+
const backupPath = `${agentPath}.backup`;
|
|
673
|
+
await import_fs.promises.copyFile(agentPath, backupPath);
|
|
674
|
+
try {
|
|
675
|
+
await import_fs.promises.writeFile(agentPath, yaml, "utf-8");
|
|
676
|
+
const newConfig = await (0, import_agent_management.reloadAgentConfigFromFile)(agentPath);
|
|
677
|
+
const enrichedConfig = (0, import_agent_management.enrichAgentConfig)(newConfig, agentPath);
|
|
678
|
+
const reloadResult = await agent.reload(enrichedConfig);
|
|
679
|
+
if (reloadResult.restarted) {
|
|
680
|
+
import_core.logger.info(
|
|
681
|
+
`Agent restarted to apply changes: ${reloadResult.changesApplied.join(", ")}`
|
|
682
|
+
);
|
|
683
|
+
} else if (reloadResult.changesApplied.length === 0) {
|
|
684
|
+
import_core.logger.info("Configuration saved (no changes detected)");
|
|
685
|
+
}
|
|
686
|
+
await import_fs.promises.unlink(backupPath).catch(() => {
|
|
687
|
+
});
|
|
688
|
+
import_core.logger.info(`Agent configuration saved and applied: ${agentPath}`);
|
|
689
|
+
return ctx.json({
|
|
690
|
+
ok: true,
|
|
691
|
+
path: agentPath,
|
|
692
|
+
reloaded: true,
|
|
693
|
+
restarted: reloadResult.restarted,
|
|
694
|
+
changesApplied: reloadResult.changesApplied,
|
|
695
|
+
message: reloadResult.restarted ? "Configuration saved and applied successfully (agent restarted)" : "Configuration saved successfully (no changes detected)"
|
|
696
|
+
});
|
|
697
|
+
} catch (error) {
|
|
698
|
+
await import_fs.promises.copyFile(backupPath, agentPath).catch(() => {
|
|
699
|
+
});
|
|
700
|
+
throw error;
|
|
701
|
+
}
|
|
702
|
+
}).openapi(exportConfigRoute, async (ctx) => {
|
|
703
|
+
const agent = getAgent();
|
|
704
|
+
const { sessionId } = ctx.req.valid("query");
|
|
705
|
+
const config = agent.getEffectiveConfig(sessionId);
|
|
706
|
+
const maskedConfig = {
|
|
707
|
+
...config,
|
|
708
|
+
llm: {
|
|
709
|
+
...config.llm,
|
|
710
|
+
apiKey: config.llm.apiKey ? "[REDACTED]" : void 0
|
|
711
|
+
},
|
|
712
|
+
mcpServers: config.mcpServers ? Object.fromEntries(
|
|
713
|
+
Object.entries(config.mcpServers).map(([name, serverConfig]) => [
|
|
714
|
+
name,
|
|
715
|
+
serverConfig.type === "stdio" && serverConfig.env ? {
|
|
716
|
+
...serverConfig,
|
|
717
|
+
env: Object.fromEntries(
|
|
718
|
+
Object.keys(serverConfig.env).map((key) => [
|
|
719
|
+
key,
|
|
720
|
+
"[REDACTED]"
|
|
721
|
+
])
|
|
722
|
+
)
|
|
723
|
+
} : serverConfig
|
|
724
|
+
])
|
|
725
|
+
) : void 0
|
|
726
|
+
};
|
|
727
|
+
const yamlStr = (0, import_yaml.stringify)(maskedConfig);
|
|
728
|
+
ctx.header("Content-Type", "application/x-yaml");
|
|
729
|
+
return ctx.body(yamlStr);
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
733
|
+
0 && (module.exports = {
|
|
734
|
+
createAgentsRouter
|
|
735
|
+
});
|