@dexto/agent-management 1.3.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AgentFactory.cjs +152 -0
- package/dist/AgentFactory.d.ts +121 -0
- package/dist/AgentFactory.d.ts.map +1 -0
- package/dist/AgentFactory.js +132 -0
- package/dist/AgentManager.cjs +226 -0
- package/dist/AgentManager.d.ts +191 -0
- package/dist/AgentManager.d.ts.map +1 -0
- package/dist/AgentManager.js +192 -0
- package/dist/config/config-enrichment.cjs +23 -3
- package/dist/config/config-enrichment.d.ts +20 -5
- package/dist/config/config-enrichment.d.ts.map +1 -1
- package/dist/config/config-enrichment.js +22 -3
- package/dist/config/config-manager.cjs +340 -3
- package/dist/config/config-manager.d.ts +158 -7
- package/dist/config/config-manager.d.ts.map +1 -1
- package/dist/config/config-manager.js +325 -3
- package/dist/config/discover-prompts.cjs +103 -0
- package/dist/config/discover-prompts.d.ts +28 -0
- package/dist/config/discover-prompts.d.ts.map +1 -0
- package/dist/config/discover-prompts.js +73 -0
- package/dist/config/errors.cjs +2 -2
- package/dist/config/errors.js +2 -2
- package/dist/config/index.cjs +14 -2
- package/dist/config/index.d.ts +2 -2
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +21 -3
- package/dist/index.cjs +109 -6
- package/dist/index.d.ts +9 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +111 -6
- package/dist/installation.cjs +239 -0
- package/dist/installation.d.ts +72 -0
- package/dist/installation.d.ts.map +1 -0
- package/dist/installation.js +202 -0
- package/dist/models/custom-models.cjs +157 -0
- package/dist/models/custom-models.d.ts +94 -0
- package/dist/models/custom-models.d.ts.map +1 -0
- package/dist/models/custom-models.js +117 -0
- package/dist/models/index.cjs +89 -0
- package/dist/models/index.d.ts +11 -0
- package/dist/models/index.d.ts.map +1 -0
- package/dist/models/index.js +68 -0
- package/dist/models/path-resolver.cjs +154 -0
- package/dist/models/path-resolver.d.ts +77 -0
- package/dist/models/path-resolver.d.ts.map +1 -0
- package/dist/models/path-resolver.js +108 -0
- package/dist/models/state-manager.cjs +220 -0
- package/dist/models/state-manager.d.ts +138 -0
- package/dist/models/state-manager.d.ts.map +1 -0
- package/dist/models/state-manager.js +184 -0
- package/dist/preferences/error-codes.cjs +2 -0
- package/dist/preferences/error-codes.d.ts +3 -1
- package/dist/preferences/error-codes.d.ts.map +1 -1
- package/dist/preferences/error-codes.js +2 -0
- package/dist/preferences/index.d.ts +1 -1
- package/dist/preferences/index.d.ts.map +1 -1
- package/dist/preferences/loader.cjs +32 -6
- package/dist/preferences/loader.d.ts +23 -4
- package/dist/preferences/loader.d.ts.map +1 -1
- package/dist/preferences/loader.js +32 -6
- package/dist/preferences/schemas.cjs +21 -3
- package/dist/preferences/schemas.d.ts +52 -24
- package/dist/preferences/schemas.d.ts.map +1 -1
- package/dist/preferences/schemas.js +28 -4
- package/dist/registry/registry.cjs +28 -45
- package/dist/registry/registry.d.ts +8 -6
- package/dist/registry/registry.d.ts.map +1 -1
- package/dist/registry/registry.js +26 -44
- package/dist/registry/types.d.ts +11 -13
- package/dist/registry/types.d.ts.map +1 -1
- package/dist/resolver.cjs +82 -43
- package/dist/resolver.d.ts +7 -5
- package/dist/resolver.d.ts.map +1 -1
- package/dist/resolver.js +83 -44
- package/dist/utils/api-key-resolver.cjs +19 -1
- package/dist/utils/api-key-resolver.d.ts.map +1 -1
- package/dist/utils/api-key-resolver.js +19 -1
- package/dist/utils/api-key-store.cjs +46 -0
- package/dist/utils/api-key-store.d.ts +27 -0
- package/dist/utils/api-key-store.d.ts.map +1 -1
- package/dist/utils/api-key-store.js +44 -0
- package/dist/utils/env-file.cjs +20 -68
- package/dist/utils/env-file.d.ts +2 -1
- package/dist/utils/env-file.d.ts.map +1 -1
- package/dist/utils/env-file.js +20 -68
- package/dist/writer.cjs +20 -2
- package/dist/writer.d.ts +1 -0
- package/dist/writer.d.ts.map +1 -1
- package/dist/writer.js +20 -2
- package/package.json +2 -2
- package/dist/AgentOrchestrator.cjs +0 -263
- package/dist/AgentOrchestrator.d.ts +0 -191
- package/dist/AgentOrchestrator.d.ts.map +0 -1
- package/dist/AgentOrchestrator.js +0 -239
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentManager - Registry-based agent lifecycle management
|
|
3
|
+
*
|
|
4
|
+
* USE THIS WHEN: You have a registry.json file with multiple predefined agents
|
|
5
|
+
* and need discovery/selection capabilities (listAgents, hasAgent, createAgent by ID).
|
|
6
|
+
*
|
|
7
|
+
* Examples:
|
|
8
|
+
* - CLI tools with multiple agent options
|
|
9
|
+
* - Projects with several predefined agents users can choose from
|
|
10
|
+
*
|
|
11
|
+
* FOR INLINE/DYNAMIC CONFIGS: Use `AgentFactory.createAgent(config)` instead.
|
|
12
|
+
* This is better when configs come from a database, API, or are constructed
|
|
13
|
+
* programmatically without a registry file.
|
|
14
|
+
*
|
|
15
|
+
* @see AgentFactory.createAgent() for inline config creation
|
|
16
|
+
* @see https://docs.dexto.ai/api/sdk/agent-manager for full documentation
|
|
17
|
+
*/
|
|
18
|
+
import { DextoAgent } from '@dexto/core';
|
|
19
|
+
import { z } from 'zod';
|
|
20
|
+
/**
|
|
21
|
+
* Agent metadata - describes an agent in the registry
|
|
22
|
+
*/
|
|
23
|
+
export interface AgentMetadata {
|
|
24
|
+
id: string;
|
|
25
|
+
name: string;
|
|
26
|
+
description: string;
|
|
27
|
+
author?: string | undefined;
|
|
28
|
+
tags?: string[] | undefined;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Registry file schema
|
|
32
|
+
*/
|
|
33
|
+
declare const RegistrySchema: z.ZodObject<{
|
|
34
|
+
agents: z.ZodArray<z.ZodObject<{
|
|
35
|
+
id: z.ZodString;
|
|
36
|
+
name: z.ZodString;
|
|
37
|
+
description: z.ZodString;
|
|
38
|
+
configPath: z.ZodString;
|
|
39
|
+
author: z.ZodOptional<z.ZodString>;
|
|
40
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
41
|
+
}, "strict", z.ZodTypeAny, {
|
|
42
|
+
id: string;
|
|
43
|
+
name: string;
|
|
44
|
+
description: string;
|
|
45
|
+
configPath: string;
|
|
46
|
+
author?: string | undefined;
|
|
47
|
+
tags?: string[] | undefined;
|
|
48
|
+
}, {
|
|
49
|
+
id: string;
|
|
50
|
+
name: string;
|
|
51
|
+
description: string;
|
|
52
|
+
configPath: string;
|
|
53
|
+
author?: string | undefined;
|
|
54
|
+
tags?: string[] | undefined;
|
|
55
|
+
}>, "many">;
|
|
56
|
+
}, "strict", z.ZodTypeAny, {
|
|
57
|
+
agents: {
|
|
58
|
+
id: string;
|
|
59
|
+
name: string;
|
|
60
|
+
description: string;
|
|
61
|
+
configPath: string;
|
|
62
|
+
author?: string | undefined;
|
|
63
|
+
tags?: string[] | undefined;
|
|
64
|
+
}[];
|
|
65
|
+
}, {
|
|
66
|
+
agents: {
|
|
67
|
+
id: string;
|
|
68
|
+
name: string;
|
|
69
|
+
description: string;
|
|
70
|
+
configPath: string;
|
|
71
|
+
author?: string | undefined;
|
|
72
|
+
tags?: string[] | undefined;
|
|
73
|
+
}[];
|
|
74
|
+
}>;
|
|
75
|
+
type Registry = z.output<typeof RegistrySchema>;
|
|
76
|
+
/**
|
|
77
|
+
* AgentManager - Simple registry-based agent lifecycle management
|
|
78
|
+
*
|
|
79
|
+
* Provides a clean API for loading agent configurations from a registry file
|
|
80
|
+
* and creating agent instances. The registry is a JSON file that lists available
|
|
81
|
+
* agents and their config file paths.
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```typescript
|
|
85
|
+
* // Point to your registry
|
|
86
|
+
* const manager = new AgentManager('./agents/registry.json');
|
|
87
|
+
*
|
|
88
|
+
* // List available agents
|
|
89
|
+
* const agents = manager.listAgents();
|
|
90
|
+
* console.log(agents); // [{ id: 'coding-agent', name: '...', ... }]
|
|
91
|
+
*
|
|
92
|
+
* // Load an agent instance
|
|
93
|
+
* const agent = await manager.loadAgent('coding-agent');
|
|
94
|
+
* await agent.start();
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
export declare class AgentManager {
|
|
98
|
+
private registry;
|
|
99
|
+
private registryPath;
|
|
100
|
+
private basePath;
|
|
101
|
+
/**
|
|
102
|
+
* Create a new AgentManager
|
|
103
|
+
*
|
|
104
|
+
* @param registryPath Absolute or relative path to registry.json file
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```typescript
|
|
108
|
+
* // Project-local registry
|
|
109
|
+
* const manager = new AgentManager('./agents/registry.json');
|
|
110
|
+
*
|
|
111
|
+
* // Absolute path
|
|
112
|
+
* const manager = new AgentManager('/path/to/registry.json');
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
constructor(registryPath: string);
|
|
116
|
+
/**
|
|
117
|
+
* Load registry from file (lazy loaded, cached)
|
|
118
|
+
*
|
|
119
|
+
* Call this before using sync methods like `listAgents()` or `hasAgent()`.
|
|
120
|
+
* Alternatively, calling `loadAgent()` will automatically load the registry.
|
|
121
|
+
*
|
|
122
|
+
* @returns The loaded registry
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```typescript
|
|
126
|
+
* const manager = new AgentManager('./registry.json');
|
|
127
|
+
* await manager.loadRegistry();
|
|
128
|
+
*
|
|
129
|
+
* // Now sync methods work
|
|
130
|
+
* const agents = manager.listAgents();
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
loadRegistry(): Promise<Registry>;
|
|
134
|
+
/**
|
|
135
|
+
* List all agents in the registry
|
|
136
|
+
*
|
|
137
|
+
* @returns Array of agent metadata
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```typescript
|
|
141
|
+
* const manager = new AgentManager('./registry.json');
|
|
142
|
+
* const agents = manager.listAgents();
|
|
143
|
+
* console.log(agents);
|
|
144
|
+
* // [
|
|
145
|
+
* // { id: 'coding-agent', name: 'Coding Assistant', description: '...', tags: ['coding'] },
|
|
146
|
+
* // { id: 'support-agent', name: 'Support Assistant', description: '...', tags: ['support'] }
|
|
147
|
+
* // ]
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
listAgents(): AgentMetadata[];
|
|
151
|
+
/**
|
|
152
|
+
* Load a DextoAgent instance from registry
|
|
153
|
+
*
|
|
154
|
+
* @param id Agent ID from registry
|
|
155
|
+
* @returns Promise resolving to DextoAgent instance (not started)
|
|
156
|
+
*
|
|
157
|
+
* @throws {DextoRuntimeError} If agent not found or config loading fails
|
|
158
|
+
* @throws {DextoValidationError} If agent config validation fails
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ```typescript
|
|
162
|
+
* const manager = new AgentManager('./registry.json');
|
|
163
|
+
* const agent = await manager.loadAgent('coding-agent');
|
|
164
|
+
* await agent.start();
|
|
165
|
+
*
|
|
166
|
+
* // Use the agent
|
|
167
|
+
* const session = await agent.createSession();
|
|
168
|
+
* const response = await agent.generate('Write a function', session.id);
|
|
169
|
+
* ```
|
|
170
|
+
*/
|
|
171
|
+
loadAgent(id: string): Promise<DextoAgent>;
|
|
172
|
+
/**
|
|
173
|
+
* Check if an agent exists in the registry
|
|
174
|
+
*
|
|
175
|
+
* @param id Agent ID to check
|
|
176
|
+
* @returns True if agent exists
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* ```typescript
|
|
180
|
+
* const manager = new AgentManager('./registry.json');
|
|
181
|
+
* await manager.loadRegistry();
|
|
182
|
+
*
|
|
183
|
+
* if (manager.hasAgent('coding-agent')) {
|
|
184
|
+
* const agent = await manager.loadAgent('coding-agent');
|
|
185
|
+
* }
|
|
186
|
+
* ```
|
|
187
|
+
*/
|
|
188
|
+
hasAgent(id: string): boolean;
|
|
189
|
+
}
|
|
190
|
+
export {};
|
|
191
|
+
//# sourceMappingURL=AgentManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AgentManager.d.ts","sourceRoot":"","sources":["../src/AgentManager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,EAAU,UAAU,EAAqC,MAAM,aAAa,CAAC;AAGpF,OAAO,EAAE,CAAC,EAAY,MAAM,KAAK,CAAC;AAElC;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;CAC/B;AAED;;GAEG;AACH,QAAA,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAeP,CAAC;AAEd,KAAK,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC;AAEhD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,YAAY;IACrB,OAAO,CAAC,QAAQ,CAAyB;IACzC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAS;IAEzB;;;;;;;;;;;;;OAaG;gBACS,YAAY,EAAE,MAAM;IAKhC;;;;;;;;;;;;;;;;OAgBG;IACG,YAAY,IAAI,OAAO,CAAC,QAAQ,CAAC;IA8BvC;;;;;;;;;;;;;;;OAeG;IACH,UAAU,IAAI,aAAa,EAAE;IAiB7B;;;;;;;;;;;;;;;;;;;OAmBG;IACG,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAuChD;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;CAUhC"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { promises as fs } from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { logger, DextoAgent, DextoValidationError, zodToIssues } from "@dexto/core";
|
|
4
|
+
import { loadAgentConfig, enrichAgentConfig } from "./config/index.js";
|
|
5
|
+
import { RegistryError } from "./registry/errors.js";
|
|
6
|
+
import { z, ZodError } from "zod";
|
|
7
|
+
const RegistrySchema = z.object({
|
|
8
|
+
agents: z.array(
|
|
9
|
+
z.object({
|
|
10
|
+
id: z.string(),
|
|
11
|
+
name: z.string(),
|
|
12
|
+
description: z.string(),
|
|
13
|
+
configPath: z.string(),
|
|
14
|
+
author: z.string().optional(),
|
|
15
|
+
tags: z.array(z.string()).optional()
|
|
16
|
+
}).strict()
|
|
17
|
+
)
|
|
18
|
+
}).strict();
|
|
19
|
+
class AgentManager {
|
|
20
|
+
registry = null;
|
|
21
|
+
registryPath;
|
|
22
|
+
basePath;
|
|
23
|
+
/**
|
|
24
|
+
* Create a new AgentManager
|
|
25
|
+
*
|
|
26
|
+
* @param registryPath Absolute or relative path to registry.json file
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* // Project-local registry
|
|
31
|
+
* const manager = new AgentManager('./agents/registry.json');
|
|
32
|
+
*
|
|
33
|
+
* // Absolute path
|
|
34
|
+
* const manager = new AgentManager('/path/to/registry.json');
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
constructor(registryPath) {
|
|
38
|
+
this.registryPath = path.resolve(registryPath);
|
|
39
|
+
this.basePath = path.dirname(this.registryPath);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Load registry from file (lazy loaded, cached)
|
|
43
|
+
*
|
|
44
|
+
* Call this before using sync methods like `listAgents()` or `hasAgent()`.
|
|
45
|
+
* Alternatively, calling `loadAgent()` will automatically load the registry.
|
|
46
|
+
*
|
|
47
|
+
* @returns The loaded registry
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```typescript
|
|
51
|
+
* const manager = new AgentManager('./registry.json');
|
|
52
|
+
* await manager.loadRegistry();
|
|
53
|
+
*
|
|
54
|
+
* // Now sync methods work
|
|
55
|
+
* const agents = manager.listAgents();
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
async loadRegistry() {
|
|
59
|
+
if (this.registry) {
|
|
60
|
+
return this.registry;
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
const content = await fs.readFile(this.registryPath, "utf-8");
|
|
64
|
+
const parsed = JSON.parse(content);
|
|
65
|
+
this.registry = RegistrySchema.parse(parsed);
|
|
66
|
+
logger.debug(
|
|
67
|
+
`Loaded registry from ${this.registryPath}: ${this.registry.agents.length} agents`
|
|
68
|
+
);
|
|
69
|
+
return this.registry;
|
|
70
|
+
} catch (error) {
|
|
71
|
+
if (error.code === "ENOENT") {
|
|
72
|
+
throw RegistryError.registryNotFound(this.registryPath, "File does not exist");
|
|
73
|
+
}
|
|
74
|
+
if (error instanceof ZodError) {
|
|
75
|
+
throw RegistryError.registryParseError(
|
|
76
|
+
this.registryPath,
|
|
77
|
+
`Invalid registry schema: ${error.errors.map((e) => e.message).join(", ")}`
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
throw RegistryError.registryParseError(
|
|
81
|
+
this.registryPath,
|
|
82
|
+
error instanceof Error ? error.message : String(error)
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* List all agents in the registry
|
|
88
|
+
*
|
|
89
|
+
* @returns Array of agent metadata
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```typescript
|
|
93
|
+
* const manager = new AgentManager('./registry.json');
|
|
94
|
+
* const agents = manager.listAgents();
|
|
95
|
+
* console.log(agents);
|
|
96
|
+
* // [
|
|
97
|
+
* // { id: 'coding-agent', name: 'Coding Assistant', description: '...', tags: ['coding'] },
|
|
98
|
+
* // { id: 'support-agent', name: 'Support Assistant', description: '...', tags: ['support'] }
|
|
99
|
+
* // ]
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
listAgents() {
|
|
103
|
+
if (!this.registry) {
|
|
104
|
+
throw RegistryError.registryNotFound(
|
|
105
|
+
this.registryPath,
|
|
106
|
+
"Registry not loaded. Call loadRegistry() first or use async methods."
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
return this.registry.agents.map((entry) => ({
|
|
110
|
+
id: entry.id,
|
|
111
|
+
name: entry.name,
|
|
112
|
+
description: entry.description,
|
|
113
|
+
author: entry.author,
|
|
114
|
+
tags: entry.tags
|
|
115
|
+
}));
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Load a DextoAgent instance from registry
|
|
119
|
+
*
|
|
120
|
+
* @param id Agent ID from registry
|
|
121
|
+
* @returns Promise resolving to DextoAgent instance (not started)
|
|
122
|
+
*
|
|
123
|
+
* @throws {DextoRuntimeError} If agent not found or config loading fails
|
|
124
|
+
* @throws {DextoValidationError} If agent config validation fails
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```typescript
|
|
128
|
+
* const manager = new AgentManager('./registry.json');
|
|
129
|
+
* const agent = await manager.loadAgent('coding-agent');
|
|
130
|
+
* await agent.start();
|
|
131
|
+
*
|
|
132
|
+
* // Use the agent
|
|
133
|
+
* const session = await agent.createSession();
|
|
134
|
+
* const response = await agent.generate('Write a function', session.id);
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
async loadAgent(id) {
|
|
138
|
+
const registry = await this.loadRegistry();
|
|
139
|
+
const entry = registry.agents.find((a) => a.id === id);
|
|
140
|
+
if (!entry) {
|
|
141
|
+
const available = registry.agents.map((a) => a.id);
|
|
142
|
+
throw RegistryError.agentNotFound(id, available);
|
|
143
|
+
}
|
|
144
|
+
const configPath = path.resolve(this.basePath, entry.configPath);
|
|
145
|
+
try {
|
|
146
|
+
const config = await loadAgentConfig(configPath);
|
|
147
|
+
const enrichedConfig = enrichAgentConfig(config, configPath);
|
|
148
|
+
logger.debug(`Loading agent: ${id} from ${configPath}`);
|
|
149
|
+
return new DextoAgent(enrichedConfig, configPath);
|
|
150
|
+
} catch (error) {
|
|
151
|
+
if (error instanceof ZodError) {
|
|
152
|
+
const issues = zodToIssues(error, "error");
|
|
153
|
+
throw new DextoValidationError(issues);
|
|
154
|
+
}
|
|
155
|
+
if (error instanceof Error && error.name.startsWith("Dexto")) {
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
158
|
+
throw RegistryError.installationFailed(
|
|
159
|
+
id,
|
|
160
|
+
error instanceof Error ? error.message : String(error)
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Check if an agent exists in the registry
|
|
166
|
+
*
|
|
167
|
+
* @param id Agent ID to check
|
|
168
|
+
* @returns True if agent exists
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```typescript
|
|
172
|
+
* const manager = new AgentManager('./registry.json');
|
|
173
|
+
* await manager.loadRegistry();
|
|
174
|
+
*
|
|
175
|
+
* if (manager.hasAgent('coding-agent')) {
|
|
176
|
+
* const agent = await manager.loadAgent('coding-agent');
|
|
177
|
+
* }
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
180
|
+
hasAgent(id) {
|
|
181
|
+
if (!this.registry) {
|
|
182
|
+
throw RegistryError.registryNotFound(
|
|
183
|
+
this.registryPath,
|
|
184
|
+
"Registry not loaded. Call loadRegistry() first or use async methods."
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
return this.registry.agents.some((a) => a.id === id);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
export {
|
|
191
|
+
AgentManager
|
|
192
|
+
};
|
|
@@ -29,11 +29,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
29
29
|
var config_enrichment_exports = {};
|
|
30
30
|
__export(config_enrichment_exports, {
|
|
31
31
|
deriveAgentId: () => deriveAgentId,
|
|
32
|
+
discoverCommandPrompts: () => import_discover_prompts2.discoverCommandPrompts,
|
|
32
33
|
enrichAgentConfig: () => enrichAgentConfig
|
|
33
34
|
});
|
|
34
35
|
module.exports = __toCommonJS(config_enrichment_exports);
|
|
35
36
|
var import_path = require("../utils/path.js");
|
|
36
37
|
var path = __toESM(require("path"), 1);
|
|
38
|
+
var import_discover_prompts = require("./discover-prompts.js");
|
|
39
|
+
var import_discover_prompts2 = require("./discover-prompts.js");
|
|
37
40
|
function deriveAgentId(config, configPath) {
|
|
38
41
|
if (config.agentCard?.name) {
|
|
39
42
|
const sanitizedName = config.agentCard.name.toLowerCase().replace(/[^a-z0-9-_]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
@@ -47,9 +50,11 @@ function deriveAgentId(config, configPath) {
|
|
|
47
50
|
return basename;
|
|
48
51
|
}
|
|
49
52
|
}
|
|
50
|
-
return "
|
|
53
|
+
return "coding-agent";
|
|
51
54
|
}
|
|
52
|
-
function enrichAgentConfig(config, configPath,
|
|
55
|
+
function enrichAgentConfig(config, configPath, options = {}) {
|
|
56
|
+
const opts = typeof options === "boolean" ? { isInteractiveCli: options } : options;
|
|
57
|
+
const { isInteractiveCli = false, logLevel = "error" } = opts;
|
|
53
58
|
const agentId = deriveAgentId(config, configPath);
|
|
54
59
|
const logPath = (0, import_path.getDextoPath)("logs", `${agentId}.log`);
|
|
55
60
|
const dbPath = (0, import_path.getDextoPath)("database", `${agentId}.db`);
|
|
@@ -79,7 +84,7 @@ function enrichAgentConfig(config, configPath, isInteractiveCli = false) {
|
|
|
79
84
|
}
|
|
80
85
|
];
|
|
81
86
|
enriched.logger = {
|
|
82
|
-
level:
|
|
87
|
+
level: logLevel,
|
|
83
88
|
transports
|
|
84
89
|
};
|
|
85
90
|
} else {
|
|
@@ -108,10 +113,25 @@ function enrichAgentConfig(config, configPath, isInteractiveCli = false) {
|
|
|
108
113
|
};
|
|
109
114
|
}
|
|
110
115
|
}
|
|
116
|
+
const discoveredPrompts = (0, import_discover_prompts.discoverCommandPrompts)();
|
|
117
|
+
if (discoveredPrompts.length > 0) {
|
|
118
|
+
const existingPrompts = config.prompts ?? [];
|
|
119
|
+
const existingFilePaths = /* @__PURE__ */ new Set();
|
|
120
|
+
for (const prompt of existingPrompts) {
|
|
121
|
+
if (prompt.type === "file") {
|
|
122
|
+
existingFilePaths.add(path.resolve(prompt.file));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
const filteredDiscovered = discoveredPrompts.filter(
|
|
126
|
+
(p) => !existingFilePaths.has(path.resolve(p.file))
|
|
127
|
+
);
|
|
128
|
+
enriched.prompts = [...existingPrompts, ...filteredDiscovered];
|
|
129
|
+
}
|
|
111
130
|
return enriched;
|
|
112
131
|
}
|
|
113
132
|
// Annotate the CommonJS export names for ESM import in node:
|
|
114
133
|
0 && (module.exports = {
|
|
115
134
|
deriveAgentId,
|
|
135
|
+
discoverCommandPrompts,
|
|
116
136
|
enrichAgentConfig
|
|
117
137
|
});
|
|
@@ -5,27 +5,42 @@
|
|
|
5
5
|
* This layer runs before agent initialization and injects explicit paths
|
|
6
6
|
* into the configuration, eliminating the need for core services to resolve paths themselves.
|
|
7
7
|
*
|
|
8
|
+
* Also discovers command prompts from:
|
|
9
|
+
* - Local: <projectRoot>/commands/ (in dev mode or dexto-project context)
|
|
10
|
+
* - Global: ~/.dexto/commands/
|
|
11
|
+
*
|
|
8
12
|
* Core services now require explicit paths - this enrichment layer provides them.
|
|
9
13
|
*/
|
|
10
14
|
import type { AgentConfig } from '@dexto/core';
|
|
15
|
+
export { discoverCommandPrompts } from './discover-prompts.js';
|
|
11
16
|
/**
|
|
12
17
|
* Derives an agent ID from config or file path for per-agent isolation.
|
|
13
|
-
* Priority: agentCard.name > filename (without extension) > '
|
|
18
|
+
* Priority: agentCard.name > filename (without extension) > 'coding-agent'
|
|
14
19
|
*/
|
|
15
20
|
export declare function deriveAgentId(config: AgentConfig, configPath?: string): string;
|
|
16
21
|
/**
|
|
17
|
-
*
|
|
22
|
+
* Options for enriching agent configuration
|
|
23
|
+
*/
|
|
24
|
+
export interface EnrichAgentConfigOptions {
|
|
25
|
+
/** Whether this is interactive CLI mode (affects logger transports - file only vs console+file) */
|
|
26
|
+
isInteractiveCli?: boolean;
|
|
27
|
+
/** Override log level (defaults to 'error' for SDK, CLI/server can override to 'info') */
|
|
28
|
+
logLevel?: 'error' | 'warn' | 'info' | 'debug';
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Enriches agent configuration with per-agent file paths and discovered commands.
|
|
18
32
|
* This function is called before creating the DextoAgent instance.
|
|
19
33
|
*
|
|
20
34
|
* Enrichment adds:
|
|
21
35
|
* - File transport to logger config (per-agent log file)
|
|
22
36
|
* - Full paths to storage config (SQLite database, blob storage)
|
|
23
37
|
* - Backup path to filesystem config (per-agent backups)
|
|
38
|
+
* - Discovered command prompts from local/global commands/ directories
|
|
24
39
|
*
|
|
25
40
|
* @param config Agent configuration from YAML file + CLI overrides
|
|
26
41
|
* @param configPath Path to the agent config file (used for agent ID derivation)
|
|
27
|
-
* @param
|
|
28
|
-
* @returns Enriched configuration with explicit per-agent paths
|
|
42
|
+
* @param options Enrichment options (isInteractiveCli, logLevel)
|
|
43
|
+
* @returns Enriched configuration with explicit per-agent paths and discovered prompts
|
|
29
44
|
*/
|
|
30
|
-
export declare function enrichAgentConfig(config: AgentConfig, configPath?: string,
|
|
45
|
+
export declare function enrichAgentConfig(config: AgentConfig, configPath?: string, options?: EnrichAgentConfigOptions | boolean): AgentConfig;
|
|
31
46
|
//# sourceMappingURL=config-enrichment.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-enrichment.d.ts","sourceRoot":"","sources":["../../src/config/config-enrichment.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"config-enrichment.d.ts","sourceRoot":"","sources":["../../src/config/config-enrichment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAK/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/D;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAyB9E;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACrC,mGAAmG;IACnG,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,0FAA0F;IAC1F,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;CAClD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAC7B,MAAM,EAAE,WAAW,EACnB,UAAU,CAAC,EAAE,MAAM,EACnB,OAAO,GAAE,wBAAwB,GAAG,OAAY,GACjD,WAAW,CA+Gb"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { getDextoPath } from "../utils/path.js";
|
|
2
2
|
import * as path from "path";
|
|
3
|
+
import { discoverCommandPrompts } from "./discover-prompts.js";
|
|
4
|
+
import { discoverCommandPrompts as discoverCommandPrompts2 } from "./discover-prompts.js";
|
|
3
5
|
function deriveAgentId(config, configPath) {
|
|
4
6
|
if (config.agentCard?.name) {
|
|
5
7
|
const sanitizedName = config.agentCard.name.toLowerCase().replace(/[^a-z0-9-_]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
@@ -13,9 +15,11 @@ function deriveAgentId(config, configPath) {
|
|
|
13
15
|
return basename;
|
|
14
16
|
}
|
|
15
17
|
}
|
|
16
|
-
return "
|
|
18
|
+
return "coding-agent";
|
|
17
19
|
}
|
|
18
|
-
function enrichAgentConfig(config, configPath,
|
|
20
|
+
function enrichAgentConfig(config, configPath, options = {}) {
|
|
21
|
+
const opts = typeof options === "boolean" ? { isInteractiveCli: options } : options;
|
|
22
|
+
const { isInteractiveCli = false, logLevel = "error" } = opts;
|
|
19
23
|
const agentId = deriveAgentId(config, configPath);
|
|
20
24
|
const logPath = getDextoPath("logs", `${agentId}.log`);
|
|
21
25
|
const dbPath = getDextoPath("database", `${agentId}.db`);
|
|
@@ -45,7 +49,7 @@ function enrichAgentConfig(config, configPath, isInteractiveCli = false) {
|
|
|
45
49
|
}
|
|
46
50
|
];
|
|
47
51
|
enriched.logger = {
|
|
48
|
-
level:
|
|
52
|
+
level: logLevel,
|
|
49
53
|
transports
|
|
50
54
|
};
|
|
51
55
|
} else {
|
|
@@ -74,9 +78,24 @@ function enrichAgentConfig(config, configPath, isInteractiveCli = false) {
|
|
|
74
78
|
};
|
|
75
79
|
}
|
|
76
80
|
}
|
|
81
|
+
const discoveredPrompts = discoverCommandPrompts();
|
|
82
|
+
if (discoveredPrompts.length > 0) {
|
|
83
|
+
const existingPrompts = config.prompts ?? [];
|
|
84
|
+
const existingFilePaths = /* @__PURE__ */ new Set();
|
|
85
|
+
for (const prompt of existingPrompts) {
|
|
86
|
+
if (prompt.type === "file") {
|
|
87
|
+
existingFilePaths.add(path.resolve(prompt.file));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const filteredDiscovered = discoveredPrompts.filter(
|
|
91
|
+
(p) => !existingFilePaths.has(path.resolve(p.file))
|
|
92
|
+
);
|
|
93
|
+
enriched.prompts = [...existingPrompts, ...filteredDiscovered];
|
|
94
|
+
}
|
|
77
95
|
return enriched;
|
|
78
96
|
}
|
|
79
97
|
export {
|
|
80
98
|
deriveAgentId,
|
|
99
|
+
discoverCommandPrompts2 as discoverCommandPrompts,
|
|
81
100
|
enrichAgentConfig
|
|
82
101
|
};
|