@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.
- package/LICENSE +21 -0
- package/README.md +85 -0
- package/dist/__tests__/benchmark.test.d.ts +10 -0
- package/dist/__tests__/benchmark.test.d.ts.map +1 -0
- package/dist/__tests__/benchmark.test.js +211 -0
- package/dist/__tests__/benchmark.test.js.map +1 -0
- package/dist/__tests__/container-pool.test.d.ts +2 -0
- package/dist/__tests__/container-pool.test.d.ts.map +1 -0
- package/dist/__tests__/container-pool.test.js +107 -0
- package/dist/__tests__/container-pool.test.js.map +1 -0
- package/dist/__tests__/native-executor.test.d.ts +2 -0
- package/dist/__tests__/native-executor.test.d.ts.map +1 -0
- package/dist/__tests__/native-executor.test.js +148 -0
- package/dist/__tests__/native-executor.test.js.map +1 -0
- package/dist/__tests__/sandbox-manager.test.d.ts +2 -0
- package/dist/__tests__/sandbox-manager.test.d.ts.map +1 -0
- package/dist/__tests__/sandbox-manager.test.js +115 -0
- package/dist/__tests__/sandbox-manager.test.js.map +1 -0
- package/dist/docker-types.d.ts +51 -0
- package/dist/docker-types.d.ts.map +1 -0
- package/dist/docker-types.js +6 -0
- package/dist/docker-types.js.map +1 -0
- package/dist/executors/base.d.ts +14 -0
- package/dist/executors/base.d.ts.map +1 -0
- package/dist/executors/base.js +12 -0
- package/dist/executors/base.js.map +1 -0
- package/dist/executors/docker.d.ts +22 -0
- package/dist/executors/docker.d.ts.map +1 -0
- package/dist/executors/docker.js +160 -0
- package/dist/executors/docker.js.map +1 -0
- package/dist/executors/index.d.ts +5 -0
- package/dist/executors/index.d.ts.map +1 -0
- package/dist/executors/index.js +5 -0
- package/dist/executors/index.js.map +1 -0
- package/dist/executors/native.d.ts +14 -0
- package/dist/executors/native.d.ts.map +1 -0
- package/dist/executors/native.js +62 -0
- package/dist/executors/native.js.map +1 -0
- package/dist/executors/wasm.d.ts +29 -0
- package/dist/executors/wasm.d.ts.map +1 -0
- package/dist/executors/wasm.js +171 -0
- package/dist/executors/wasm.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/pool/container-pool.d.ts +33 -0
- package/dist/pool/container-pool.d.ts.map +1 -0
- package/dist/pool/container-pool.js +116 -0
- package/dist/pool/container-pool.js.map +1 -0
- package/dist/pool/index.d.ts +2 -0
- package/dist/pool/index.d.ts.map +1 -0
- package/dist/pool/index.js +2 -0
- package/dist/pool/index.js.map +1 -0
- package/dist/sandbox-manager.d.ts +16 -0
- package/dist/sandbox-manager.d.ts.map +1 -0
- package/dist/sandbox-manager.js +98 -0
- package/dist/sandbox-manager.js.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/parse-resources.d.ts +14 -0
- package/dist/utils/parse-resources.d.ts.map +1 -0
- package/dist/utils/parse-resources.js +31 -0
- package/dist/utils/parse-resources.js.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { SandboxManager } from '../sandbox-manager';
|
|
3
|
+
function assertSuccess(result) {
|
|
4
|
+
if (!result.success) {
|
|
5
|
+
throw new Error(`Expected success but got error: ${result.error}`);
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
describe('SandboxManager', () => {
|
|
9
|
+
let manager;
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
manager = new SandboxManager();
|
|
12
|
+
});
|
|
13
|
+
afterEach(async () => {
|
|
14
|
+
await manager.shutdown();
|
|
15
|
+
});
|
|
16
|
+
describe('initialization', () => {
|
|
17
|
+
it('initializes successfully', async () => {
|
|
18
|
+
await manager.initialize();
|
|
19
|
+
});
|
|
20
|
+
it('only initializes once', async () => {
|
|
21
|
+
await manager.initialize();
|
|
22
|
+
await manager.initialize();
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
describe('native execution', () => {
|
|
26
|
+
it('executes command with native sandbox', async () => {
|
|
27
|
+
const request = {
|
|
28
|
+
command: ['echo', 'hello from sandbox'],
|
|
29
|
+
};
|
|
30
|
+
const config = {
|
|
31
|
+
type: 'native',
|
|
32
|
+
};
|
|
33
|
+
const result = await manager.execute(request, config);
|
|
34
|
+
assertSuccess(result);
|
|
35
|
+
expect(result.data.stdout.trim()).toBe('hello from sandbox');
|
|
36
|
+
expect(result.data.exitCode).toBe(0);
|
|
37
|
+
});
|
|
38
|
+
it('handles command failure', async () => {
|
|
39
|
+
const request = {
|
|
40
|
+
command: ['exit 1'],
|
|
41
|
+
};
|
|
42
|
+
const config = {
|
|
43
|
+
type: 'native',
|
|
44
|
+
};
|
|
45
|
+
const result = await manager.execute(request, config);
|
|
46
|
+
assertSuccess(result);
|
|
47
|
+
expect(result.data.exitCode).toBe(1);
|
|
48
|
+
});
|
|
49
|
+
it('handles timeout', async () => {
|
|
50
|
+
const request = {
|
|
51
|
+
command: ['sleep', '10'],
|
|
52
|
+
timeout: 100,
|
|
53
|
+
};
|
|
54
|
+
const config = {
|
|
55
|
+
type: 'native',
|
|
56
|
+
};
|
|
57
|
+
const result = await manager.execute(request, config);
|
|
58
|
+
assertSuccess(result);
|
|
59
|
+
expect(result.data.timedOut).toBe(true);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
describe('config merging', () => {
|
|
63
|
+
it('merges default config with request config', async () => {
|
|
64
|
+
const managerWithDefaults = new SandboxManager({
|
|
65
|
+
defaults: {
|
|
66
|
+
type: 'native',
|
|
67
|
+
timeout: 5000,
|
|
68
|
+
env: { DEFAULT_VAR: 'default' },
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
const request = {
|
|
72
|
+
command: ['echo $DEFAULT_VAR $EXTRA_VAR'],
|
|
73
|
+
};
|
|
74
|
+
const config = {
|
|
75
|
+
type: 'native',
|
|
76
|
+
env: { EXTRA_VAR: 'extra' },
|
|
77
|
+
};
|
|
78
|
+
const result = await managerWithDefaults.execute(request, config);
|
|
79
|
+
assertSuccess(result);
|
|
80
|
+
expect(result.data.stdout.trim()).toBe('default extra');
|
|
81
|
+
await managerWithDefaults.shutdown();
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
describe('docker fallback', () => {
|
|
85
|
+
it('falls back to native when docker unavailable', async () => {
|
|
86
|
+
const request = {
|
|
87
|
+
command: ['echo', 'fallback test'],
|
|
88
|
+
};
|
|
89
|
+
const config = {
|
|
90
|
+
type: 'docker',
|
|
91
|
+
image: 'alpine:3.19',
|
|
92
|
+
};
|
|
93
|
+
const result = await manager.execute(request, config);
|
|
94
|
+
assertSuccess(result);
|
|
95
|
+
expect(result.data.stdout.trim()).toBe('fallback test');
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
describe('isDockerAvailable', () => {
|
|
99
|
+
it('returns boolean for docker availability', async () => {
|
|
100
|
+
const available = await manager.isDockerAvailable();
|
|
101
|
+
expect(typeof available).toBe('boolean');
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
describe('shutdown', () => {
|
|
105
|
+
it('shuts down cleanly', async () => {
|
|
106
|
+
await manager.initialize();
|
|
107
|
+
await manager.shutdown();
|
|
108
|
+
await manager.initialize();
|
|
109
|
+
});
|
|
110
|
+
it('can shutdown without initialization', async () => {
|
|
111
|
+
await manager.shutdown();
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
//# sourceMappingURL=sandbox-manager.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-manager.test.js","sourceRoot":"","sources":["../../src/__tests__/sandbox-manager.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Docker types for sandbox execution
|
|
3
|
+
* These are minimal interfaces to avoid requiring @types/dockerode at compile time
|
|
4
|
+
*/
|
|
5
|
+
export interface DockerStream {
|
|
6
|
+
on(event: 'data', listener: (chunk: Buffer) => void): this;
|
|
7
|
+
on(event: 'end', listener: () => void): this;
|
|
8
|
+
on(event: string, listener: (...args: unknown[]) => void): this;
|
|
9
|
+
write(data: string | Buffer): boolean;
|
|
10
|
+
end(): void;
|
|
11
|
+
}
|
|
12
|
+
export interface DockerExec {
|
|
13
|
+
start(options: {
|
|
14
|
+
hijack?: boolean;
|
|
15
|
+
stdin?: boolean;
|
|
16
|
+
}): Promise<DockerStream>;
|
|
17
|
+
inspect(): Promise<{
|
|
18
|
+
ExitCode: number | null;
|
|
19
|
+
}>;
|
|
20
|
+
}
|
|
21
|
+
export interface DockerContainer {
|
|
22
|
+
id: string;
|
|
23
|
+
start(): Promise<void>;
|
|
24
|
+
stop(options?: {
|
|
25
|
+
t?: number;
|
|
26
|
+
}): Promise<void>;
|
|
27
|
+
remove(options?: {
|
|
28
|
+
force?: boolean;
|
|
29
|
+
}): Promise<void>;
|
|
30
|
+
exec(options: {
|
|
31
|
+
Cmd: string[];
|
|
32
|
+
Env?: string[];
|
|
33
|
+
WorkingDir?: string;
|
|
34
|
+
AttachStdout?: boolean;
|
|
35
|
+
AttachStderr?: boolean;
|
|
36
|
+
AttachStdin?: boolean;
|
|
37
|
+
}): Promise<DockerExec>;
|
|
38
|
+
}
|
|
39
|
+
export interface DockerImage {
|
|
40
|
+
inspect(): Promise<unknown>;
|
|
41
|
+
}
|
|
42
|
+
export interface Docker {
|
|
43
|
+
ping(): Promise<string>;
|
|
44
|
+
createContainer(options: Record<string, unknown>): Promise<DockerContainer>;
|
|
45
|
+
getImage(name: string): DockerImage;
|
|
46
|
+
pull(image: string, callback: (err: Error | null, stream: NodeJS.ReadableStream) => void): void;
|
|
47
|
+
modem: {
|
|
48
|
+
followProgress(stream: NodeJS.ReadableStream, callback: (err: Error | null, output: unknown[]) => void): void;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=docker-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker-types.d.ts","sourceRoot":"","sources":["../src/docker-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,YAAY;IAC3B,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IAC3D,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAC7C,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IAChE,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IACtC,GAAG,IAAI,IAAI,CAAC;CACb;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,OAAO,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC7E,OAAO,IAAI,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;CACjD;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,CAAC,OAAO,CAAC,EAAE;QAAE,CAAC,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,CAAC,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,IAAI,CAAC,OAAO,EAAE;QACZ,GAAG,EAAE,MAAM,EAAE,CAAC;QACd,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,WAAW,CAAC,EAAE,OAAO,CAAC;KACvB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACxB,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAC5E,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IACpC,IAAI,CACF,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,cAAc,KAAK,IAAI,GACnE,IAAI,CAAC;IACR,KAAK,EAAE;QACL,cAAc,CACZ,MAAM,EAAE,MAAM,CAAC,cAAc,EAC7B,QAAQ,EAAE,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,IAAI,GACvD,IAAI,CAAC;KACT,CAAC;CACH"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker-types.js","sourceRoot":"","sources":["../src/docker-types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base sandbox executor interface
|
|
3
|
+
*/
|
|
4
|
+
import type { SandboxConfig, SandboxExecutionRequest, SandboxExecutionResult, SandboxResult } from '@cogitator-ai/types';
|
|
5
|
+
export declare abstract class BaseSandboxExecutor {
|
|
6
|
+
abstract readonly type: string;
|
|
7
|
+
abstract execute(request: SandboxExecutionRequest, config: SandboxConfig): Promise<SandboxResult<SandboxExecutionResult>>;
|
|
8
|
+
abstract connect(): Promise<SandboxResult<void>>;
|
|
9
|
+
abstract disconnect(): Promise<SandboxResult<void>>;
|
|
10
|
+
abstract isAvailable(): Promise<boolean>;
|
|
11
|
+
protected success<T>(data: T): SandboxResult<T>;
|
|
12
|
+
protected failure(error: string): SandboxResult<never>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/executors/base.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,uBAAuB,EACvB,sBAAsB,EACtB,aAAa,EACd,MAAM,qBAAqB,CAAC;AAE7B,8BAAsB,mBAAmB;IACvC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAE/B,QAAQ,CAAC,OAAO,CACd,OAAO,EAAE,uBAAuB,EAChC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC;IAEjD,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAChD,QAAQ,CAAC,UAAU,IAAI,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IACnD,QAAQ,CAAC,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAExC,SAAS,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC;IAI/C,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC;CAGvD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/executors/base.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH,MAAM,OAAgB,mBAAmB;IAY7B,OAAO,CAAI,IAAO;QAC1B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACjC,CAAC;IAES,OAAO,CAAC,KAAa;QAC7B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IACnC,CAAC;CACF"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Docker sandbox executor - isolated execution in containers
|
|
3
|
+
*/
|
|
4
|
+
import type { SandboxConfig, SandboxExecutionRequest, SandboxExecutionResult, SandboxResult, SandboxDockerConfig, SandboxPoolConfig } from '@cogitator-ai/types';
|
|
5
|
+
import { BaseSandboxExecutor } from './base';
|
|
6
|
+
export interface DockerExecutorOptions {
|
|
7
|
+
docker?: SandboxDockerConfig;
|
|
8
|
+
pool?: SandboxPoolConfig;
|
|
9
|
+
}
|
|
10
|
+
export declare class DockerSandboxExecutor extends BaseSandboxExecutor {
|
|
11
|
+
readonly type = "docker";
|
|
12
|
+
private docker?;
|
|
13
|
+
private pool?;
|
|
14
|
+
private options;
|
|
15
|
+
constructor(options?: DockerExecutorOptions);
|
|
16
|
+
connect(): Promise<SandboxResult<void>>;
|
|
17
|
+
disconnect(): Promise<SandboxResult<void>>;
|
|
18
|
+
isAvailable(): Promise<boolean>;
|
|
19
|
+
execute(request: SandboxExecutionRequest, config: SandboxConfig): Promise<SandboxResult<SandboxExecutionResult>>;
|
|
20
|
+
private runWithTimeout;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=docker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../../src/executors/docker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,uBAAuB,EACvB,sBAAsB,EACtB,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAK7C,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,IAAI,CAAC,EAAE,iBAAiB,CAAC;CAC1B;AAMD,qBAAa,qBAAsB,SAAQ,mBAAmB;IAC5D,QAAQ,CAAC,IAAI,YAAY;IACzB,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,IAAI,CAAC,CAAgB;IAC7B,OAAO,CAAC,OAAO,CAAwB;gBAE3B,OAAO,GAAE,qBAA0B;IAKzC,OAAO,IAAI,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAyBvC,UAAU,IAAI,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAS1C,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAU/B,OAAO,CACX,OAAO,EAAE,uBAAuB,EAChC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC;YAqDnC,cAAc;CA2E7B"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Docker sandbox executor - isolated execution in containers
|
|
3
|
+
*/
|
|
4
|
+
import { BaseSandboxExecutor } from './base';
|
|
5
|
+
import { ContainerPool } from '../pool/container-pool';
|
|
6
|
+
import { parseMemory } from '../utils/parse-resources';
|
|
7
|
+
const MAX_OUTPUT_SIZE = 50_000;
|
|
8
|
+
const DEFAULT_TIMEOUT = 30_000;
|
|
9
|
+
const DEFAULT_IMAGE = 'alpine:3.19';
|
|
10
|
+
export class DockerSandboxExecutor extends BaseSandboxExecutor {
|
|
11
|
+
type = 'docker';
|
|
12
|
+
docker;
|
|
13
|
+
pool;
|
|
14
|
+
options;
|
|
15
|
+
constructor(options = {}) {
|
|
16
|
+
super();
|
|
17
|
+
this.options = options;
|
|
18
|
+
}
|
|
19
|
+
async connect() {
|
|
20
|
+
try {
|
|
21
|
+
const Dockerode = (await import('dockerode')).default;
|
|
22
|
+
this.docker = new Dockerode({
|
|
23
|
+
socketPath: this.options.docker?.socketPath ?? '/var/run/docker.sock',
|
|
24
|
+
host: this.options.docker?.host,
|
|
25
|
+
port: this.options.docker?.port,
|
|
26
|
+
});
|
|
27
|
+
await this.docker.ping();
|
|
28
|
+
this.pool = new ContainerPool(this.docker, {
|
|
29
|
+
maxSize: this.options.pool?.maxSize ?? 5,
|
|
30
|
+
idleTimeoutMs: this.options.pool?.idleTimeoutMs ?? 60_000,
|
|
31
|
+
});
|
|
32
|
+
return this.success(undefined);
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
return this.failure(`Failed to connect to Docker: ${error instanceof Error ? error.message : String(error)}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async disconnect() {
|
|
39
|
+
if (this.pool) {
|
|
40
|
+
await this.pool.destroyAll();
|
|
41
|
+
}
|
|
42
|
+
this.docker = undefined;
|
|
43
|
+
this.pool = undefined;
|
|
44
|
+
return this.success(undefined);
|
|
45
|
+
}
|
|
46
|
+
async isAvailable() {
|
|
47
|
+
if (!this.docker)
|
|
48
|
+
return false;
|
|
49
|
+
try {
|
|
50
|
+
await this.docker.ping();
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async execute(request, config) {
|
|
58
|
+
if (!this.docker || !this.pool) {
|
|
59
|
+
return this.failure('Docker executor not connected');
|
|
60
|
+
}
|
|
61
|
+
const startTime = Date.now();
|
|
62
|
+
const timeout = request.timeout ?? config.timeout ?? DEFAULT_TIMEOUT;
|
|
63
|
+
const image = config.image ?? DEFAULT_IMAGE;
|
|
64
|
+
try {
|
|
65
|
+
const container = await this.pool.acquire(image, {
|
|
66
|
+
memory: config.resources?.memory
|
|
67
|
+
? parseMemory(config.resources.memory)
|
|
68
|
+
: undefined,
|
|
69
|
+
cpus: config.resources?.cpus,
|
|
70
|
+
cpuShares: config.resources?.cpuShares,
|
|
71
|
+
pidsLimit: config.resources?.pidsLimit,
|
|
72
|
+
networkMode: config.network?.mode ?? 'none',
|
|
73
|
+
mounts: config.mounts,
|
|
74
|
+
user: config.user,
|
|
75
|
+
});
|
|
76
|
+
try {
|
|
77
|
+
const exec = await container.exec({
|
|
78
|
+
Cmd: request.command,
|
|
79
|
+
Env: Object.entries({ ...config.env, ...request.env }).map(([k, v]) => `${k}=${v}`),
|
|
80
|
+
WorkingDir: request.cwd ?? config.workdir ?? '/workspace',
|
|
81
|
+
AttachStdout: true,
|
|
82
|
+
AttachStderr: true,
|
|
83
|
+
AttachStdin: !!request.stdin,
|
|
84
|
+
});
|
|
85
|
+
const result = await this.runWithTimeout(exec, request.stdin, timeout);
|
|
86
|
+
return this.success({
|
|
87
|
+
stdout: result.stdout,
|
|
88
|
+
stderr: result.stderr,
|
|
89
|
+
exitCode: result.exitCode,
|
|
90
|
+
timedOut: result.timedOut,
|
|
91
|
+
duration: Date.now() - startTime,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
await this.pool.release(container);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
return this.failure(`Execution failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
async runWithTimeout(exec, stdin, timeoutMs) {
|
|
103
|
+
return new Promise((resolve, reject) => {
|
|
104
|
+
let timedOut = false;
|
|
105
|
+
const timer = setTimeout(() => {
|
|
106
|
+
timedOut = true;
|
|
107
|
+
}, timeoutMs);
|
|
108
|
+
void (async () => {
|
|
109
|
+
try {
|
|
110
|
+
const stream = await exec.start({
|
|
111
|
+
hijack: true,
|
|
112
|
+
stdin: !!stdin,
|
|
113
|
+
});
|
|
114
|
+
let stdout = '';
|
|
115
|
+
let stderr = '';
|
|
116
|
+
stream.on('data', (chunk) => {
|
|
117
|
+
let offset = 0;
|
|
118
|
+
while (offset < chunk.length) {
|
|
119
|
+
if (offset + 8 > chunk.length)
|
|
120
|
+
break;
|
|
121
|
+
const type = chunk[offset];
|
|
122
|
+
const size = (chunk[offset + 4] << 24) |
|
|
123
|
+
(chunk[offset + 5] << 16) |
|
|
124
|
+
(chunk[offset + 6] << 8) |
|
|
125
|
+
chunk[offset + 7];
|
|
126
|
+
if (offset + 8 + size > chunk.length)
|
|
127
|
+
break;
|
|
128
|
+
const data = chunk.slice(offset + 8, offset + 8 + size).toString('utf-8');
|
|
129
|
+
if (type === 1) {
|
|
130
|
+
stdout += data;
|
|
131
|
+
}
|
|
132
|
+
else if (type === 2) {
|
|
133
|
+
stderr += data;
|
|
134
|
+
}
|
|
135
|
+
offset += 8 + size;
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
if (stdin) {
|
|
139
|
+
stream.write(stdin);
|
|
140
|
+
stream.end();
|
|
141
|
+
}
|
|
142
|
+
await new Promise((res) => stream.on('end', res));
|
|
143
|
+
clearTimeout(timer);
|
|
144
|
+
const inspection = await exec.inspect();
|
|
145
|
+
resolve({
|
|
146
|
+
stdout: stdout.slice(0, MAX_OUTPUT_SIZE),
|
|
147
|
+
stderr: stderr.slice(0, MAX_OUTPUT_SIZE),
|
|
148
|
+
exitCode: inspection.ExitCode ?? 1,
|
|
149
|
+
timedOut,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
clearTimeout(timer);
|
|
154
|
+
reject(error instanceof Error ? error : new Error(String(error)));
|
|
155
|
+
}
|
|
156
|
+
})();
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=docker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker.js","sourceRoot":"","sources":["../../src/executors/docker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { BaseSandboxExecutor } from './base';
|
|
2
|
+
export { NativeSandboxExecutor } from './native';
|
|
3
|
+
export { DockerSandboxExecutor, type DockerExecutorOptions } from './docker';
|
|
4
|
+
export { WasmSandboxExecutor, type WasmExecutorOptions } from './wasm';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/executors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,KAAK,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,KAAK,mBAAmB,EAAE,MAAM,QAAQ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/executors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAA8B,MAAM,UAAU,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAA4B,MAAM,QAAQ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native sandbox executor - no isolation, runs directly on host.
|
|
3
|
+
* Used as fallback when Docker is unavailable.
|
|
4
|
+
*/
|
|
5
|
+
import type { SandboxConfig, SandboxExecutionRequest, SandboxExecutionResult, SandboxResult } from '@cogitator-ai/types';
|
|
6
|
+
import { BaseSandboxExecutor } from './base';
|
|
7
|
+
export declare class NativeSandboxExecutor extends BaseSandboxExecutor {
|
|
8
|
+
readonly type = "native";
|
|
9
|
+
connect(): Promise<SandboxResult<void>>;
|
|
10
|
+
disconnect(): Promise<SandboxResult<void>>;
|
|
11
|
+
isAvailable(): Promise<boolean>;
|
|
12
|
+
execute(request: SandboxExecutionRequest, config: SandboxConfig): Promise<SandboxResult<SandboxExecutionResult>>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=native.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../src/executors/native.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EACV,aAAa,EACb,uBAAuB,EACvB,sBAAsB,EACtB,aAAa,EACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAO7C,qBAAa,qBAAsB,SAAQ,mBAAmB;IAC5D,QAAQ,CAAC,IAAI,YAAY;IAEnB,OAAO,IAAI,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAIvC,UAAU,IAAI,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAI1C,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAI/B,OAAO,CACX,OAAO,EAAE,uBAAuB,EAChC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC;CA+ClD"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native sandbox executor - no isolation, runs directly on host.
|
|
3
|
+
* Used as fallback when Docker is unavailable.
|
|
4
|
+
*/
|
|
5
|
+
import { exec as execCallback } from 'node:child_process';
|
|
6
|
+
import { promisify } from 'node:util';
|
|
7
|
+
import { BaseSandboxExecutor } from './base';
|
|
8
|
+
const execPromise = promisify(execCallback);
|
|
9
|
+
const MAX_OUTPUT_SIZE = 50_000;
|
|
10
|
+
const MAX_BUFFER = 10 * 1024 * 1024;
|
|
11
|
+
export class NativeSandboxExecutor extends BaseSandboxExecutor {
|
|
12
|
+
type = 'native';
|
|
13
|
+
async connect() {
|
|
14
|
+
return this.success(undefined);
|
|
15
|
+
}
|
|
16
|
+
async disconnect() {
|
|
17
|
+
return this.success(undefined);
|
|
18
|
+
}
|
|
19
|
+
async isAvailable() {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
async execute(request, config) {
|
|
23
|
+
const startTime = Date.now();
|
|
24
|
+
const timeout = request.timeout ?? config.timeout ?? 30_000;
|
|
25
|
+
try {
|
|
26
|
+
const command = request.command.join(' ');
|
|
27
|
+
const { stdout, stderr } = await execPromise(command, {
|
|
28
|
+
cwd: request.cwd ?? config.workdir,
|
|
29
|
+
timeout,
|
|
30
|
+
env: { ...process.env, ...config.env, ...request.env },
|
|
31
|
+
maxBuffer: MAX_BUFFER,
|
|
32
|
+
});
|
|
33
|
+
return this.success({
|
|
34
|
+
stdout: stdout.slice(0, MAX_OUTPUT_SIZE),
|
|
35
|
+
stderr: stderr.slice(0, MAX_OUTPUT_SIZE),
|
|
36
|
+
exitCode: 0,
|
|
37
|
+
timedOut: false,
|
|
38
|
+
duration: Date.now() - startTime,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
const error = err;
|
|
43
|
+
if (error.killed) {
|
|
44
|
+
return this.success({
|
|
45
|
+
stdout: '',
|
|
46
|
+
stderr: `Command timed out after ${timeout.toString()}ms`,
|
|
47
|
+
exitCode: 124,
|
|
48
|
+
timedOut: true,
|
|
49
|
+
duration: Date.now() - startTime,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
return this.success({
|
|
53
|
+
stdout: (error.stdout ?? '').slice(0, MAX_OUTPUT_SIZE),
|
|
54
|
+
stderr: (error.stderr ?? error.message).slice(0, MAX_OUTPUT_SIZE),
|
|
55
|
+
exitCode: error.code ?? 1,
|
|
56
|
+
timedOut: false,
|
|
57
|
+
duration: Date.now() - startTime,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=native.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native.js","sourceRoot":"","sources":["../../src/executors/native.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAOtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAE7C,MAAM,WAAW,GAAG,SAAS,CAAC,YAAY,CAAC,CAAC;AAE5C,MAAM,eAAe,GAAG,MAAM,CAAC;AAC/B,MAAM,UAAU,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAEpC,MAAM,OAAO,qBAAsB,SAAQ,mBAAmB;IACnD,IAAI,GAAG,QAAQ,CAAC;IAEzB,KAAK,CAAC,OAAO;QACX,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,UAAU;QACd,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,WAAW;QACf,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,OAAO,CACX,OAAgC,EAChC,MAAqB;QAErB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC;QAE5D,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC1C,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE;gBACpD,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,MAAM,CAAC,OAAO;gBAClC,OAAO;gBACP,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE;gBACtD,SAAS,EAAE,UAAU;aACtB,CAAC,CAAC;YAEH,OAAO,IAAI,CAAC,OAAO,CAAC;gBAClB,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC;gBACxC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC;gBACxC,QAAQ,EAAE,CAAC;gBACX,QAAQ,EAAE,KAAK;gBACf,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;aACjC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,KAAK,GAAG,GAKb,CAAC;YAEF,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;gBACjB,OAAO,IAAI,CAAC,OAAO,CAAC;oBAClB,MAAM,EAAE,EAAE;oBACV,MAAM,EAAE,2BAA2B,OAAO,CAAC,QAAQ,EAAE,IAAI;oBACzD,QAAQ,EAAE,GAAG;oBACb,QAAQ,EAAE,IAAI;oBACd,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;iBACjC,CAAC,CAAC;YACL,CAAC;YAED,OAAO,IAAI,CAAC,OAAO,CAAC;gBAClB,MAAM,EAAE,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC;gBACtD,MAAM,EAAE,CAAC,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC;gBACjE,QAAQ,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC;gBACzB,QAAQ,EAAE,KAAK;gBACf,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;aACjC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,29 @@
|
|
|
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 type { SandboxConfig, SandboxExecutionRequest, SandboxExecutionResult, SandboxResult, SandboxWasmConfig } from '@cogitator-ai/types';
|
|
9
|
+
import { BaseSandboxExecutor } from './base';
|
|
10
|
+
export interface WasmExecutorOptions {
|
|
11
|
+
wasm?: SandboxWasmConfig;
|
|
12
|
+
}
|
|
13
|
+
export declare class WasmSandboxExecutor extends BaseSandboxExecutor {
|
|
14
|
+
readonly type = "wasm";
|
|
15
|
+
private createPlugin?;
|
|
16
|
+
private pluginCache;
|
|
17
|
+
private options;
|
|
18
|
+
private cacheOrder;
|
|
19
|
+
constructor(options?: WasmExecutorOptions);
|
|
20
|
+
connect(): Promise<SandboxResult<void>>;
|
|
21
|
+
disconnect(): Promise<SandboxResult<void>>;
|
|
22
|
+
isAvailable(): Promise<boolean>;
|
|
23
|
+
execute(request: SandboxExecutionRequest, config: SandboxConfig): Promise<SandboxResult<SandboxExecutionResult>>;
|
|
24
|
+
private getOrCreatePlugin;
|
|
25
|
+
private loadWasmSource;
|
|
26
|
+
private buildInput;
|
|
27
|
+
private executeWithTimeout;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=wasm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wasm.d.ts","sourceRoot":"","sources":["../../src/executors/wasm.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,uBAAuB,EACvB,sBAAsB,EACtB,aAAa,EACb,iBAAiB,EAClB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAI7C,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,iBAAiB,CAAC;CAC1B;AAiBD,qBAAa,mBAAoB,SAAQ,mBAAmB;IAC1D,QAAQ,CAAC,IAAI,UAAU;IACvB,OAAO,CAAC,YAAY,CAAC,CAAiB;IACtC,OAAO,CAAC,WAAW,CAAmC;IACtD,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,UAAU,CAAgB;gBAEtB,OAAO,GAAE,mBAAwB;IAKvC,OAAO,IAAI,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAYvC,UAAU,IAAI,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAY1C,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAQ/B,OAAO,CACX,OAAO,EAAE,uBAAuB,EAChC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC;YAkCnC,iBAAiB;YA6BjB,cAAc;IAiB5B,OAAO,CAAC,UAAU;YAWJ,kBAAkB;CA4DjC"}
|