@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.
Files changed (94) hide show
  1. package/dist/AgentFactory.cjs +152 -0
  2. package/dist/AgentFactory.d.ts +121 -0
  3. package/dist/AgentFactory.d.ts.map +1 -0
  4. package/dist/AgentFactory.js +132 -0
  5. package/dist/AgentManager.cjs +226 -0
  6. package/dist/AgentManager.d.ts +191 -0
  7. package/dist/AgentManager.d.ts.map +1 -0
  8. package/dist/AgentManager.js +192 -0
  9. package/dist/config/config-enrichment.cjs +23 -3
  10. package/dist/config/config-enrichment.d.ts +20 -5
  11. package/dist/config/config-enrichment.d.ts.map +1 -1
  12. package/dist/config/config-enrichment.js +22 -3
  13. package/dist/config/config-manager.cjs +340 -3
  14. package/dist/config/config-manager.d.ts +158 -7
  15. package/dist/config/config-manager.d.ts.map +1 -1
  16. package/dist/config/config-manager.js +325 -3
  17. package/dist/config/discover-prompts.cjs +103 -0
  18. package/dist/config/discover-prompts.d.ts +28 -0
  19. package/dist/config/discover-prompts.d.ts.map +1 -0
  20. package/dist/config/discover-prompts.js +73 -0
  21. package/dist/config/errors.cjs +2 -2
  22. package/dist/config/errors.js +2 -2
  23. package/dist/config/index.cjs +14 -2
  24. package/dist/config/index.d.ts +2 -2
  25. package/dist/config/index.d.ts.map +1 -1
  26. package/dist/config/index.js +21 -3
  27. package/dist/index.cjs +109 -6
  28. package/dist/index.d.ts +9 -6
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +111 -6
  31. package/dist/installation.cjs +239 -0
  32. package/dist/installation.d.ts +72 -0
  33. package/dist/installation.d.ts.map +1 -0
  34. package/dist/installation.js +202 -0
  35. package/dist/models/custom-models.cjs +157 -0
  36. package/dist/models/custom-models.d.ts +94 -0
  37. package/dist/models/custom-models.d.ts.map +1 -0
  38. package/dist/models/custom-models.js +117 -0
  39. package/dist/models/index.cjs +89 -0
  40. package/dist/models/index.d.ts +11 -0
  41. package/dist/models/index.d.ts.map +1 -0
  42. package/dist/models/index.js +68 -0
  43. package/dist/models/path-resolver.cjs +154 -0
  44. package/dist/models/path-resolver.d.ts +77 -0
  45. package/dist/models/path-resolver.d.ts.map +1 -0
  46. package/dist/models/path-resolver.js +108 -0
  47. package/dist/models/state-manager.cjs +220 -0
  48. package/dist/models/state-manager.d.ts +138 -0
  49. package/dist/models/state-manager.d.ts.map +1 -0
  50. package/dist/models/state-manager.js +184 -0
  51. package/dist/preferences/error-codes.cjs +2 -0
  52. package/dist/preferences/error-codes.d.ts +3 -1
  53. package/dist/preferences/error-codes.d.ts.map +1 -1
  54. package/dist/preferences/error-codes.js +2 -0
  55. package/dist/preferences/index.d.ts +1 -1
  56. package/dist/preferences/index.d.ts.map +1 -1
  57. package/dist/preferences/loader.cjs +32 -6
  58. package/dist/preferences/loader.d.ts +23 -4
  59. package/dist/preferences/loader.d.ts.map +1 -1
  60. package/dist/preferences/loader.js +32 -6
  61. package/dist/preferences/schemas.cjs +21 -3
  62. package/dist/preferences/schemas.d.ts +52 -24
  63. package/dist/preferences/schemas.d.ts.map +1 -1
  64. package/dist/preferences/schemas.js +28 -4
  65. package/dist/registry/registry.cjs +28 -45
  66. package/dist/registry/registry.d.ts +8 -6
  67. package/dist/registry/registry.d.ts.map +1 -1
  68. package/dist/registry/registry.js +26 -44
  69. package/dist/registry/types.d.ts +11 -13
  70. package/dist/registry/types.d.ts.map +1 -1
  71. package/dist/resolver.cjs +82 -43
  72. package/dist/resolver.d.ts +7 -5
  73. package/dist/resolver.d.ts.map +1 -1
  74. package/dist/resolver.js +83 -44
  75. package/dist/utils/api-key-resolver.cjs +19 -1
  76. package/dist/utils/api-key-resolver.d.ts.map +1 -1
  77. package/dist/utils/api-key-resolver.js +19 -1
  78. package/dist/utils/api-key-store.cjs +46 -0
  79. package/dist/utils/api-key-store.d.ts +27 -0
  80. package/dist/utils/api-key-store.d.ts.map +1 -1
  81. package/dist/utils/api-key-store.js +44 -0
  82. package/dist/utils/env-file.cjs +20 -68
  83. package/dist/utils/env-file.d.ts +2 -1
  84. package/dist/utils/env-file.d.ts.map +1 -1
  85. package/dist/utils/env-file.js +20 -68
  86. package/dist/writer.cjs +20 -2
  87. package/dist/writer.d.ts +1 -0
  88. package/dist/writer.d.ts.map +1 -1
  89. package/dist/writer.js +20 -2
  90. package/package.json +2 -2
  91. package/dist/AgentOrchestrator.cjs +0 -263
  92. package/dist/AgentOrchestrator.d.ts +0 -191
  93. package/dist/AgentOrchestrator.d.ts.map +0 -1
  94. 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 "default-agent";
53
+ return "coding-agent";
51
54
  }
52
- function enrichAgentConfig(config, configPath, isInteractiveCli = false) {
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: "info",
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) > 'default-agent'
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
- * Enriches agent configuration with per-agent file paths.
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 isInteractiveCli Whether this is interactive CLI mode (affects logger defaults) - defaults to false
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, isInteractiveCli?: boolean): AgentConfig;
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;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAyB9E;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAC7B,MAAM,EAAE,WAAW,EACnB,UAAU,CAAC,EAAE,MAAM,EACnB,gBAAgB,GAAE,OAAe,GAClC,WAAW,CAkFb"}
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 "default-agent";
18
+ return "coding-agent";
17
19
  }
18
- function enrichAgentConfig(config, configPath, isInteractiveCli = false) {
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: "info",
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
  };