@dexto/agent-management 1.3.0 → 1.4.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 +153 -0
- package/dist/AgentFactory.d.ts +121 -0
- package/dist/AgentFactory.d.ts.map +1 -0
- package/dist/AgentFactory.js +133 -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 +22 -2
- package/dist/config/config-enrichment.d.ts +19 -4
- package/dist/config/config-enrichment.d.ts.map +1 -1
- package/dist/config/config-enrichment.js +21 -2
- 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/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 +40 -6
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +40 -5
- package/dist/installation.cjs +252 -0
- package/dist/installation.d.ts +74 -0
- package/dist/installation.d.ts.map +1 -0
- package/dist/installation.js +215 -0
- package/dist/models/custom-models.cjs +116 -0
- package/dist/models/custom-models.d.ts +51 -0
- package/dist/models/custom-models.d.ts.map +1 -0
- package/dist/models/custom-models.js +77 -0
- package/dist/registry/registry.cjs +21 -2
- package/dist/registry/registry.d.ts +5 -0
- package/dist/registry/registry.d.ts.map +1 -1
- package/dist/registry/registry.js +19 -1
- package/dist/registry/types.d.ts +9 -9
- package/dist/resolver.cjs +68 -29
- package/dist/resolver.d.ts +6 -3
- package/dist/resolver.d.ts.map +1 -1
- package/dist/resolver.js +69 -30
- 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,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var AgentFactory_exports = {};
|
|
20
|
+
__export(AgentFactory_exports, {
|
|
21
|
+
AgentFactory: () => AgentFactory
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(AgentFactory_exports);
|
|
24
|
+
var import_fs = require("fs");
|
|
25
|
+
var import_core = require("@dexto/core");
|
|
26
|
+
var import_path = require("./utils/path.js");
|
|
27
|
+
var import_types = require("./registry/types.js");
|
|
28
|
+
var import_registry = require("./registry/registry.js");
|
|
29
|
+
var import_config = require("./config/index.js");
|
|
30
|
+
var import_installation = require("./installation.js");
|
|
31
|
+
const AgentFactory = {
|
|
32
|
+
/**
|
|
33
|
+
* List all agents (installed and available from bundled registry)
|
|
34
|
+
* @param options - Optional fallback values for descriptions
|
|
35
|
+
*/
|
|
36
|
+
async listAgents(options) {
|
|
37
|
+
const bundledAgents = (0, import_registry.loadBundledRegistryAgents)();
|
|
38
|
+
const installed = await listInstalledAgents();
|
|
39
|
+
const descriptionFallback = options?.descriptionFallback ?? "";
|
|
40
|
+
const customAgentDescriptionFallback = options?.customAgentDescriptionFallback ?? descriptionFallback;
|
|
41
|
+
const installedAgents = installed.map((id) => {
|
|
42
|
+
const bundledEntry = bundledAgents[id];
|
|
43
|
+
return {
|
|
44
|
+
id,
|
|
45
|
+
name: bundledEntry?.name || (0, import_types.deriveDisplayName)(id),
|
|
46
|
+
description: bundledEntry?.description || (bundledEntry ? descriptionFallback : customAgentDescriptionFallback),
|
|
47
|
+
author: bundledEntry?.author || "",
|
|
48
|
+
tags: bundledEntry?.tags || [],
|
|
49
|
+
type: bundledEntry ? "builtin" : "custom"
|
|
50
|
+
};
|
|
51
|
+
});
|
|
52
|
+
const installedSet = new Set(installed);
|
|
53
|
+
const availableAgents = Object.entries(bundledAgents).filter(([id]) => !installedSet.has(id)).map(([id, entry]) => ({
|
|
54
|
+
id,
|
|
55
|
+
name: entry.name,
|
|
56
|
+
description: entry.description || descriptionFallback,
|
|
57
|
+
author: entry.author || "",
|
|
58
|
+
tags: entry.tags || [],
|
|
59
|
+
type: "builtin"
|
|
60
|
+
}));
|
|
61
|
+
return {
|
|
62
|
+
installed: installedAgents,
|
|
63
|
+
available: availableAgents
|
|
64
|
+
};
|
|
65
|
+
},
|
|
66
|
+
/**
|
|
67
|
+
* Install an agent from the bundled registry
|
|
68
|
+
*/
|
|
69
|
+
async installAgent(agentId, options) {
|
|
70
|
+
return (0, import_installation.installBundledAgent)(agentId, options);
|
|
71
|
+
},
|
|
72
|
+
/**
|
|
73
|
+
* Install a custom agent from local path
|
|
74
|
+
*/
|
|
75
|
+
async installCustomAgent(agentId, sourcePath, metadata, injectPreferences) {
|
|
76
|
+
const options = typeof injectPreferences === "boolean" ? { injectPreferences } : injectPreferences || {};
|
|
77
|
+
return (0, import_installation.installCustomAgent)(agentId, sourcePath, metadata, options);
|
|
78
|
+
},
|
|
79
|
+
/**
|
|
80
|
+
* Uninstall an agent
|
|
81
|
+
* @param agentId - Agent ID to uninstall
|
|
82
|
+
* @param _force - Deprecated: force parameter is kept for backward compatibility but has no effect
|
|
83
|
+
*/
|
|
84
|
+
async uninstallAgent(agentId, _force) {
|
|
85
|
+
return (0, import_installation.uninstallAgent)(agentId);
|
|
86
|
+
},
|
|
87
|
+
/**
|
|
88
|
+
* Create an agent from an inline configuration object
|
|
89
|
+
*
|
|
90
|
+
* Use this when you have a config from a database, API, or constructed programmatically
|
|
91
|
+
* and don't need a registry file. The agent is returned unstarted.
|
|
92
|
+
*
|
|
93
|
+
* @param config - Agent configuration object
|
|
94
|
+
* @param options - Optional creation options
|
|
95
|
+
* @returns Promise resolving to DextoAgent instance (not started)
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```typescript
|
|
99
|
+
* // Create from inline config
|
|
100
|
+
* const agent = await AgentFactory.createAgent({
|
|
101
|
+
* llm: {
|
|
102
|
+
* provider: 'openai',
|
|
103
|
+
* model: 'gpt-4o',
|
|
104
|
+
* apiKey: process.env.OPENAI_API_KEY
|
|
105
|
+
* },
|
|
106
|
+
* systemPrompt: 'You are a helpful assistant.'
|
|
107
|
+
* });
|
|
108
|
+
* await agent.start();
|
|
109
|
+
*
|
|
110
|
+
* // With custom agent ID (affects log/storage paths)
|
|
111
|
+
* const agent = await AgentFactory.createAgent(config, { agentId: 'my-custom-agent' });
|
|
112
|
+
*
|
|
113
|
+
* // From database
|
|
114
|
+
* const configFromDb = await db.getAgentConfig(userId);
|
|
115
|
+
* const agent = await AgentFactory.createAgent(configFromDb, { agentId: `user-${userId}` });
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
async createAgent(config, options) {
|
|
119
|
+
let configToEnrich = config;
|
|
120
|
+
if (options?.agentId) {
|
|
121
|
+
configToEnrich = {
|
|
122
|
+
...config,
|
|
123
|
+
agentCard: {
|
|
124
|
+
...config.agentCard || {},
|
|
125
|
+
name: options.agentId
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
const enrichedConfig = (0, import_config.enrichAgentConfig)(
|
|
130
|
+
configToEnrich,
|
|
131
|
+
void 0,
|
|
132
|
+
// No config path for inline configs
|
|
133
|
+
options?.isInteractiveCli ?? false
|
|
134
|
+
);
|
|
135
|
+
return new import_core.DextoAgent(enrichedConfig);
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
async function listInstalledAgents() {
|
|
139
|
+
const agentsDir = (0, import_path.getDextoGlobalPath)("agents");
|
|
140
|
+
try {
|
|
141
|
+
const entries = await import_fs.promises.readdir(agentsDir, { withFileTypes: true });
|
|
142
|
+
return entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
143
|
+
} catch (error) {
|
|
144
|
+
if (error.code === "ENOENT") {
|
|
145
|
+
return [];
|
|
146
|
+
}
|
|
147
|
+
throw error;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
151
|
+
0 && (module.exports = {
|
|
152
|
+
AgentFactory
|
|
153
|
+
});
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentFactory - Static convenience API for agent operations
|
|
3
|
+
*
|
|
4
|
+
* USE THIS WHEN: You need a simple, direct way to create agents or manage installations.
|
|
5
|
+
* No registry file required for agent creation.
|
|
6
|
+
*
|
|
7
|
+
* Key methods:
|
|
8
|
+
* - `AgentFactory.createAgent(config)` - Create agent from inline config (DB, API, dynamic)
|
|
9
|
+
* - `AgentFactory.installAgent(id)` - Install agent from bundled registry
|
|
10
|
+
* - `AgentFactory.uninstallAgent(id)` - Remove installed agent
|
|
11
|
+
* - `AgentFactory.listAgents()` - List installed/available agents
|
|
12
|
+
*
|
|
13
|
+
* Examples:
|
|
14
|
+
* - SaaS platforms with per-tenant configs from database
|
|
15
|
+
* - Dynamically constructed agent configurations
|
|
16
|
+
* - Quick scripts and demos
|
|
17
|
+
* - Single-agent applications
|
|
18
|
+
*
|
|
19
|
+
* FOR REGISTRY-BASED MULTI-AGENT SCENARIOS: Use `AgentManager` instead.
|
|
20
|
+
* This is better when you have a registry.json with multiple predefined agents
|
|
21
|
+
* and need discovery/selection capabilities.
|
|
22
|
+
*
|
|
23
|
+
* @see AgentManager for registry-based agent management
|
|
24
|
+
* @see https://docs.dexto.ai/api/sdk/agent-factory for full documentation
|
|
25
|
+
*/
|
|
26
|
+
import { DextoAgent, type AgentConfig } from '@dexto/core';
|
|
27
|
+
import { type InstallOptions } from './installation.js';
|
|
28
|
+
import type { AgentMetadata } from './AgentManager.js';
|
|
29
|
+
/**
|
|
30
|
+
* Options for listing agents
|
|
31
|
+
*/
|
|
32
|
+
export interface ListAgentsOptions {
|
|
33
|
+
/** Fallback description when not provided */
|
|
34
|
+
descriptionFallback?: string;
|
|
35
|
+
/** Fallback description for custom agents */
|
|
36
|
+
customAgentDescriptionFallback?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Options for creating an agent from inline config
|
|
40
|
+
*/
|
|
41
|
+
export interface CreateAgentOptions {
|
|
42
|
+
/** Override agent ID (otherwise derived from agentCard.name or defaults to 'inline-agent') */
|
|
43
|
+
agentId?: string;
|
|
44
|
+
/** Whether this is interactive CLI mode (affects logger defaults) */
|
|
45
|
+
isInteractiveCli?: boolean;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Static API for agent management operations
|
|
49
|
+
* Provides convenient methods for listing, installing, and uninstalling agents
|
|
50
|
+
*/
|
|
51
|
+
export declare const AgentFactory: {
|
|
52
|
+
/**
|
|
53
|
+
* List all agents (installed and available from bundled registry)
|
|
54
|
+
* @param options - Optional fallback values for descriptions
|
|
55
|
+
*/
|
|
56
|
+
listAgents(options?: ListAgentsOptions): Promise<{
|
|
57
|
+
installed: {
|
|
58
|
+
id: string;
|
|
59
|
+
name: string;
|
|
60
|
+
description: string;
|
|
61
|
+
author: string;
|
|
62
|
+
tags: string[];
|
|
63
|
+
type: "custom" | "builtin";
|
|
64
|
+
}[];
|
|
65
|
+
available: {
|
|
66
|
+
id: string;
|
|
67
|
+
name: any;
|
|
68
|
+
description: any;
|
|
69
|
+
author: any;
|
|
70
|
+
tags: any;
|
|
71
|
+
type: "builtin";
|
|
72
|
+
}[];
|
|
73
|
+
}>;
|
|
74
|
+
/**
|
|
75
|
+
* Install an agent from the bundled registry
|
|
76
|
+
*/
|
|
77
|
+
installAgent(agentId: string, options?: InstallOptions): Promise<string>;
|
|
78
|
+
/**
|
|
79
|
+
* Install a custom agent from local path
|
|
80
|
+
*/
|
|
81
|
+
installCustomAgent(agentId: string, sourcePath: string, metadata: Pick<AgentMetadata, "name" | "description" | "author" | "tags">, injectPreferences?: boolean | InstallOptions): Promise<string>;
|
|
82
|
+
/**
|
|
83
|
+
* Uninstall an agent
|
|
84
|
+
* @param agentId - Agent ID to uninstall
|
|
85
|
+
* @param _force - Deprecated: force parameter is kept for backward compatibility but has no effect
|
|
86
|
+
*/
|
|
87
|
+
uninstallAgent(agentId: string, _force?: boolean): Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* Create an agent from an inline configuration object
|
|
90
|
+
*
|
|
91
|
+
* Use this when you have a config from a database, API, or constructed programmatically
|
|
92
|
+
* and don't need a registry file. The agent is returned unstarted.
|
|
93
|
+
*
|
|
94
|
+
* @param config - Agent configuration object
|
|
95
|
+
* @param options - Optional creation options
|
|
96
|
+
* @returns Promise resolving to DextoAgent instance (not started)
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```typescript
|
|
100
|
+
* // Create from inline config
|
|
101
|
+
* const agent = await AgentFactory.createAgent({
|
|
102
|
+
* llm: {
|
|
103
|
+
* provider: 'openai',
|
|
104
|
+
* model: 'gpt-4o',
|
|
105
|
+
* apiKey: process.env.OPENAI_API_KEY
|
|
106
|
+
* },
|
|
107
|
+
* systemPrompt: 'You are a helpful assistant.'
|
|
108
|
+
* });
|
|
109
|
+
* await agent.start();
|
|
110
|
+
*
|
|
111
|
+
* // With custom agent ID (affects log/storage paths)
|
|
112
|
+
* const agent = await AgentFactory.createAgent(config, { agentId: 'my-custom-agent' });
|
|
113
|
+
*
|
|
114
|
+
* // From database
|
|
115
|
+
* const configFromDb = await db.getAgentConfig(userId);
|
|
116
|
+
* const agent = await AgentFactory.createAgent(configFromDb, { agentId: `user-${userId}` });
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
createAgent(config: AgentConfig, options?: CreateAgentOptions): Promise<DextoAgent>;
|
|
120
|
+
};
|
|
121
|
+
//# sourceMappingURL=AgentFactory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AgentFactory.d.ts","sourceRoot":"","sources":["../src/AgentFactory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAGH,OAAO,EAAE,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAK3D,OAAO,EAIH,KAAK,cAAc,EACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAC9B,6CAA6C;IAC7C,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,6CAA6C;IAC7C,8BAA8B,CAAC,EAAE,MAAM,CAAC;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAC/B,8FAA8F;IAC9F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY;IACrB;;;OAGG;yBACwB,iBAAiB;;;;;;;;;;;;;;;;;;IAyC5C;;OAEG;0BACyB,MAAM,YAAY,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC;IAI9E;;OAEG;gCAEU,MAAM,cACH,MAAM,YACR,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,aAAa,GAAG,QAAQ,GAAG,MAAM,CAAC,sBACrD,OAAO,GAAG,cAAc,GAC7C,OAAO,CAAC,MAAM,CAAC;IAUlB;;;;OAIG;4BAC2B,MAAM,WAAW,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAItE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;wBACuB,WAAW,YAAY,kBAAkB,GAAG,OAAO,CAAC,UAAU,CAAC;CAwB5F,CAAC"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { promises as fs } from "fs";
|
|
2
|
+
import { DextoAgent } from "@dexto/core";
|
|
3
|
+
import { getDextoGlobalPath } from "./utils/path.js";
|
|
4
|
+
import { deriveDisplayName } from "./registry/types.js";
|
|
5
|
+
import { loadBundledRegistryAgents } from "./registry/registry.js";
|
|
6
|
+
import { enrichAgentConfig } from "./config/index.js";
|
|
7
|
+
import {
|
|
8
|
+
installBundledAgent,
|
|
9
|
+
installCustomAgent,
|
|
10
|
+
uninstallAgent
|
|
11
|
+
} from "./installation.js";
|
|
12
|
+
const AgentFactory = {
|
|
13
|
+
/**
|
|
14
|
+
* List all agents (installed and available from bundled registry)
|
|
15
|
+
* @param options - Optional fallback values for descriptions
|
|
16
|
+
*/
|
|
17
|
+
async listAgents(options) {
|
|
18
|
+
const bundledAgents = loadBundledRegistryAgents();
|
|
19
|
+
const installed = await listInstalledAgents();
|
|
20
|
+
const descriptionFallback = options?.descriptionFallback ?? "";
|
|
21
|
+
const customAgentDescriptionFallback = options?.customAgentDescriptionFallback ?? descriptionFallback;
|
|
22
|
+
const installedAgents = installed.map((id) => {
|
|
23
|
+
const bundledEntry = bundledAgents[id];
|
|
24
|
+
return {
|
|
25
|
+
id,
|
|
26
|
+
name: bundledEntry?.name || deriveDisplayName(id),
|
|
27
|
+
description: bundledEntry?.description || (bundledEntry ? descriptionFallback : customAgentDescriptionFallback),
|
|
28
|
+
author: bundledEntry?.author || "",
|
|
29
|
+
tags: bundledEntry?.tags || [],
|
|
30
|
+
type: bundledEntry ? "builtin" : "custom"
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
const installedSet = new Set(installed);
|
|
34
|
+
const availableAgents = Object.entries(bundledAgents).filter(([id]) => !installedSet.has(id)).map(([id, entry]) => ({
|
|
35
|
+
id,
|
|
36
|
+
name: entry.name,
|
|
37
|
+
description: entry.description || descriptionFallback,
|
|
38
|
+
author: entry.author || "",
|
|
39
|
+
tags: entry.tags || [],
|
|
40
|
+
type: "builtin"
|
|
41
|
+
}));
|
|
42
|
+
return {
|
|
43
|
+
installed: installedAgents,
|
|
44
|
+
available: availableAgents
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
/**
|
|
48
|
+
* Install an agent from the bundled registry
|
|
49
|
+
*/
|
|
50
|
+
async installAgent(agentId, options) {
|
|
51
|
+
return installBundledAgent(agentId, options);
|
|
52
|
+
},
|
|
53
|
+
/**
|
|
54
|
+
* Install a custom agent from local path
|
|
55
|
+
*/
|
|
56
|
+
async installCustomAgent(agentId, sourcePath, metadata, injectPreferences) {
|
|
57
|
+
const options = typeof injectPreferences === "boolean" ? { injectPreferences } : injectPreferences || {};
|
|
58
|
+
return installCustomAgent(agentId, sourcePath, metadata, options);
|
|
59
|
+
},
|
|
60
|
+
/**
|
|
61
|
+
* Uninstall an agent
|
|
62
|
+
* @param agentId - Agent ID to uninstall
|
|
63
|
+
* @param _force - Deprecated: force parameter is kept for backward compatibility but has no effect
|
|
64
|
+
*/
|
|
65
|
+
async uninstallAgent(agentId, _force) {
|
|
66
|
+
return uninstallAgent(agentId);
|
|
67
|
+
},
|
|
68
|
+
/**
|
|
69
|
+
* Create an agent from an inline configuration object
|
|
70
|
+
*
|
|
71
|
+
* Use this when you have a config from a database, API, or constructed programmatically
|
|
72
|
+
* and don't need a registry file. The agent is returned unstarted.
|
|
73
|
+
*
|
|
74
|
+
* @param config - Agent configuration object
|
|
75
|
+
* @param options - Optional creation options
|
|
76
|
+
* @returns Promise resolving to DextoAgent instance (not started)
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* // Create from inline config
|
|
81
|
+
* const agent = await AgentFactory.createAgent({
|
|
82
|
+
* llm: {
|
|
83
|
+
* provider: 'openai',
|
|
84
|
+
* model: 'gpt-4o',
|
|
85
|
+
* apiKey: process.env.OPENAI_API_KEY
|
|
86
|
+
* },
|
|
87
|
+
* systemPrompt: 'You are a helpful assistant.'
|
|
88
|
+
* });
|
|
89
|
+
* await agent.start();
|
|
90
|
+
*
|
|
91
|
+
* // With custom agent ID (affects log/storage paths)
|
|
92
|
+
* const agent = await AgentFactory.createAgent(config, { agentId: 'my-custom-agent' });
|
|
93
|
+
*
|
|
94
|
+
* // From database
|
|
95
|
+
* const configFromDb = await db.getAgentConfig(userId);
|
|
96
|
+
* const agent = await AgentFactory.createAgent(configFromDb, { agentId: `user-${userId}` });
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
async createAgent(config, options) {
|
|
100
|
+
let configToEnrich = config;
|
|
101
|
+
if (options?.agentId) {
|
|
102
|
+
configToEnrich = {
|
|
103
|
+
...config,
|
|
104
|
+
agentCard: {
|
|
105
|
+
...config.agentCard || {},
|
|
106
|
+
name: options.agentId
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
const enrichedConfig = enrichAgentConfig(
|
|
111
|
+
configToEnrich,
|
|
112
|
+
void 0,
|
|
113
|
+
// No config path for inline configs
|
|
114
|
+
options?.isInteractiveCli ?? false
|
|
115
|
+
);
|
|
116
|
+
return new DextoAgent(enrichedConfig);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
async function listInstalledAgents() {
|
|
120
|
+
const agentsDir = getDextoGlobalPath("agents");
|
|
121
|
+
try {
|
|
122
|
+
const entries = await fs.readdir(agentsDir, { withFileTypes: true });
|
|
123
|
+
return entries.filter((e) => e.isDirectory()).map((e) => e.name);
|
|
124
|
+
} catch (error) {
|
|
125
|
+
if (error.code === "ENOENT") {
|
|
126
|
+
return [];
|
|
127
|
+
}
|
|
128
|
+
throw error;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
export {
|
|
132
|
+
AgentFactory
|
|
133
|
+
};
|
|
@@ -0,0 +1,226 @@
|
|
|
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 AgentManager_exports = {};
|
|
30
|
+
__export(AgentManager_exports, {
|
|
31
|
+
AgentManager: () => AgentManager
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(AgentManager_exports);
|
|
34
|
+
var import_fs = require("fs");
|
|
35
|
+
var import_path = __toESM(require("path"), 1);
|
|
36
|
+
var import_core = require("@dexto/core");
|
|
37
|
+
var import_config = require("./config/index.js");
|
|
38
|
+
var import_errors = require("./registry/errors.js");
|
|
39
|
+
var import_zod = require("zod");
|
|
40
|
+
const RegistrySchema = import_zod.z.object({
|
|
41
|
+
agents: import_zod.z.array(
|
|
42
|
+
import_zod.z.object({
|
|
43
|
+
id: import_zod.z.string(),
|
|
44
|
+
name: import_zod.z.string(),
|
|
45
|
+
description: import_zod.z.string(),
|
|
46
|
+
configPath: import_zod.z.string(),
|
|
47
|
+
author: import_zod.z.string().optional(),
|
|
48
|
+
tags: import_zod.z.array(import_zod.z.string()).optional()
|
|
49
|
+
}).strict()
|
|
50
|
+
)
|
|
51
|
+
}).strict();
|
|
52
|
+
class AgentManager {
|
|
53
|
+
registry = null;
|
|
54
|
+
registryPath;
|
|
55
|
+
basePath;
|
|
56
|
+
/**
|
|
57
|
+
* Create a new AgentManager
|
|
58
|
+
*
|
|
59
|
+
* @param registryPath Absolute or relative path to registry.json file
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```typescript
|
|
63
|
+
* // Project-local registry
|
|
64
|
+
* const manager = new AgentManager('./agents/registry.json');
|
|
65
|
+
*
|
|
66
|
+
* // Absolute path
|
|
67
|
+
* const manager = new AgentManager('/path/to/registry.json');
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
constructor(registryPath) {
|
|
71
|
+
this.registryPath = import_path.default.resolve(registryPath);
|
|
72
|
+
this.basePath = import_path.default.dirname(this.registryPath);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Load registry from file (lazy loaded, cached)
|
|
76
|
+
*
|
|
77
|
+
* Call this before using sync methods like `listAgents()` or `hasAgent()`.
|
|
78
|
+
* Alternatively, calling `loadAgent()` will automatically load the registry.
|
|
79
|
+
*
|
|
80
|
+
* @returns The loaded registry
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* const manager = new AgentManager('./registry.json');
|
|
85
|
+
* await manager.loadRegistry();
|
|
86
|
+
*
|
|
87
|
+
* // Now sync methods work
|
|
88
|
+
* const agents = manager.listAgents();
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
async loadRegistry() {
|
|
92
|
+
if (this.registry) {
|
|
93
|
+
return this.registry;
|
|
94
|
+
}
|
|
95
|
+
try {
|
|
96
|
+
const content = await import_fs.promises.readFile(this.registryPath, "utf-8");
|
|
97
|
+
const parsed = JSON.parse(content);
|
|
98
|
+
this.registry = RegistrySchema.parse(parsed);
|
|
99
|
+
import_core.logger.debug(
|
|
100
|
+
`Loaded registry from ${this.registryPath}: ${this.registry.agents.length} agents`
|
|
101
|
+
);
|
|
102
|
+
return this.registry;
|
|
103
|
+
} catch (error) {
|
|
104
|
+
if (error.code === "ENOENT") {
|
|
105
|
+
throw import_errors.RegistryError.registryNotFound(this.registryPath, "File does not exist");
|
|
106
|
+
}
|
|
107
|
+
if (error instanceof import_zod.ZodError) {
|
|
108
|
+
throw import_errors.RegistryError.registryParseError(
|
|
109
|
+
this.registryPath,
|
|
110
|
+
`Invalid registry schema: ${error.errors.map((e) => e.message).join(", ")}`
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
throw import_errors.RegistryError.registryParseError(
|
|
114
|
+
this.registryPath,
|
|
115
|
+
error instanceof Error ? error.message : String(error)
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* List all agents in the registry
|
|
121
|
+
*
|
|
122
|
+
* @returns Array of agent metadata
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```typescript
|
|
126
|
+
* const manager = new AgentManager('./registry.json');
|
|
127
|
+
* const agents = manager.listAgents();
|
|
128
|
+
* console.log(agents);
|
|
129
|
+
* // [
|
|
130
|
+
* // { id: 'coding-agent', name: 'Coding Assistant', description: '...', tags: ['coding'] },
|
|
131
|
+
* // { id: 'support-agent', name: 'Support Assistant', description: '...', tags: ['support'] }
|
|
132
|
+
* // ]
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
135
|
+
listAgents() {
|
|
136
|
+
if (!this.registry) {
|
|
137
|
+
throw import_errors.RegistryError.registryNotFound(
|
|
138
|
+
this.registryPath,
|
|
139
|
+
"Registry not loaded. Call loadRegistry() first or use async methods."
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
return this.registry.agents.map((entry) => ({
|
|
143
|
+
id: entry.id,
|
|
144
|
+
name: entry.name,
|
|
145
|
+
description: entry.description,
|
|
146
|
+
author: entry.author,
|
|
147
|
+
tags: entry.tags
|
|
148
|
+
}));
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Load a DextoAgent instance from registry
|
|
152
|
+
*
|
|
153
|
+
* @param id Agent ID from registry
|
|
154
|
+
* @returns Promise resolving to DextoAgent instance (not started)
|
|
155
|
+
*
|
|
156
|
+
* @throws {DextoRuntimeError} If agent not found or config loading fails
|
|
157
|
+
* @throws {DextoValidationError} If agent config validation fails
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* ```typescript
|
|
161
|
+
* const manager = new AgentManager('./registry.json');
|
|
162
|
+
* const agent = await manager.loadAgent('coding-agent');
|
|
163
|
+
* await agent.start();
|
|
164
|
+
*
|
|
165
|
+
* // Use the agent
|
|
166
|
+
* const session = await agent.createSession();
|
|
167
|
+
* const response = await agent.generate('Write a function', session.id);
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
async loadAgent(id) {
|
|
171
|
+
const registry = await this.loadRegistry();
|
|
172
|
+
const entry = registry.agents.find((a) => a.id === id);
|
|
173
|
+
if (!entry) {
|
|
174
|
+
const available = registry.agents.map((a) => a.id);
|
|
175
|
+
throw import_errors.RegistryError.agentNotFound(id, available);
|
|
176
|
+
}
|
|
177
|
+
const configPath = import_path.default.resolve(this.basePath, entry.configPath);
|
|
178
|
+
try {
|
|
179
|
+
const config = await (0, import_config.loadAgentConfig)(configPath);
|
|
180
|
+
const enrichedConfig = (0, import_config.enrichAgentConfig)(config, configPath);
|
|
181
|
+
import_core.logger.debug(`Loading agent: ${id} from ${configPath}`);
|
|
182
|
+
return new import_core.DextoAgent(enrichedConfig, configPath);
|
|
183
|
+
} catch (error) {
|
|
184
|
+
if (error instanceof import_zod.ZodError) {
|
|
185
|
+
const issues = (0, import_core.zodToIssues)(error, "error");
|
|
186
|
+
throw new import_core.DextoValidationError(issues);
|
|
187
|
+
}
|
|
188
|
+
if (error instanceof Error && error.name.startsWith("Dexto")) {
|
|
189
|
+
throw error;
|
|
190
|
+
}
|
|
191
|
+
throw import_errors.RegistryError.installationFailed(
|
|
192
|
+
id,
|
|
193
|
+
error instanceof Error ? error.message : String(error)
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Check if an agent exists in the registry
|
|
199
|
+
*
|
|
200
|
+
* @param id Agent ID to check
|
|
201
|
+
* @returns True if agent exists
|
|
202
|
+
*
|
|
203
|
+
* @example
|
|
204
|
+
* ```typescript
|
|
205
|
+
* const manager = new AgentManager('./registry.json');
|
|
206
|
+
* await manager.loadRegistry();
|
|
207
|
+
*
|
|
208
|
+
* if (manager.hasAgent('coding-agent')) {
|
|
209
|
+
* const agent = await manager.loadAgent('coding-agent');
|
|
210
|
+
* }
|
|
211
|
+
* ```
|
|
212
|
+
*/
|
|
213
|
+
hasAgent(id) {
|
|
214
|
+
if (!this.registry) {
|
|
215
|
+
throw import_errors.RegistryError.registryNotFound(
|
|
216
|
+
this.registryPath,
|
|
217
|
+
"Registry not loaded. Call loadRegistry() first or use async methods."
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
return this.registry.agents.some((a) => a.id === id);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
224
|
+
0 && (module.exports = {
|
|
225
|
+
AgentManager
|
|
226
|
+
});
|