@papicandela/mcx-core 0.1.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/index.d.ts +568 -0
- package/dist/index.js +4679 -0
- package/package.json +36 -0
- package/src/adapter.ts +166 -0
- package/src/config.ts +175 -0
- package/src/executor.ts +377 -0
- package/src/index.ts +53 -0
- package/src/sandbox/bun-worker.ts +272 -0
- package/src/sandbox/interface.ts +40 -0
- package/src/skill.ts +180 -0
- package/src/types.ts +146 -0
- package/tsconfig.json +28 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ExecutionContext, SandboxConfig, SandboxResult } from "../types.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Interface for sandbox implementations
|
|
5
|
+
*
|
|
6
|
+
* Sandboxes provide isolated code execution environments
|
|
7
|
+
* with configurable resource limits and adapter injection.
|
|
8
|
+
*/
|
|
9
|
+
export interface ISandbox {
|
|
10
|
+
/**
|
|
11
|
+
* Execute code in the sandbox
|
|
12
|
+
*
|
|
13
|
+
* @param code - JavaScript code to execute
|
|
14
|
+
* @param context - Execution context with adapters and variables
|
|
15
|
+
* @returns Result containing the value, logs, and execution metadata
|
|
16
|
+
*/
|
|
17
|
+
execute<T = unknown>(code: string, context: ExecutionContext): Promise<SandboxResult<T>>;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Get the current sandbox configuration
|
|
21
|
+
*/
|
|
22
|
+
getConfig(): SandboxConfig;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Update sandbox configuration
|
|
26
|
+
*
|
|
27
|
+
* @param config - New configuration options to merge
|
|
28
|
+
*/
|
|
29
|
+
configure(config: Partial<SandboxConfig>): void;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Dispose of sandbox resources
|
|
33
|
+
*/
|
|
34
|
+
dispose(): void;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Factory function type for creating sandbox instances
|
|
39
|
+
*/
|
|
40
|
+
export type SandboxFactory = (config?: SandboxConfig) => ISandbox;
|
package/src/skill.ts
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import type { SandboxConfig, Skill, SkillConfig } from "./types.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Default sandbox configuration for skills.
|
|
5
|
+
*/
|
|
6
|
+
const DEFAULT_SANDBOX_CONFIG: Required<SandboxConfig> = {
|
|
7
|
+
timeout: 5000,
|
|
8
|
+
memoryLimit: 128,
|
|
9
|
+
allowAsync: true,
|
|
10
|
+
globals: {},
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Define a skill with configuration.
|
|
15
|
+
*
|
|
16
|
+
* Skills are executable code snippets that run in a sandboxed environment
|
|
17
|
+
* with access to registered adapters.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* const mySkill = defineSkill({
|
|
22
|
+
* name: 'process-data',
|
|
23
|
+
* description: 'Processes data using file and http adapters',
|
|
24
|
+
* adapters: ['file', 'http'],
|
|
25
|
+
* code: `
|
|
26
|
+
* const data = await adapters.file.read('input.json');
|
|
27
|
+
* const result = await adapters.http.post('/api/process', { body: data });
|
|
28
|
+
* return result;
|
|
29
|
+
* `,
|
|
30
|
+
* sandbox: {
|
|
31
|
+
* timeout: 10000,
|
|
32
|
+
* },
|
|
33
|
+
* });
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export function defineSkill(config: SkillConfig): Skill {
|
|
37
|
+
if (!config.name) {
|
|
38
|
+
throw new Error("Skill name is required");
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const hasCode = config.code && config.code.trim() !== "";
|
|
42
|
+
const hasRun = typeof config.run === "function";
|
|
43
|
+
|
|
44
|
+
if (!hasCode && !hasRun) {
|
|
45
|
+
throw new Error("Skill must have either 'code' (string) or 'run' (function)");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
name: config.name,
|
|
50
|
+
description: config.description,
|
|
51
|
+
version: config.version ?? "1.0.0",
|
|
52
|
+
adapters: config.adapters ?? [],
|
|
53
|
+
code: config.code,
|
|
54
|
+
run: config.run,
|
|
55
|
+
sandboxConfig: {
|
|
56
|
+
...DEFAULT_SANDBOX_CONFIG,
|
|
57
|
+
...config.sandbox,
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Define multiple skills at once.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```ts
|
|
67
|
+
* const skills = defineSkills([
|
|
68
|
+
* { name: 'skill1', code: '...' },
|
|
69
|
+
* { name: 'skill2', code: '...' },
|
|
70
|
+
* ]);
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export function defineSkills(configs: SkillConfig[]): Skill[] {
|
|
74
|
+
return configs.map(defineSkill);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Create a skill builder for fluent skill definition.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```ts
|
|
82
|
+
* const skill = skillBuilder('my-skill')
|
|
83
|
+
* .description('Does something useful')
|
|
84
|
+
* .requires('file', 'http')
|
|
85
|
+
* .timeout(10000)
|
|
86
|
+
* .code(`
|
|
87
|
+
* // skill code here
|
|
88
|
+
* `)
|
|
89
|
+
* .build();
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
export function skillBuilder(name: string): SkillBuilder {
|
|
93
|
+
return new SkillBuilder(name);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Fluent builder for skill configuration.
|
|
98
|
+
*/
|
|
99
|
+
class SkillBuilder {
|
|
100
|
+
private config: SkillConfig;
|
|
101
|
+
|
|
102
|
+
constructor(name: string) {
|
|
103
|
+
this.config = {
|
|
104
|
+
name,
|
|
105
|
+
code: "",
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Set the skill description.
|
|
111
|
+
*/
|
|
112
|
+
description(description: string): this {
|
|
113
|
+
this.config.description = description;
|
|
114
|
+
return this;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Set the skill version.
|
|
119
|
+
*/
|
|
120
|
+
version(version: string): this {
|
|
121
|
+
this.config.version = version;
|
|
122
|
+
return this;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Specify required adapters.
|
|
127
|
+
*/
|
|
128
|
+
requires(...adapters: string[]): this {
|
|
129
|
+
this.config.adapters = adapters;
|
|
130
|
+
return this;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Set the execution timeout in milliseconds.
|
|
135
|
+
*/
|
|
136
|
+
timeout(ms: number): this {
|
|
137
|
+
this.config.sandbox = {
|
|
138
|
+
...this.config.sandbox,
|
|
139
|
+
timeout: ms,
|
|
140
|
+
};
|
|
141
|
+
return this;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Set the memory limit in MB.
|
|
146
|
+
*/
|
|
147
|
+
memoryLimit(mb: number): this {
|
|
148
|
+
this.config.sandbox = {
|
|
149
|
+
...this.config.sandbox,
|
|
150
|
+
memoryLimit: mb,
|
|
151
|
+
};
|
|
152
|
+
return this;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Set the skill code.
|
|
157
|
+
*/
|
|
158
|
+
code(code: string): this {
|
|
159
|
+
this.config.code = code;
|
|
160
|
+
return this;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Set custom sandbox configuration.
|
|
165
|
+
*/
|
|
166
|
+
sandbox(config: SandboxConfig): this {
|
|
167
|
+
this.config.sandbox = {
|
|
168
|
+
...this.config.sandbox,
|
|
169
|
+
...config,
|
|
170
|
+
};
|
|
171
|
+
return this;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Build the skill.
|
|
176
|
+
*/
|
|
177
|
+
build(): Skill {
|
|
178
|
+
return defineSkill(this.config);
|
|
179
|
+
}
|
|
180
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Configuration for an adapter method parameter
|
|
5
|
+
*/
|
|
6
|
+
export interface AdapterMethodParameter {
|
|
7
|
+
name: string;
|
|
8
|
+
type: "string" | "number" | "boolean" | "object" | "array";
|
|
9
|
+
description?: string;
|
|
10
|
+
required?: boolean;
|
|
11
|
+
default?: unknown;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Configuration for an adapter method
|
|
16
|
+
*/
|
|
17
|
+
export interface AdapterMethodConfig {
|
|
18
|
+
name: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
parameters?: AdapterMethodParameter[];
|
|
21
|
+
handler: (...args: unknown[]) => unknown | Promise<unknown>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* A method exposed by an adapter
|
|
26
|
+
*/
|
|
27
|
+
export interface AdapterMethod {
|
|
28
|
+
name: string;
|
|
29
|
+
description?: string;
|
|
30
|
+
parameters: AdapterMethodParameter[];
|
|
31
|
+
execute: (...args: unknown[]) => unknown | Promise<unknown>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Configuration for defining an adapter
|
|
36
|
+
*/
|
|
37
|
+
export interface AdapterConfig<TSchema extends z.ZodTypeAny = z.ZodTypeAny> {
|
|
38
|
+
name: string;
|
|
39
|
+
description?: string;
|
|
40
|
+
version?: string;
|
|
41
|
+
configSchema?: TSchema;
|
|
42
|
+
methods: AdapterMethodConfig[];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* A registered adapter instance
|
|
47
|
+
*/
|
|
48
|
+
export interface Adapter {
|
|
49
|
+
name: string;
|
|
50
|
+
description?: string;
|
|
51
|
+
version: string;
|
|
52
|
+
methods: Map<string, AdapterMethod>;
|
|
53
|
+
config?: unknown;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Configuration for the sandbox execution environment
|
|
58
|
+
*/
|
|
59
|
+
export interface SandboxConfig {
|
|
60
|
+
/** Timeout in milliseconds (default: 5000) */
|
|
61
|
+
timeout?: number;
|
|
62
|
+
/** Memory limit in MB (default: 128) */
|
|
63
|
+
memoryLimit?: number;
|
|
64
|
+
/** Whether to allow async/await (default: true) */
|
|
65
|
+
allowAsync?: boolean;
|
|
66
|
+
/** Custom global variables to inject */
|
|
67
|
+
globals?: Record<string, unknown>;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Result from sandbox code execution
|
|
72
|
+
*/
|
|
73
|
+
export interface SandboxResult<T = unknown> {
|
|
74
|
+
success: boolean;
|
|
75
|
+
value?: T;
|
|
76
|
+
error?: {
|
|
77
|
+
name: string;
|
|
78
|
+
message: string;
|
|
79
|
+
stack?: string;
|
|
80
|
+
};
|
|
81
|
+
logs: string[];
|
|
82
|
+
executionTime: number;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Skill run function signature
|
|
87
|
+
*/
|
|
88
|
+
export type SkillRunFunction = (ctx: Record<string, unknown>) => Promise<unknown> | unknown;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Configuration for defining a skill
|
|
92
|
+
*/
|
|
93
|
+
export interface SkillConfig {
|
|
94
|
+
name: string;
|
|
95
|
+
description?: string;
|
|
96
|
+
version?: string;
|
|
97
|
+
/** Required adapters for this skill */
|
|
98
|
+
adapters?: string[];
|
|
99
|
+
/** The skill code to execute (sandbox mode) */
|
|
100
|
+
code?: string;
|
|
101
|
+
/** Direct run function (native mode) */
|
|
102
|
+
run?: SkillRunFunction;
|
|
103
|
+
/** Sandbox configuration overrides */
|
|
104
|
+
sandbox?: SandboxConfig;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* A registered skill instance
|
|
109
|
+
*/
|
|
110
|
+
export interface Skill {
|
|
111
|
+
name: string;
|
|
112
|
+
description?: string;
|
|
113
|
+
version: string;
|
|
114
|
+
adapters: string[];
|
|
115
|
+
/** Code string for sandbox execution */
|
|
116
|
+
code?: string;
|
|
117
|
+
/** Direct run function for native execution */
|
|
118
|
+
run?: SkillRunFunction;
|
|
119
|
+
sandboxConfig: SandboxConfig;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Main MCX framework configuration
|
|
124
|
+
*/
|
|
125
|
+
export interface MCXConfig {
|
|
126
|
+
/** Adapters to load */
|
|
127
|
+
adapters?: Adapter[];
|
|
128
|
+
/** Skills to register */
|
|
129
|
+
skills?: Skill[];
|
|
130
|
+
/** Default sandbox configuration */
|
|
131
|
+
sandbox?: SandboxConfig;
|
|
132
|
+
/** Path to adapters directory */
|
|
133
|
+
adaptersDir?: string;
|
|
134
|
+
/** Path to skills directory */
|
|
135
|
+
skillsDir?: string;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Context passed to sandbox execution
|
|
140
|
+
*/
|
|
141
|
+
export interface ExecutionContext {
|
|
142
|
+
/** Registered adapters accessible in sandbox */
|
|
143
|
+
adapters: Record<string, Record<string, (...args: unknown[]) => unknown | Promise<unknown>>>;
|
|
144
|
+
/** Custom variables */
|
|
145
|
+
variables?: Record<string, unknown>;
|
|
146
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"lib": ["ES2022"],
|
|
7
|
+
"types": ["@types/bun"],
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"declaration": true,
|
|
13
|
+
"declarationMap": true,
|
|
14
|
+
"sourceMap": true,
|
|
15
|
+
"outDir": "./dist",
|
|
16
|
+
"rootDir": "./src",
|
|
17
|
+
"resolveJsonModule": true,
|
|
18
|
+
"isolatedModules": true,
|
|
19
|
+
"noEmit": true,
|
|
20
|
+
"noUnusedLocals": true,
|
|
21
|
+
"noUnusedParameters": true,
|
|
22
|
+
"noImplicitReturns": true,
|
|
23
|
+
"noFallthroughCasesInSwitch": true,
|
|
24
|
+
"allowSyntheticDefaultImports": true
|
|
25
|
+
},
|
|
26
|
+
"include": ["src/**/*"],
|
|
27
|
+
"exclude": ["node_modules", "dist", "**/*.test.ts"]
|
|
28
|
+
}
|