@dexto/agent-config 1.6.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/LICENSE +44 -0
- package/README.md +46 -0
- package/dist/image/types.cjs +16 -0
- package/dist/image/types.d.ts +123 -0
- package/dist/image/types.d.ts.map +1 -0
- package/dist/image/types.js +0 -0
- package/dist/index.cjs +63 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/resolver/apply-image-defaults.cjs +102 -0
- package/dist/resolver/apply-image-defaults.d.ts +13 -0
- package/dist/resolver/apply-image-defaults.d.ts.map +1 -0
- package/dist/resolver/apply-image-defaults.js +78 -0
- package/dist/resolver/load-image.cjs +139 -0
- package/dist/resolver/load-image.d.ts +13 -0
- package/dist/resolver/load-image.d.ts.map +1 -0
- package/dist/resolver/load-image.js +114 -0
- package/dist/resolver/resolve-services-from-config.cjs +146 -0
- package/dist/resolver/resolve-services-from-config.d.ts +5 -0
- package/dist/resolver/resolve-services-from-config.d.ts.map +1 -0
- package/dist/resolver/resolve-services-from-config.js +122 -0
- package/dist/resolver/to-dexto-agent-options.cjs +51 -0
- package/dist/resolver/to-dexto-agent-options.d.ts +10 -0
- package/dist/resolver/to-dexto-agent-options.d.ts.map +1 -0
- package/dist/resolver/to-dexto-agent-options.js +27 -0
- package/dist/resolver/types.cjs +16 -0
- package/dist/resolver/types.d.ts +19 -0
- package/dist/resolver/types.d.ts.map +1 -0
- package/dist/resolver/types.js +0 -0
- package/dist/resolver/utils.cjs +35 -0
- package/dist/resolver/utils.d.ts +4 -0
- package/dist/resolver/utils.d.ts.map +1 -0
- package/dist/resolver/utils.js +10 -0
- package/dist/schemas/agent-config.cjs +117 -0
- package/dist/schemas/agent-config.d.ts +4910 -0
- package/dist/schemas/agent-config.d.ts.map +1 -0
- package/dist/schemas/agent-config.js +104 -0
- package/dist/schemas/compaction.cjs +64 -0
- package/dist/schemas/compaction.d.ts +77 -0
- package/dist/schemas/compaction.d.ts.map +1 -0
- package/dist/schemas/compaction.js +37 -0
- package/dist/schemas/hooks.cjs +37 -0
- package/dist/schemas/hooks.d.ts +36 -0
- package/dist/schemas/hooks.d.ts.map +1 -0
- package/dist/schemas/hooks.js +12 -0
- package/dist/utils/clean-null-values.cjs +52 -0
- package/dist/utils/clean-null-values.d.ts +8 -0
- package/dist/utils/clean-null-values.d.ts.map +1 -0
- package/dist/utils/clean-null-values.js +28 -0
- package/package.json +42 -0
|
@@ -0,0 +1,139 @@
|
|
|
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 load_image_exports = {};
|
|
20
|
+
__export(load_image_exports, {
|
|
21
|
+
loadImage: () => loadImage,
|
|
22
|
+
setImageImporter: () => setImageImporter
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(load_image_exports);
|
|
25
|
+
var import_utils = require("./utils.js");
|
|
26
|
+
let configuredImageImporter;
|
|
27
|
+
function setImageImporter(importer) {
|
|
28
|
+
configuredImageImporter = importer;
|
|
29
|
+
}
|
|
30
|
+
function assertFactoryMap(value, options) {
|
|
31
|
+
const { imageName, field } = options;
|
|
32
|
+
if (!(0, import_utils.isPlainObject)(value)) {
|
|
33
|
+
throw new Error(`Invalid image '${imageName}': expected '${field}' to be an object`);
|
|
34
|
+
}
|
|
35
|
+
for (const [key, factory] of Object.entries(value)) {
|
|
36
|
+
if (!(0, import_utils.isPlainObject)(factory)) {
|
|
37
|
+
throw new Error(
|
|
38
|
+
`Invalid image '${imageName}': expected '${field}.${key}' to be an object`
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
if (!(0, import_utils.isSchemaLike)(factory.configSchema)) {
|
|
42
|
+
throw new Error(
|
|
43
|
+
`Invalid image '${imageName}': expected '${field}.${key}.configSchema' to be a Zod schema`
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
if (typeof factory.create !== "function") {
|
|
47
|
+
throw new Error(
|
|
48
|
+
`Invalid image '${imageName}': expected '${field}.${key}.create' to be a function`
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function assertDextoImage(value, imageName) {
|
|
54
|
+
if (!(0, import_utils.isPlainObject)(value)) {
|
|
55
|
+
throw new Error(`Invalid image '${imageName}': expected an object export`);
|
|
56
|
+
}
|
|
57
|
+
const metadata = value.metadata;
|
|
58
|
+
if (!(0, import_utils.isPlainObject)(metadata)) {
|
|
59
|
+
throw new Error(`Invalid image '${imageName}': missing required 'metadata' object`);
|
|
60
|
+
}
|
|
61
|
+
if (typeof metadata.name !== "string" || metadata.name.length === 0) {
|
|
62
|
+
throw new Error(`Invalid image '${imageName}': metadata.name must be a non-empty string`);
|
|
63
|
+
}
|
|
64
|
+
if (typeof metadata.version !== "string" || metadata.version.length === 0) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
`Invalid image '${imageName}': metadata.version must be a non-empty string`
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
if (typeof metadata.description !== "string" || metadata.description.length === 0) {
|
|
70
|
+
throw new Error(
|
|
71
|
+
`Invalid image '${imageName}': metadata.description must be a non-empty string`
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
if (metadata.target !== void 0 && typeof metadata.target !== "string") {
|
|
75
|
+
throw new Error(
|
|
76
|
+
`Invalid image '${imageName}': metadata.target must be a string when provided`
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
if (metadata.constraints !== void 0) {
|
|
80
|
+
if (!Array.isArray(metadata.constraints) || metadata.constraints.some((c) => typeof c !== "string")) {
|
|
81
|
+
throw new Error(
|
|
82
|
+
`Invalid image '${imageName}': metadata.constraints must be string[] when provided`
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
assertFactoryMap(value.tools, { imageName, field: "tools" });
|
|
87
|
+
const storage = value.storage;
|
|
88
|
+
if (!(0, import_utils.isPlainObject)(storage)) {
|
|
89
|
+
throw new Error(`Invalid image '${imageName}': missing required 'storage' object`);
|
|
90
|
+
}
|
|
91
|
+
assertFactoryMap(storage.blob, { imageName, field: "storage.blob" });
|
|
92
|
+
assertFactoryMap(storage.database, { imageName, field: "storage.database" });
|
|
93
|
+
assertFactoryMap(storage.cache, { imageName, field: "storage.cache" });
|
|
94
|
+
assertFactoryMap(value.hooks, { imageName, field: "hooks" });
|
|
95
|
+
assertFactoryMap(value.compaction, { imageName, field: "compaction" });
|
|
96
|
+
const logger = value.logger;
|
|
97
|
+
if (!(0, import_utils.isPlainObject)(logger)) {
|
|
98
|
+
throw new Error(`Invalid image '${imageName}': missing required 'logger' factory`);
|
|
99
|
+
}
|
|
100
|
+
if (!(0, import_utils.isSchemaLike)(logger.configSchema)) {
|
|
101
|
+
throw new Error(`Invalid image '${imageName}': logger.configSchema must be a Zod schema`);
|
|
102
|
+
}
|
|
103
|
+
if (typeof logger.create !== "function") {
|
|
104
|
+
throw new Error(`Invalid image '${imageName}': logger.create must be a function`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function extractImageExport(module2) {
|
|
108
|
+
if (!(0, import_utils.isPlainObject)(module2)) {
|
|
109
|
+
return module2;
|
|
110
|
+
}
|
|
111
|
+
if ("default" in module2 && module2.default !== void 0) {
|
|
112
|
+
return module2.default;
|
|
113
|
+
}
|
|
114
|
+
if ("image" in module2 && module2.image !== void 0) {
|
|
115
|
+
return module2.image;
|
|
116
|
+
}
|
|
117
|
+
return module2;
|
|
118
|
+
}
|
|
119
|
+
async function loadImage(imageName) {
|
|
120
|
+
let module2;
|
|
121
|
+
try {
|
|
122
|
+
const importer = configuredImageImporter ?? ((specifier) => import(specifier));
|
|
123
|
+
module2 = await importer(imageName);
|
|
124
|
+
} catch (error) {
|
|
125
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
126
|
+
throw new Error(
|
|
127
|
+
`Failed to import image '${imageName}': ${message}
|
|
128
|
+
If you're running under pnpm (strict dependency boundaries), call setImageImporter((s) => import(s)) from the host entrypoint.`
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
const candidate = extractImageExport(module2);
|
|
132
|
+
assertDextoImage(candidate, imageName);
|
|
133
|
+
return candidate;
|
|
134
|
+
}
|
|
135
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
136
|
+
0 && (module.exports = {
|
|
137
|
+
loadImage,
|
|
138
|
+
setImageImporter
|
|
139
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { DextoImage } from '../image/types.js';
|
|
2
|
+
export type ImageImporter = (specifier: string) => Promise<unknown>;
|
|
3
|
+
/**
|
|
4
|
+
* Configure how images are dynamically imported.
|
|
5
|
+
*
|
|
6
|
+
* Why: In strict package manager layouts (pnpm), a helper inside `@dexto/agent-config`
|
|
7
|
+
* cannot reliably `import('@dexto/image-local')` because that image is not a dependency
|
|
8
|
+
* of agent-config. Hosts (CLI/server/apps) should call `setImageImporter((s) => import(s))`
|
|
9
|
+
* from their entrypoint so the import resolves relative to the host package.
|
|
10
|
+
*/
|
|
11
|
+
export declare function setImageImporter(importer: ImageImporter | undefined): void;
|
|
12
|
+
export declare function loadImage(imageName: string): Promise<DextoImage>;
|
|
13
|
+
//# sourceMappingURL=load-image.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-image.d.ts","sourceRoot":"","sources":["../../src/resolver/load-image.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGpD,MAAM,MAAM,aAAa,GAAG,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAIpE;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,aAAa,GAAG,SAAS,GAAG,IAAI,CAE1E;AA8GD,wBAAsB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAgBtE"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { isPlainObject, isSchemaLike } from "./utils.js";
|
|
2
|
+
let configuredImageImporter;
|
|
3
|
+
function setImageImporter(importer) {
|
|
4
|
+
configuredImageImporter = importer;
|
|
5
|
+
}
|
|
6
|
+
function assertFactoryMap(value, options) {
|
|
7
|
+
const { imageName, field } = options;
|
|
8
|
+
if (!isPlainObject(value)) {
|
|
9
|
+
throw new Error(`Invalid image '${imageName}': expected '${field}' to be an object`);
|
|
10
|
+
}
|
|
11
|
+
for (const [key, factory] of Object.entries(value)) {
|
|
12
|
+
if (!isPlainObject(factory)) {
|
|
13
|
+
throw new Error(
|
|
14
|
+
`Invalid image '${imageName}': expected '${field}.${key}' to be an object`
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
if (!isSchemaLike(factory.configSchema)) {
|
|
18
|
+
throw new Error(
|
|
19
|
+
`Invalid image '${imageName}': expected '${field}.${key}.configSchema' to be a Zod schema`
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
if (typeof factory.create !== "function") {
|
|
23
|
+
throw new Error(
|
|
24
|
+
`Invalid image '${imageName}': expected '${field}.${key}.create' to be a function`
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function assertDextoImage(value, imageName) {
|
|
30
|
+
if (!isPlainObject(value)) {
|
|
31
|
+
throw new Error(`Invalid image '${imageName}': expected an object export`);
|
|
32
|
+
}
|
|
33
|
+
const metadata = value.metadata;
|
|
34
|
+
if (!isPlainObject(metadata)) {
|
|
35
|
+
throw new Error(`Invalid image '${imageName}': missing required 'metadata' object`);
|
|
36
|
+
}
|
|
37
|
+
if (typeof metadata.name !== "string" || metadata.name.length === 0) {
|
|
38
|
+
throw new Error(`Invalid image '${imageName}': metadata.name must be a non-empty string`);
|
|
39
|
+
}
|
|
40
|
+
if (typeof metadata.version !== "string" || metadata.version.length === 0) {
|
|
41
|
+
throw new Error(
|
|
42
|
+
`Invalid image '${imageName}': metadata.version must be a non-empty string`
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
if (typeof metadata.description !== "string" || metadata.description.length === 0) {
|
|
46
|
+
throw new Error(
|
|
47
|
+
`Invalid image '${imageName}': metadata.description must be a non-empty string`
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
if (metadata.target !== void 0 && typeof metadata.target !== "string") {
|
|
51
|
+
throw new Error(
|
|
52
|
+
`Invalid image '${imageName}': metadata.target must be a string when provided`
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
if (metadata.constraints !== void 0) {
|
|
56
|
+
if (!Array.isArray(metadata.constraints) || metadata.constraints.some((c) => typeof c !== "string")) {
|
|
57
|
+
throw new Error(
|
|
58
|
+
`Invalid image '${imageName}': metadata.constraints must be string[] when provided`
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
assertFactoryMap(value.tools, { imageName, field: "tools" });
|
|
63
|
+
const storage = value.storage;
|
|
64
|
+
if (!isPlainObject(storage)) {
|
|
65
|
+
throw new Error(`Invalid image '${imageName}': missing required 'storage' object`);
|
|
66
|
+
}
|
|
67
|
+
assertFactoryMap(storage.blob, { imageName, field: "storage.blob" });
|
|
68
|
+
assertFactoryMap(storage.database, { imageName, field: "storage.database" });
|
|
69
|
+
assertFactoryMap(storage.cache, { imageName, field: "storage.cache" });
|
|
70
|
+
assertFactoryMap(value.hooks, { imageName, field: "hooks" });
|
|
71
|
+
assertFactoryMap(value.compaction, { imageName, field: "compaction" });
|
|
72
|
+
const logger = value.logger;
|
|
73
|
+
if (!isPlainObject(logger)) {
|
|
74
|
+
throw new Error(`Invalid image '${imageName}': missing required 'logger' factory`);
|
|
75
|
+
}
|
|
76
|
+
if (!isSchemaLike(logger.configSchema)) {
|
|
77
|
+
throw new Error(`Invalid image '${imageName}': logger.configSchema must be a Zod schema`);
|
|
78
|
+
}
|
|
79
|
+
if (typeof logger.create !== "function") {
|
|
80
|
+
throw new Error(`Invalid image '${imageName}': logger.create must be a function`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function extractImageExport(module) {
|
|
84
|
+
if (!isPlainObject(module)) {
|
|
85
|
+
return module;
|
|
86
|
+
}
|
|
87
|
+
if ("default" in module && module.default !== void 0) {
|
|
88
|
+
return module.default;
|
|
89
|
+
}
|
|
90
|
+
if ("image" in module && module.image !== void 0) {
|
|
91
|
+
return module.image;
|
|
92
|
+
}
|
|
93
|
+
return module;
|
|
94
|
+
}
|
|
95
|
+
async function loadImage(imageName) {
|
|
96
|
+
let module;
|
|
97
|
+
try {
|
|
98
|
+
const importer = configuredImageImporter ?? ((specifier) => import(specifier));
|
|
99
|
+
module = await importer(imageName);
|
|
100
|
+
} catch (error) {
|
|
101
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
102
|
+
throw new Error(
|
|
103
|
+
`Failed to import image '${imageName}': ${message}
|
|
104
|
+
If you're running under pnpm (strict dependency boundaries), call setImageImporter((s) => import(s)) from the host entrypoint.`
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
const candidate = extractImageExport(module);
|
|
108
|
+
assertDextoImage(candidate, imageName);
|
|
109
|
+
return candidate;
|
|
110
|
+
}
|
|
111
|
+
export {
|
|
112
|
+
loadImage,
|
|
113
|
+
setImageImporter
|
|
114
|
+
};
|
|
@@ -0,0 +1,146 @@
|
|
|
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 resolve_services_from_config_exports = {};
|
|
20
|
+
__export(resolve_services_from_config_exports, {
|
|
21
|
+
resolveServicesFromConfig: () => resolveServicesFromConfig
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(resolve_services_from_config_exports);
|
|
24
|
+
var import_utils = require("./utils.js");
|
|
25
|
+
const MCP_TOOL_PREFIX = "mcp--";
|
|
26
|
+
function stripEnabled(entry) {
|
|
27
|
+
const obj = entry;
|
|
28
|
+
if (!Object.prototype.hasOwnProperty.call(obj, "enabled")) {
|
|
29
|
+
return obj;
|
|
30
|
+
}
|
|
31
|
+
const { enabled: _enabled, ...rest } = obj;
|
|
32
|
+
return rest;
|
|
33
|
+
}
|
|
34
|
+
function resolveByType(options) {
|
|
35
|
+
const { kind, type, factories, imageName } = options;
|
|
36
|
+
const factory = factories[type];
|
|
37
|
+
if (!factory) {
|
|
38
|
+
const available = Object.keys(factories).sort();
|
|
39
|
+
throw new Error(
|
|
40
|
+
`Unknown ${kind} type '${type}'. Available types from image '${imageName}': ${available.join(", ")}`
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
return factory;
|
|
44
|
+
}
|
|
45
|
+
async function resolveServicesFromConfig(config, image) {
|
|
46
|
+
const imageName = image.metadata.name;
|
|
47
|
+
const loggerFactoryInput = {
|
|
48
|
+
agentId: config.agentId,
|
|
49
|
+
config: config.logger
|
|
50
|
+
};
|
|
51
|
+
const loggerConfig = image.logger.configSchema.parse(loggerFactoryInput);
|
|
52
|
+
const logger = image.logger.create(loggerConfig);
|
|
53
|
+
const blobFactory = resolveByType({
|
|
54
|
+
kind: "blob storage",
|
|
55
|
+
type: config.storage.blob.type,
|
|
56
|
+
factories: image.storage.blob,
|
|
57
|
+
imageName
|
|
58
|
+
});
|
|
59
|
+
const databaseFactory = resolveByType({
|
|
60
|
+
kind: "database",
|
|
61
|
+
type: config.storage.database.type,
|
|
62
|
+
factories: image.storage.database,
|
|
63
|
+
imageName
|
|
64
|
+
});
|
|
65
|
+
const cacheFactory = resolveByType({
|
|
66
|
+
kind: "cache",
|
|
67
|
+
type: config.storage.cache.type,
|
|
68
|
+
factories: image.storage.cache,
|
|
69
|
+
imageName
|
|
70
|
+
});
|
|
71
|
+
const blobConfig = blobFactory.configSchema.parse(config.storage.blob);
|
|
72
|
+
const databaseConfig = databaseFactory.configSchema.parse(config.storage.database);
|
|
73
|
+
const cacheConfig = cacheFactory.configSchema.parse(config.storage.cache);
|
|
74
|
+
const storage = {
|
|
75
|
+
blob: await blobFactory.create(blobConfig, logger),
|
|
76
|
+
database: await databaseFactory.create(databaseConfig, logger),
|
|
77
|
+
cache: await cacheFactory.create(cacheConfig, logger)
|
|
78
|
+
};
|
|
79
|
+
const toolEntries = config.tools ?? image.defaults?.tools ?? [];
|
|
80
|
+
const tools = [];
|
|
81
|
+
const toolIds = /* @__PURE__ */ new Set();
|
|
82
|
+
for (const entry of toolEntries) {
|
|
83
|
+
if (entry.enabled === false) {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const factory = resolveByType({
|
|
87
|
+
kind: "tool",
|
|
88
|
+
type: entry.type,
|
|
89
|
+
factories: image.tools,
|
|
90
|
+
imageName
|
|
91
|
+
});
|
|
92
|
+
const validatedConfig = factory.configSchema.parse(stripEnabled(entry));
|
|
93
|
+
for (const tool of factory.create(validatedConfig)) {
|
|
94
|
+
if (tool.id.startsWith(MCP_TOOL_PREFIX)) {
|
|
95
|
+
throw new Error(
|
|
96
|
+
`Invalid local tool id '${tool.id}': '${MCP_TOOL_PREFIX}' prefix is reserved for MCP tools.`
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
if (toolIds.has(tool.id)) {
|
|
100
|
+
logger.warn(`Tool id conflict for '${tool.id}'. Skipping duplicate tool.`);
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
toolIds.add(tool.id);
|
|
104
|
+
tools.push(tool);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const hookEntries = config.hooks ?? image.defaults?.hooks ?? [];
|
|
108
|
+
const hooks = [];
|
|
109
|
+
for (const entry of hookEntries) {
|
|
110
|
+
if (entry.enabled === false) {
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
const factory = resolveByType({
|
|
114
|
+
kind: "hook",
|
|
115
|
+
type: entry.type,
|
|
116
|
+
factories: image.hooks,
|
|
117
|
+
imageName
|
|
118
|
+
});
|
|
119
|
+
const parsedConfig = factory.configSchema.parse(stripEnabled(entry));
|
|
120
|
+
const hook = factory.create(parsedConfig);
|
|
121
|
+
if (hook.initialize) {
|
|
122
|
+
if (!(0, import_utils.isPlainObject)(parsedConfig)) {
|
|
123
|
+
throw new Error(`Invalid hook config for '${entry.type}': expected an object`);
|
|
124
|
+
}
|
|
125
|
+
await hook.initialize(parsedConfig);
|
|
126
|
+
}
|
|
127
|
+
hooks.push(hook);
|
|
128
|
+
}
|
|
129
|
+
const compactionConfig = config.compaction;
|
|
130
|
+
let compaction = null;
|
|
131
|
+
if (compactionConfig.enabled !== false) {
|
|
132
|
+
const factory = resolveByType({
|
|
133
|
+
kind: "compaction",
|
|
134
|
+
type: compactionConfig.type,
|
|
135
|
+
factories: image.compaction,
|
|
136
|
+
imageName
|
|
137
|
+
});
|
|
138
|
+
const parsedConfig = factory.configSchema.parse(compactionConfig);
|
|
139
|
+
compaction = await factory.create(parsedConfig);
|
|
140
|
+
}
|
|
141
|
+
return { logger, storage, tools, hooks, compaction };
|
|
142
|
+
}
|
|
143
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
144
|
+
0 && (module.exports = {
|
|
145
|
+
resolveServicesFromConfig
|
|
146
|
+
});
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ValidatedAgentConfig } from '../schemas/agent-config.js';
|
|
2
|
+
import type { DextoImage } from '../image/types.js';
|
|
3
|
+
import type { ResolvedServices } from './types.js';
|
|
4
|
+
export declare function resolveServicesFromConfig(config: ValidatedAgentConfig, image: DextoImage): Promise<ResolvedServices>;
|
|
5
|
+
//# sourceMappingURL=resolve-services-from-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-services-from-config.d.ts","sourceRoot":"","sources":["../../src/resolver/resolve-services-from-config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAmCnD,wBAAsB,yBAAyB,CAC3C,MAAM,EAAE,oBAAoB,EAC5B,KAAK,EAAE,UAAU,GAClB,OAAO,CAAC,gBAAgB,CAAC,CAqH3B"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { isPlainObject } from "./utils.js";
|
|
2
|
+
const MCP_TOOL_PREFIX = "mcp--";
|
|
3
|
+
function stripEnabled(entry) {
|
|
4
|
+
const obj = entry;
|
|
5
|
+
if (!Object.prototype.hasOwnProperty.call(obj, "enabled")) {
|
|
6
|
+
return obj;
|
|
7
|
+
}
|
|
8
|
+
const { enabled: _enabled, ...rest } = obj;
|
|
9
|
+
return rest;
|
|
10
|
+
}
|
|
11
|
+
function resolveByType(options) {
|
|
12
|
+
const { kind, type, factories, imageName } = options;
|
|
13
|
+
const factory = factories[type];
|
|
14
|
+
if (!factory) {
|
|
15
|
+
const available = Object.keys(factories).sort();
|
|
16
|
+
throw new Error(
|
|
17
|
+
`Unknown ${kind} type '${type}'. Available types from image '${imageName}': ${available.join(", ")}`
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
return factory;
|
|
21
|
+
}
|
|
22
|
+
async function resolveServicesFromConfig(config, image) {
|
|
23
|
+
const imageName = image.metadata.name;
|
|
24
|
+
const loggerFactoryInput = {
|
|
25
|
+
agentId: config.agentId,
|
|
26
|
+
config: config.logger
|
|
27
|
+
};
|
|
28
|
+
const loggerConfig = image.logger.configSchema.parse(loggerFactoryInput);
|
|
29
|
+
const logger = image.logger.create(loggerConfig);
|
|
30
|
+
const blobFactory = resolveByType({
|
|
31
|
+
kind: "blob storage",
|
|
32
|
+
type: config.storage.blob.type,
|
|
33
|
+
factories: image.storage.blob,
|
|
34
|
+
imageName
|
|
35
|
+
});
|
|
36
|
+
const databaseFactory = resolveByType({
|
|
37
|
+
kind: "database",
|
|
38
|
+
type: config.storage.database.type,
|
|
39
|
+
factories: image.storage.database,
|
|
40
|
+
imageName
|
|
41
|
+
});
|
|
42
|
+
const cacheFactory = resolveByType({
|
|
43
|
+
kind: "cache",
|
|
44
|
+
type: config.storage.cache.type,
|
|
45
|
+
factories: image.storage.cache,
|
|
46
|
+
imageName
|
|
47
|
+
});
|
|
48
|
+
const blobConfig = blobFactory.configSchema.parse(config.storage.blob);
|
|
49
|
+
const databaseConfig = databaseFactory.configSchema.parse(config.storage.database);
|
|
50
|
+
const cacheConfig = cacheFactory.configSchema.parse(config.storage.cache);
|
|
51
|
+
const storage = {
|
|
52
|
+
blob: await blobFactory.create(blobConfig, logger),
|
|
53
|
+
database: await databaseFactory.create(databaseConfig, logger),
|
|
54
|
+
cache: await cacheFactory.create(cacheConfig, logger)
|
|
55
|
+
};
|
|
56
|
+
const toolEntries = config.tools ?? image.defaults?.tools ?? [];
|
|
57
|
+
const tools = [];
|
|
58
|
+
const toolIds = /* @__PURE__ */ new Set();
|
|
59
|
+
for (const entry of toolEntries) {
|
|
60
|
+
if (entry.enabled === false) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
const factory = resolveByType({
|
|
64
|
+
kind: "tool",
|
|
65
|
+
type: entry.type,
|
|
66
|
+
factories: image.tools,
|
|
67
|
+
imageName
|
|
68
|
+
});
|
|
69
|
+
const validatedConfig = factory.configSchema.parse(stripEnabled(entry));
|
|
70
|
+
for (const tool of factory.create(validatedConfig)) {
|
|
71
|
+
if (tool.id.startsWith(MCP_TOOL_PREFIX)) {
|
|
72
|
+
throw new Error(
|
|
73
|
+
`Invalid local tool id '${tool.id}': '${MCP_TOOL_PREFIX}' prefix is reserved for MCP tools.`
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
if (toolIds.has(tool.id)) {
|
|
77
|
+
logger.warn(`Tool id conflict for '${tool.id}'. Skipping duplicate tool.`);
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
toolIds.add(tool.id);
|
|
81
|
+
tools.push(tool);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const hookEntries = config.hooks ?? image.defaults?.hooks ?? [];
|
|
85
|
+
const hooks = [];
|
|
86
|
+
for (const entry of hookEntries) {
|
|
87
|
+
if (entry.enabled === false) {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
const factory = resolveByType({
|
|
91
|
+
kind: "hook",
|
|
92
|
+
type: entry.type,
|
|
93
|
+
factories: image.hooks,
|
|
94
|
+
imageName
|
|
95
|
+
});
|
|
96
|
+
const parsedConfig = factory.configSchema.parse(stripEnabled(entry));
|
|
97
|
+
const hook = factory.create(parsedConfig);
|
|
98
|
+
if (hook.initialize) {
|
|
99
|
+
if (!isPlainObject(parsedConfig)) {
|
|
100
|
+
throw new Error(`Invalid hook config for '${entry.type}': expected an object`);
|
|
101
|
+
}
|
|
102
|
+
await hook.initialize(parsedConfig);
|
|
103
|
+
}
|
|
104
|
+
hooks.push(hook);
|
|
105
|
+
}
|
|
106
|
+
const compactionConfig = config.compaction;
|
|
107
|
+
let compaction = null;
|
|
108
|
+
if (compactionConfig.enabled !== false) {
|
|
109
|
+
const factory = resolveByType({
|
|
110
|
+
kind: "compaction",
|
|
111
|
+
type: compactionConfig.type,
|
|
112
|
+
factories: image.compaction,
|
|
113
|
+
imageName
|
|
114
|
+
});
|
|
115
|
+
const parsedConfig = factory.configSchema.parse(compactionConfig);
|
|
116
|
+
compaction = await factory.create(parsedConfig);
|
|
117
|
+
}
|
|
118
|
+
return { logger, storage, tools, hooks, compaction };
|
|
119
|
+
}
|
|
120
|
+
export {
|
|
121
|
+
resolveServicesFromConfig
|
|
122
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
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 to_dexto_agent_options_exports = {};
|
|
20
|
+
__export(to_dexto_agent_options_exports, {
|
|
21
|
+
toDextoAgentOptions: () => toDextoAgentOptions
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(to_dexto_agent_options_exports);
|
|
24
|
+
function toDextoAgentOptions(options) {
|
|
25
|
+
const { config, services, overrides } = options;
|
|
26
|
+
return {
|
|
27
|
+
agentId: config.agentId,
|
|
28
|
+
llm: config.llm,
|
|
29
|
+
systemPrompt: config.systemPrompt,
|
|
30
|
+
agentCard: config.agentCard,
|
|
31
|
+
greeting: config.greeting,
|
|
32
|
+
telemetry: config.telemetry,
|
|
33
|
+
memories: config.memories,
|
|
34
|
+
mcpServers: config.mcpServers,
|
|
35
|
+
sessions: config.sessions,
|
|
36
|
+
permissions: config.permissions,
|
|
37
|
+
elicitation: config.elicitation,
|
|
38
|
+
resources: config.resources,
|
|
39
|
+
prompts: config.prompts,
|
|
40
|
+
logger: services.logger,
|
|
41
|
+
storage: services.storage,
|
|
42
|
+
tools: services.tools,
|
|
43
|
+
hooks: services.hooks,
|
|
44
|
+
compaction: services.compaction,
|
|
45
|
+
...overrides ? { overrides } : {}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
49
|
+
0 && (module.exports = {
|
|
50
|
+
toDextoAgentOptions
|
|
51
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { DextoAgentOptions, InitializeServicesOptions } from '@dexto/core';
|
|
2
|
+
import type { ValidatedAgentConfig } from '../schemas/agent-config.js';
|
|
3
|
+
import type { ResolvedServices } from './types.js';
|
|
4
|
+
export interface ToDextoAgentOptionsInput {
|
|
5
|
+
config: ValidatedAgentConfig;
|
|
6
|
+
services: ResolvedServices;
|
|
7
|
+
overrides?: InitializeServicesOptions | undefined;
|
|
8
|
+
}
|
|
9
|
+
export declare function toDextoAgentOptions(options: ToDextoAgentOptionsInput): DextoAgentOptions;
|
|
10
|
+
//# sourceMappingURL=to-dexto-agent-options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"to-dexto-agent-options.d.ts","sourceRoot":"","sources":["../../src/resolver/to-dexto-agent-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAChF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,MAAM,WAAW,wBAAwB;IACrC,MAAM,EAAE,oBAAoB,CAAC;IAC7B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,SAAS,CAAC,EAAE,yBAAyB,GAAG,SAAS,CAAC;CACrD;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,wBAAwB,GAAG,iBAAiB,CAwBxF"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
function toDextoAgentOptions(options) {
|
|
2
|
+
const { config, services, overrides } = options;
|
|
3
|
+
return {
|
|
4
|
+
agentId: config.agentId,
|
|
5
|
+
llm: config.llm,
|
|
6
|
+
systemPrompt: config.systemPrompt,
|
|
7
|
+
agentCard: config.agentCard,
|
|
8
|
+
greeting: config.greeting,
|
|
9
|
+
telemetry: config.telemetry,
|
|
10
|
+
memories: config.memories,
|
|
11
|
+
mcpServers: config.mcpServers,
|
|
12
|
+
sessions: config.sessions,
|
|
13
|
+
permissions: config.permissions,
|
|
14
|
+
elicitation: config.elicitation,
|
|
15
|
+
resources: config.resources,
|
|
16
|
+
prompts: config.prompts,
|
|
17
|
+
logger: services.logger,
|
|
18
|
+
storage: services.storage,
|
|
19
|
+
tools: services.tools,
|
|
20
|
+
hooks: services.hooks,
|
|
21
|
+
compaction: services.compaction,
|
|
22
|
+
...overrides ? { overrides } : {}
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export {
|
|
26
|
+
toDextoAgentOptions
|
|
27
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
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 __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
var types_exports = {};
|
|
16
|
+
module.exports = __toCommonJS(types_exports);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { BlobStore } from '@dexto/core';
|
|
2
|
+
import type { Cache } from '@dexto/core';
|
|
3
|
+
import type { Database } from '@dexto/core';
|
|
4
|
+
import type { Hook } from '@dexto/core';
|
|
5
|
+
import type { CompactionStrategy } from '@dexto/core';
|
|
6
|
+
import type { Logger } from '@dexto/core';
|
|
7
|
+
import type { Tool } from '@dexto/core';
|
|
8
|
+
export interface ResolvedServices {
|
|
9
|
+
logger: Logger;
|
|
10
|
+
storage: {
|
|
11
|
+
blob: BlobStore;
|
|
12
|
+
database: Database;
|
|
13
|
+
cache: Cache;
|
|
14
|
+
};
|
|
15
|
+
tools: Tool[];
|
|
16
|
+
hooks: Hook[];
|
|
17
|
+
compaction: CompactionStrategy | null;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=types.d.ts.map
|