@cogitator-ai/sandbox 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.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +85 -0
  3. package/dist/__tests__/benchmark.test.d.ts +10 -0
  4. package/dist/__tests__/benchmark.test.d.ts.map +1 -0
  5. package/dist/__tests__/benchmark.test.js +211 -0
  6. package/dist/__tests__/benchmark.test.js.map +1 -0
  7. package/dist/__tests__/container-pool.test.d.ts +2 -0
  8. package/dist/__tests__/container-pool.test.d.ts.map +1 -0
  9. package/dist/__tests__/container-pool.test.js +107 -0
  10. package/dist/__tests__/container-pool.test.js.map +1 -0
  11. package/dist/__tests__/native-executor.test.d.ts +2 -0
  12. package/dist/__tests__/native-executor.test.d.ts.map +1 -0
  13. package/dist/__tests__/native-executor.test.js +148 -0
  14. package/dist/__tests__/native-executor.test.js.map +1 -0
  15. package/dist/__tests__/sandbox-manager.test.d.ts +2 -0
  16. package/dist/__tests__/sandbox-manager.test.d.ts.map +1 -0
  17. package/dist/__tests__/sandbox-manager.test.js +115 -0
  18. package/dist/__tests__/sandbox-manager.test.js.map +1 -0
  19. package/dist/docker-types.d.ts +51 -0
  20. package/dist/docker-types.d.ts.map +1 -0
  21. package/dist/docker-types.js +6 -0
  22. package/dist/docker-types.js.map +1 -0
  23. package/dist/executors/base.d.ts +14 -0
  24. package/dist/executors/base.d.ts.map +1 -0
  25. package/dist/executors/base.js +12 -0
  26. package/dist/executors/base.js.map +1 -0
  27. package/dist/executors/docker.d.ts +22 -0
  28. package/dist/executors/docker.d.ts.map +1 -0
  29. package/dist/executors/docker.js +160 -0
  30. package/dist/executors/docker.js.map +1 -0
  31. package/dist/executors/index.d.ts +5 -0
  32. package/dist/executors/index.d.ts.map +1 -0
  33. package/dist/executors/index.js +5 -0
  34. package/dist/executors/index.js.map +1 -0
  35. package/dist/executors/native.d.ts +14 -0
  36. package/dist/executors/native.d.ts.map +1 -0
  37. package/dist/executors/native.js +62 -0
  38. package/dist/executors/native.js.map +1 -0
  39. package/dist/executors/wasm.d.ts +29 -0
  40. package/dist/executors/wasm.d.ts.map +1 -0
  41. package/dist/executors/wasm.js +171 -0
  42. package/dist/executors/wasm.js.map +1 -0
  43. package/dist/index.d.ts +11 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +10 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/pool/container-pool.d.ts +33 -0
  48. package/dist/pool/container-pool.d.ts.map +1 -0
  49. package/dist/pool/container-pool.js +116 -0
  50. package/dist/pool/container-pool.js.map +1 -0
  51. package/dist/pool/index.d.ts +2 -0
  52. package/dist/pool/index.d.ts.map +1 -0
  53. package/dist/pool/index.js +2 -0
  54. package/dist/pool/index.js.map +1 -0
  55. package/dist/sandbox-manager.d.ts +16 -0
  56. package/dist/sandbox-manager.d.ts.map +1 -0
  57. package/dist/sandbox-manager.js +98 -0
  58. package/dist/sandbox-manager.js.map +1 -0
  59. package/dist/utils/index.d.ts +2 -0
  60. package/dist/utils/index.d.ts.map +1 -0
  61. package/dist/utils/index.js +2 -0
  62. package/dist/utils/index.js.map +1 -0
  63. package/dist/utils/parse-resources.d.ts +14 -0
  64. package/dist/utils/parse-resources.d.ts.map +1 -0
  65. package/dist/utils/parse-resources.js +31 -0
  66. package/dist/utils/parse-resources.js.map +1 -0
  67. package/package.json +59 -0
@@ -0,0 +1,171 @@
1
+ /**
2
+ * WASM sandbox executor - isolated execution via Extism
3
+ *
4
+ * Provides fast, memory-safe execution of WASM modules.
5
+ * Cold start: 1-10ms (vs Docker 1-5s)
6
+ * Memory: 1-10MB per plugin (vs Docker 50-200MB)
7
+ */
8
+ import { BaseSandboxExecutor } from './base';
9
+ import { readFile } from 'node:fs/promises';
10
+ import { existsSync } from 'node:fs';
11
+ const DEFAULT_TIMEOUT = 30_000;
12
+ const DEFAULT_FUNCTION = 'run';
13
+ const MAX_OUTPUT_SIZE = 50_000;
14
+ const DEFAULT_CACHE_SIZE = 10;
15
+ export class WasmSandboxExecutor extends BaseSandboxExecutor {
16
+ type = 'wasm';
17
+ createPlugin;
18
+ pluginCache = new Map();
19
+ options;
20
+ cacheOrder = [];
21
+ constructor(options = {}) {
22
+ super();
23
+ this.options = options;
24
+ }
25
+ async connect() {
26
+ try {
27
+ const extism = await import('@extism/extism');
28
+ this.createPlugin = extism.default;
29
+ return this.success(undefined);
30
+ }
31
+ catch (error) {
32
+ return this.failure(`Failed to load Extism: ${error instanceof Error ? error.message : String(error)}`);
33
+ }
34
+ }
35
+ async disconnect() {
36
+ for (const plugin of this.pluginCache.values()) {
37
+ try {
38
+ await plugin.close();
39
+ }
40
+ catch {
41
+ }
42
+ }
43
+ this.pluginCache.clear();
44
+ this.cacheOrder = [];
45
+ return this.success(undefined);
46
+ }
47
+ async isAvailable() {
48
+ if (!this.createPlugin) {
49
+ const result = await this.connect();
50
+ return result.success;
51
+ }
52
+ return true;
53
+ }
54
+ async execute(request, config) {
55
+ if (!this.createPlugin) {
56
+ return this.failure('WASM executor not connected');
57
+ }
58
+ const startTime = Date.now();
59
+ const timeout = request.timeout ?? config.timeout ?? DEFAULT_TIMEOUT;
60
+ const wasmModule = config.wasmModule;
61
+ const functionName = config.wasmFunction ?? DEFAULT_FUNCTION;
62
+ if (!wasmModule) {
63
+ return this.failure('No WASM module specified in config');
64
+ }
65
+ try {
66
+ const plugin = await this.getOrCreatePlugin(wasmModule, config.wasi ?? false);
67
+ const input = this.buildInput(request);
68
+ const result = await this.executeWithTimeout(plugin, functionName, input, timeout);
69
+ return this.success({
70
+ stdout: result.stdout.slice(0, MAX_OUTPUT_SIZE),
71
+ stderr: result.stderr.slice(0, MAX_OUTPUT_SIZE),
72
+ exitCode: result.exitCode,
73
+ timedOut: result.timedOut,
74
+ duration: Date.now() - startTime,
75
+ });
76
+ }
77
+ catch (error) {
78
+ return this.failure(`WASM execution failed: ${error instanceof Error ? error.message : String(error)}`);
79
+ }
80
+ }
81
+ async getOrCreatePlugin(wasmModule, useWasi) {
82
+ const cacheKey = `${wasmModule}:${useWasi}`;
83
+ if (this.pluginCache.has(cacheKey)) {
84
+ return this.pluginCache.get(cacheKey);
85
+ }
86
+ const source = await this.loadWasmSource(wasmModule);
87
+ const plugin = await this.createPlugin(source, { useWasi });
88
+ this.pluginCache.set(cacheKey, plugin);
89
+ this.cacheOrder.push(cacheKey);
90
+ const maxSize = this.options.wasm?.cacheSize ?? DEFAULT_CACHE_SIZE;
91
+ while (this.cacheOrder.length > maxSize) {
92
+ const oldKey = this.cacheOrder.shift();
93
+ const oldPlugin = this.pluginCache.get(oldKey);
94
+ if (oldPlugin) {
95
+ await oldPlugin.close();
96
+ this.pluginCache.delete(oldKey);
97
+ }
98
+ }
99
+ return plugin;
100
+ }
101
+ async loadWasmSource(wasmModule) {
102
+ if (wasmModule.startsWith('http://') || wasmModule.startsWith('https://')) {
103
+ return { wasm: [{ url: wasmModule }] };
104
+ }
105
+ if (existsSync(wasmModule)) {
106
+ return await readFile(wasmModule);
107
+ }
108
+ try {
109
+ const resolved = require.resolve(wasmModule);
110
+ return await readFile(resolved);
111
+ }
112
+ catch {
113
+ throw new Error(`WASM module not found: ${wasmModule}`);
114
+ }
115
+ }
116
+ buildInput(request) {
117
+ if (request.stdin) {
118
+ return request.stdin;
119
+ }
120
+ return JSON.stringify({
121
+ command: request.command,
122
+ cwd: request.cwd ?? '/workspace',
123
+ env: request.env ?? {},
124
+ });
125
+ }
126
+ async executeWithTimeout(plugin, functionName, input, timeoutMs) {
127
+ const executePromise = (async () => {
128
+ try {
129
+ const result = await plugin.call(functionName, input);
130
+ const output = new TextDecoder().decode(result);
131
+ try {
132
+ const parsed = JSON.parse(output);
133
+ return {
134
+ stdout: typeof parsed.stdout === 'string' ? parsed.stdout : output,
135
+ stderr: typeof parsed.stderr === 'string' ? parsed.stderr : '',
136
+ exitCode: typeof parsed.exitCode === 'number' ? parsed.exitCode : 0,
137
+ timedOut: false,
138
+ };
139
+ }
140
+ catch {
141
+ return {
142
+ stdout: output,
143
+ stderr: '',
144
+ exitCode: 0,
145
+ timedOut: false,
146
+ };
147
+ }
148
+ }
149
+ catch (error) {
150
+ return {
151
+ stdout: '',
152
+ stderr: error instanceof Error ? error.message : String(error),
153
+ exitCode: 1,
154
+ timedOut: false,
155
+ };
156
+ }
157
+ })();
158
+ const timeoutPromise = new Promise((resolve) => {
159
+ setTimeout(() => {
160
+ resolve({
161
+ stdout: '',
162
+ stderr: 'Execution timed out',
163
+ exitCode: 124,
164
+ timedOut: true,
165
+ });
166
+ }, timeoutMs);
167
+ });
168
+ return Promise.race([executePromise, timeoutPromise]);
169
+ }
170
+ }
171
+ //# sourceMappingURL=wasm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wasm.js","sourceRoot":"","sources":["../../src/executors/wasm.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @cogitator-ai/sandbox
3
+ *
4
+ * Docker-based sandbox execution for Cogitator agents
5
+ */
6
+ export { SandboxManager } from './sandbox-manager';
7
+ export { BaseSandboxExecutor, NativeSandboxExecutor, DockerSandboxExecutor, type DockerExecutorOptions, } from './executors/index';
8
+ export { ContainerPool, type ContainerPoolOptions, type ContainerCreateOptions } from './pool/index';
9
+ export { parseMemory, cpusToNanoCpus } from './utils/index';
10
+ export type { SandboxType, SandboxConfig, SandboxResourceLimits, SandboxNetworkConfig, SandboxMount, SandboxExecutionRequest, SandboxExecutionResult, SandboxManagerConfig, SandboxPoolConfig, SandboxDockerConfig, SandboxResult, } from '@cogitator-ai/types';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,EACrB,KAAK,qBAAqB,GAC3B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,KAAK,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACrG,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE5D,YAAY,EACV,WAAW,EACX,aAAa,EACb,qBAAqB,EACrB,oBAAoB,EACpB,YAAY,EACZ,uBAAuB,EACvB,sBAAsB,EACtB,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,aAAa,GACd,MAAM,qBAAqB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @cogitator-ai/sandbox
3
+ *
4
+ * Docker-based sandbox execution for Cogitator agents
5
+ */
6
+ export { SandboxManager } from './sandbox-manager';
7
+ export { BaseSandboxExecutor, NativeSandboxExecutor, DockerSandboxExecutor, } from './executors/index';
8
+ export { ContainerPool } from './pool/index';
9
+ export { parseMemory, cpusToNanoCpus } from './utils/index';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,GAEtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,aAAa,EAA0D,MAAM,cAAc,CAAC;AACrG,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Container pool for reusing Docker containers
3
+ */
4
+ import type { SandboxMount } from '@cogitator-ai/types';
5
+ import type { Docker, DockerContainer } from '../docker-types';
6
+ export interface ContainerCreateOptions {
7
+ memory?: number;
8
+ cpus?: number;
9
+ cpuShares?: number;
10
+ pidsLimit?: number;
11
+ networkMode?: string;
12
+ mounts?: SandboxMount[];
13
+ user?: string;
14
+ }
15
+ export interface ContainerPoolOptions {
16
+ maxSize?: number;
17
+ idleTimeoutMs?: number;
18
+ }
19
+ export declare class ContainerPool {
20
+ private docker;
21
+ private containers;
22
+ private maxSize;
23
+ private idleTimeoutMs;
24
+ private cleanupInterval?;
25
+ constructor(docker: Docker, options?: ContainerPoolOptions);
26
+ acquire(image: string, options: ContainerCreateOptions): Promise<DockerContainer>;
27
+ release(container: DockerContainer): Promise<void>;
28
+ private createContainer;
29
+ private destroyContainer;
30
+ private cleanup;
31
+ destroyAll(): Promise<void>;
32
+ }
33
+ //# sourceMappingURL=container-pool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"container-pool.d.ts","sourceRoot":"","sources":["../../src/pool/container-pool.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAS/D,MAAM,WAAW,sBAAsB;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAyB;IAC3C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,eAAe,CAAC,CAAiC;gBAE7C,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,oBAAyB;IAWxD,OAAO,CACX,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,eAAe,CAAC;IAyBrB,OAAO,CAAC,SAAS,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;YAW1C,eAAe;YA4Cf,gBAAgB;YAWhB,OAAO;IAgBf,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAUlC"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Container pool for reusing Docker containers
3
+ */
4
+ export class ContainerPool {
5
+ docker;
6
+ containers = [];
7
+ maxSize;
8
+ idleTimeoutMs;
9
+ cleanupInterval;
10
+ constructor(docker, options = {}) {
11
+ this.docker = docker;
12
+ this.maxSize = options.maxSize ?? 5;
13
+ this.idleTimeoutMs = options.idleTimeoutMs ?? 60_000;
14
+ this.cleanupInterval = setInterval(() => void this.cleanup(), this.idleTimeoutMs / 2);
15
+ }
16
+ async acquire(image, options) {
17
+ const available = this.containers.find((c) => !c.inUse && c.image === image);
18
+ if (available) {
19
+ available.inUse = true;
20
+ available.lastUsed = Date.now();
21
+ return available.container;
22
+ }
23
+ const container = await this.createContainer(image, options);
24
+ if (this.containers.length < this.maxSize) {
25
+ this.containers.push({
26
+ container,
27
+ image,
28
+ inUse: true,
29
+ lastUsed: Date.now(),
30
+ });
31
+ }
32
+ return container;
33
+ }
34
+ async release(container) {
35
+ const pooled = this.containers.find((c) => c.container.id === container.id);
36
+ if (pooled) {
37
+ pooled.inUse = false;
38
+ pooled.lastUsed = Date.now();
39
+ }
40
+ else {
41
+ await this.destroyContainer(container);
42
+ }
43
+ }
44
+ async createContainer(image, options) {
45
+ try {
46
+ await this.docker.getImage(image).inspect();
47
+ }
48
+ catch {
49
+ await new Promise((resolve, reject) => {
50
+ this.docker.pull(image, (err, stream) => {
51
+ if (err)
52
+ return reject(err);
53
+ this.docker.modem.followProgress(stream, (progressErr) => {
54
+ if (progressErr)
55
+ reject(progressErr);
56
+ else
57
+ resolve();
58
+ });
59
+ });
60
+ });
61
+ }
62
+ const binds = options.mounts?.map((m) => `${m.source}:${m.target}${m.readOnly ? ':ro' : ''}`);
63
+ const container = await this.docker.createContainer({
64
+ Image: image,
65
+ Cmd: ['sleep', 'infinity'],
66
+ User: options.user,
67
+ HostConfig: {
68
+ Memory: options.memory,
69
+ NanoCpus: options.cpus ? Math.floor(options.cpus * 1e9) : undefined,
70
+ CpuShares: options.cpuShares,
71
+ PidsLimit: options.pidsLimit ?? 100,
72
+ NetworkMode: options.networkMode ?? 'none',
73
+ Binds: binds,
74
+ SecurityOpt: ['no-new-privileges'],
75
+ CapDrop: ['ALL'],
76
+ ReadonlyRootfs: false,
77
+ },
78
+ WorkingDir: '/workspace',
79
+ });
80
+ await container.start();
81
+ return container;
82
+ }
83
+ async destroyContainer(container) {
84
+ try {
85
+ await container.stop({ t: 1 });
86
+ }
87
+ catch {
88
+ }
89
+ try {
90
+ await container.remove({ force: true });
91
+ }
92
+ catch {
93
+ }
94
+ }
95
+ async cleanup() {
96
+ const now = Date.now();
97
+ const toRemove = [];
98
+ for (const pooled of this.containers) {
99
+ if (!pooled.inUse && now - pooled.lastUsed > this.idleTimeoutMs) {
100
+ toRemove.push(pooled);
101
+ }
102
+ }
103
+ for (const pooled of toRemove) {
104
+ this.containers = this.containers.filter((c) => c !== pooled);
105
+ await this.destroyContainer(pooled.container);
106
+ }
107
+ }
108
+ async destroyAll() {
109
+ if (this.cleanupInterval) {
110
+ clearInterval(this.cleanupInterval);
111
+ }
112
+ await Promise.all(this.containers.map((c) => this.destroyContainer(c.container)));
113
+ this.containers = [];
114
+ }
115
+ }
116
+ //# sourceMappingURL=container-pool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"container-pool.js","sourceRoot":"","sources":["../../src/pool/container-pool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from './container-pool';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pool/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './container-pool';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/pool/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Sandbox manager - orchestrates sandbox execution
3
+ */
4
+ import type { SandboxConfig, SandboxExecutionRequest, SandboxExecutionResult, SandboxManagerConfig, SandboxResult } from '@cogitator-ai/types';
5
+ export declare class SandboxManager {
6
+ private executors;
7
+ private config;
8
+ private initialized;
9
+ constructor(config?: SandboxManagerConfig);
10
+ initialize(): Promise<void>;
11
+ execute(request: SandboxExecutionRequest, config: SandboxConfig): Promise<SandboxResult<SandboxExecutionResult>>;
12
+ isDockerAvailable(): Promise<boolean>;
13
+ isWasmAvailable(): Promise<boolean>;
14
+ shutdown(): Promise<void>;
15
+ }
16
+ //# sourceMappingURL=sandbox-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-manager.d.ts","sourceRoot":"","sources":["../src/sandbox-manager.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,uBAAuB,EACvB,sBAAsB,EACtB,oBAAoB,EACpB,aAAa,EAEd,MAAM,qBAAqB,CAAC;AAM7B,qBAAa,cAAc;IACzB,OAAO,CAAC,SAAS,CAA+C;IAChE,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,WAAW,CAAS;gBAEhB,MAAM,GAAE,oBAAyB;IAIvC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAiC3B,OAAO,CACX,OAAO,EAAE,uBAAuB,EAChC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC;IA8C3C,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC;IAMrC,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAMnC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAOhC"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Sandbox manager - orchestrates sandbox execution
3
+ */
4
+ import { DockerSandboxExecutor } from './executors/docker';
5
+ import { NativeSandboxExecutor } from './executors/native';
6
+ import { WasmSandboxExecutor } from './executors/wasm';
7
+ export class SandboxManager {
8
+ executors = new Map();
9
+ config;
10
+ initialized = false;
11
+ constructor(config = {}) {
12
+ this.config = config;
13
+ }
14
+ async initialize() {
15
+ if (this.initialized)
16
+ return;
17
+ const native = new NativeSandboxExecutor();
18
+ await native.connect();
19
+ this.executors.set('native', native);
20
+ try {
21
+ const docker = new DockerSandboxExecutor({
22
+ docker: this.config.docker,
23
+ pool: this.config.pool,
24
+ });
25
+ const result = await docker.connect();
26
+ if (result.success) {
27
+ this.executors.set('docker', docker);
28
+ }
29
+ }
30
+ catch {
31
+ }
32
+ try {
33
+ const wasm = new WasmSandboxExecutor({
34
+ wasm: this.config.wasm,
35
+ });
36
+ const result = await wasm.connect();
37
+ if (result.success) {
38
+ this.executors.set('wasm', wasm);
39
+ }
40
+ }
41
+ catch {
42
+ }
43
+ this.initialized = true;
44
+ }
45
+ async execute(request, config) {
46
+ await this.initialize();
47
+ const type = config.type;
48
+ const executor = this.executors.get(type);
49
+ if (!executor) {
50
+ if (type === 'wasm') {
51
+ console.warn('[sandbox] WASM unavailable, falling back to Docker');
52
+ const dockerExecutor = this.executors.get('docker');
53
+ if (dockerExecutor) {
54
+ return dockerExecutor.execute(request, { ...config, type: 'docker' });
55
+ }
56
+ console.warn('[sandbox] Docker also unavailable, falling back to native execution');
57
+ const nativeExecutor = this.executors.get('native');
58
+ if (nativeExecutor) {
59
+ return nativeExecutor.execute(request, { ...config, type: 'native' });
60
+ }
61
+ }
62
+ if (type === 'docker') {
63
+ console.warn('[sandbox] Docker unavailable, falling back to native execution');
64
+ const nativeExecutor = this.executors.get('native');
65
+ if (nativeExecutor) {
66
+ return nativeExecutor.execute(request, { ...config, type: 'native' });
67
+ }
68
+ }
69
+ return { success: false, error: `Sandbox type '${type}' not available` };
70
+ }
71
+ const mergedConfig = {
72
+ ...this.config.defaults,
73
+ ...config,
74
+ resources: { ...this.config.defaults?.resources, ...config.resources },
75
+ network: { ...this.config.defaults?.network, ...config.network },
76
+ env: { ...this.config.defaults?.env, ...config.env },
77
+ };
78
+ return executor.execute(request, mergedConfig);
79
+ }
80
+ async isDockerAvailable() {
81
+ await this.initialize();
82
+ const docker = this.executors.get('docker');
83
+ return docker ? docker.isAvailable() : false;
84
+ }
85
+ async isWasmAvailable() {
86
+ await this.initialize();
87
+ const wasm = this.executors.get('wasm');
88
+ return wasm ? wasm.isAvailable() : false;
89
+ }
90
+ async shutdown() {
91
+ for (const executor of this.executors.values()) {
92
+ await executor.disconnect();
93
+ }
94
+ this.executors.clear();
95
+ this.initialized = false;
96
+ }
97
+ }
98
+ //# sourceMappingURL=sandbox-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-manager.js","sourceRoot":"","sources":["../src/sandbox-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from './parse-resources';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './parse-resources';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Utilities for parsing resource limits
3
+ */
4
+ /**
5
+ * Parse memory string to bytes
6
+ * @example parseMemory('256MB') => 268435456
7
+ */
8
+ export declare function parseMemory(memory: string): number;
9
+ /**
10
+ * Parse CPU count to nanoseconds (Docker format)
11
+ * @example parseCpus(0.5) => 500000000
12
+ */
13
+ export declare function cpusToNanoCpus(cpus: number): number;
14
+ //# sourceMappingURL=parse-resources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-resources.d.ts","sourceRoot":"","sources":["../../src/utils/parse-resources.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAkBlD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Utilities for parsing resource limits
3
+ */
4
+ /**
5
+ * Parse memory string to bytes
6
+ * @example parseMemory('256MB') => 268435456
7
+ */
8
+ export function parseMemory(memory) {
9
+ const match = /^(\d+(?:\.\d+)?)\s*(B|KB|MB|GB|TB)?$/i.exec(memory);
10
+ if (!match) {
11
+ throw new Error(`Invalid memory format: ${memory}`);
12
+ }
13
+ const value = parseFloat(match[1]);
14
+ const unit = (match[2] ?? 'B').toUpperCase();
15
+ const multipliers = {
16
+ B: 1,
17
+ KB: 1024,
18
+ MB: 1024 * 1024,
19
+ GB: 1024 * 1024 * 1024,
20
+ TB: 1024 * 1024 * 1024 * 1024,
21
+ };
22
+ return Math.floor(value * multipliers[unit]);
23
+ }
24
+ /**
25
+ * Parse CPU count to nanoseconds (Docker format)
26
+ * @example parseCpus(0.5) => 500000000
27
+ */
28
+ export function cpusToNanoCpus(cpus) {
29
+ return Math.floor(cpus * 1e9);
30
+ }
31
+ //# sourceMappingURL=parse-resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-resources.js","sourceRoot":"","sources":["../../src/utils/parse-resources.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,MAAc;IACxC,MAAM,KAAK,GAAG,uCAAuC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,0BAA0B,MAAM,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IAE7C,MAAM,WAAW,GAA2B;QAC1C,CAAC,EAAE,CAAC;QACJ,EAAE,EAAE,IAAI;QACR,EAAE,EAAE,IAAI,GAAG,IAAI;QACf,EAAE,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI;QACtB,EAAE,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI;KAC9B,CAAC;IAEF,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC;AAChC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@cogitator-ai/sandbox",
3
+ "version": "0.1.0",
4
+ "description": "Sandbox execution for Cogitator agents (Docker and WASM)",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "dependencies": {
18
+ "@types/dockerode": "^3.3.31",
19
+ "nanoid": "^5.0.4",
20
+ "@cogitator-ai/types": "0.1.0"
21
+ },
22
+ "optionalDependencies": {
23
+ "@extism/extism": "^1.0.3",
24
+ "dockerode": "^4.0.2"
25
+ },
26
+ "devDependencies": {
27
+ "typescript": "^5.3.0",
28
+ "vitest": "^1.0.0"
29
+ },
30
+ "peerDependencies": {
31
+ "@extism/extism": "^1.0.0",
32
+ "dockerode": "^4.0.0"
33
+ },
34
+ "peerDependenciesMeta": {
35
+ "@extism/extism": {
36
+ "optional": true
37
+ },
38
+ "dockerode": {
39
+ "optional": true
40
+ }
41
+ },
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "https://github.com/eL1fe/cogitator.git",
45
+ "directory": "packages/sandbox"
46
+ },
47
+ "publishConfig": {
48
+ "access": "public"
49
+ },
50
+ "license": "MIT",
51
+ "scripts": {
52
+ "build": "tsc",
53
+ "dev": "tsc --watch",
54
+ "clean": "rm -rf dist",
55
+ "typecheck": "tsc --noEmit",
56
+ "test": "vitest run",
57
+ "test:watch": "vitest"
58
+ }
59
+ }