@timmeck/brain-core 2.36.43 → 2.36.45

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.
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Code Sandbox — Isolated Code Execution (AutoGen-inspired)
3
+ *
4
+ * Führt generierten Code in isolierten Prozessen aus.
5
+ * Unterstützt TypeScript, Python und Shell.
6
+ * Timeout und Ressourcenlimits. Ergebnis-Capture (stdout/stderr/exitCode).
7
+ *
8
+ * Docker-basiert wenn verfügbar, Fallback auf lokale Subprozesse mit Timeout.
9
+ *
10
+ * Usage:
11
+ * ```typescript
12
+ * const sandbox = new CodeSandbox(db);
13
+ * const result = await sandbox.execute({
14
+ * code: 'console.log("Hello");',
15
+ * language: 'typescript',
16
+ * timeoutMs: 5000,
17
+ * });
18
+ * console.log(result.stdout); // "Hello\n"
19
+ * ```
20
+ */
21
+ import type Database from 'better-sqlite3';
22
+ export type SandboxLanguage = 'typescript' | 'javascript' | 'python' | 'shell';
23
+ export interface ExecutionRequest {
24
+ /** Code to execute */
25
+ code: string;
26
+ /** Language */
27
+ language: SandboxLanguage;
28
+ /** Max execution time in ms. Default: 10000 */
29
+ timeoutMs?: number;
30
+ /** Max memory in MB. Default: 128 */
31
+ memoryMb?: number;
32
+ /** Working directory (used for local execution) */
33
+ workDir?: string;
34
+ /** Name/label for this execution */
35
+ name?: string;
36
+ /** Additional context metadata */
37
+ metadata?: Record<string, unknown>;
38
+ }
39
+ export interface ExecutionResult {
40
+ id: string;
41
+ language: SandboxLanguage;
42
+ stdout: string;
43
+ stderr: string;
44
+ exitCode: number;
45
+ durationMs: number;
46
+ timedOut: boolean;
47
+ error?: string;
48
+ name?: string;
49
+ createdAt: number;
50
+ }
51
+ export interface CodeSandboxConfig {
52
+ /** Prefer Docker containers. Default: true */
53
+ preferDocker?: boolean;
54
+ /** Default timeout. Default: 10000 */
55
+ defaultTimeoutMs?: number;
56
+ /** Default max memory. Default: 128 */
57
+ defaultMemoryMb?: number;
58
+ /** Max output size in chars. Default: 100000 */
59
+ maxOutputSize?: number;
60
+ }
61
+ export interface CodeSandboxStatus {
62
+ totalExecutions: number;
63
+ successCount: number;
64
+ failCount: number;
65
+ timeoutCount: number;
66
+ avgDurationMs: number;
67
+ dockerAvailable: boolean;
68
+ languages: string[];
69
+ }
70
+ export declare function runSandboxMigration(db: Database.Database): void;
71
+ export declare class CodeSandbox {
72
+ private db;
73
+ private readonly log;
74
+ private readonly config;
75
+ private dockerAvailable;
76
+ private stmtInsert;
77
+ constructor(db: Database.Database, config?: CodeSandboxConfig);
78
+ /** Execute code in a sandboxed environment. */
79
+ execute(request: ExecutionRequest): Promise<ExecutionResult>;
80
+ /** Execute multiple code blocks sequentially. */
81
+ executeMany(requests: ExecutionRequest[]): Promise<ExecutionResult[]>;
82
+ /**
83
+ * Validate code without executing (basic syntax check).
84
+ * Returns null if valid, error message if invalid.
85
+ */
86
+ validate(code: string, language: SandboxLanguage): string | null;
87
+ private executeInDocker;
88
+ private executeLocal;
89
+ private runProcess;
90
+ private getDockerConfig;
91
+ private getLocalConfig;
92
+ /** Check if Docker is available on this system. */
93
+ isDockerAvailable(): Promise<boolean>;
94
+ /** Reset Docker availability cache. */
95
+ resetDockerCache(): void;
96
+ /** Get recent execution history. */
97
+ getHistory(limit?: number): Array<{
98
+ id: string;
99
+ language: string;
100
+ exitCode: number;
101
+ durationMs: number;
102
+ timedOut: boolean;
103
+ name: string | null;
104
+ error: string | null;
105
+ createdAt: string;
106
+ }>;
107
+ /** Get execution stats by language. */
108
+ getLanguageStats(): Array<{
109
+ language: string;
110
+ total: number;
111
+ avgDuration: number;
112
+ successRate: number;
113
+ }>;
114
+ getStatus(): CodeSandboxStatus;
115
+ private truncate;
116
+ private persistResult;
117
+ }
@@ -0,0 +1,353 @@
1
+ /**
2
+ * Code Sandbox — Isolated Code Execution (AutoGen-inspired)
3
+ *
4
+ * Führt generierten Code in isolierten Prozessen aus.
5
+ * Unterstützt TypeScript, Python und Shell.
6
+ * Timeout und Ressourcenlimits. Ergebnis-Capture (stdout/stderr/exitCode).
7
+ *
8
+ * Docker-basiert wenn verfügbar, Fallback auf lokale Subprozesse mit Timeout.
9
+ *
10
+ * Usage:
11
+ * ```typescript
12
+ * const sandbox = new CodeSandbox(db);
13
+ * const result = await sandbox.execute({
14
+ * code: 'console.log("Hello");',
15
+ * language: 'typescript',
16
+ * timeoutMs: 5000,
17
+ * });
18
+ * console.log(result.stdout); // "Hello\n"
19
+ * ```
20
+ */
21
+ import { execFile } from 'node:child_process';
22
+ import fs from 'node:fs';
23
+ import path from 'node:path';
24
+ import os from 'node:os';
25
+ import { getLogger } from '../utils/logger.js';
26
+ // ── Migration ───────────────────────────────────────────
27
+ export function runSandboxMigration(db) {
28
+ db.exec(`
29
+ CREATE TABLE IF NOT EXISTS sandbox_executions (
30
+ id TEXT PRIMARY KEY,
31
+ language TEXT NOT NULL,
32
+ exit_code INTEGER NOT NULL DEFAULT 0,
33
+ duration_ms INTEGER NOT NULL DEFAULT 0,
34
+ timed_out INTEGER NOT NULL DEFAULT 0,
35
+ name TEXT,
36
+ stdout_preview TEXT,
37
+ error TEXT,
38
+ created_at TEXT DEFAULT (datetime('now'))
39
+ );
40
+ CREATE INDEX IF NOT EXISTS idx_sandbox_created ON sandbox_executions(created_at);
41
+ CREATE INDEX IF NOT EXISTS idx_sandbox_language ON sandbox_executions(language);
42
+ `);
43
+ }
44
+ // ── Sandbox ─────────────────────────────────────────────
45
+ export class CodeSandbox {
46
+ db;
47
+ log = getLogger();
48
+ config;
49
+ dockerAvailable = null;
50
+ stmtInsert;
51
+ constructor(db, config = {}) {
52
+ this.db = db;
53
+ runSandboxMigration(db);
54
+ this.config = {
55
+ preferDocker: config.preferDocker ?? true,
56
+ defaultTimeoutMs: config.defaultTimeoutMs ?? 10000,
57
+ defaultMemoryMb: config.defaultMemoryMb ?? 128,
58
+ maxOutputSize: config.maxOutputSize ?? 100000,
59
+ };
60
+ this.stmtInsert = db.prepare('INSERT INTO sandbox_executions (id, language, exit_code, duration_ms, timed_out, name, stdout_preview, error) VALUES (?, ?, ?, ?, ?, ?, ?, ?)');
61
+ }
62
+ // ── Execution ─────────────────────────────────────────
63
+ /** Execute code in a sandboxed environment. */
64
+ async execute(request) {
65
+ const timeoutMs = request.timeoutMs ?? this.config.defaultTimeoutMs;
66
+ const id = `exec-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
67
+ const startTime = Date.now();
68
+ let result;
69
+ try {
70
+ // Check Docker availability (cached)
71
+ const useDocker = this.config.preferDocker && await this.isDockerAvailable();
72
+ if (useDocker) {
73
+ result = await this.executeInDocker(id, request, timeoutMs);
74
+ }
75
+ else {
76
+ result = await this.executeLocal(id, request, timeoutMs);
77
+ }
78
+ }
79
+ catch (e) {
80
+ result = {
81
+ id,
82
+ language: request.language,
83
+ stdout: '',
84
+ stderr: '',
85
+ exitCode: 1,
86
+ durationMs: Date.now() - startTime,
87
+ timedOut: false,
88
+ error: e.message,
89
+ name: request.name,
90
+ createdAt: Date.now(),
91
+ };
92
+ }
93
+ // Truncate output
94
+ result.stdout = this.truncate(result.stdout);
95
+ result.stderr = this.truncate(result.stderr);
96
+ // Persist
97
+ this.persistResult(result);
98
+ return result;
99
+ }
100
+ /** Execute multiple code blocks sequentially. */
101
+ async executeMany(requests) {
102
+ const results = [];
103
+ for (const req of requests) {
104
+ results.push(await this.execute(req));
105
+ }
106
+ return results;
107
+ }
108
+ /**
109
+ * Validate code without executing (basic syntax check).
110
+ * Returns null if valid, error message if invalid.
111
+ */
112
+ validate(code, language) {
113
+ try {
114
+ switch (language) {
115
+ case 'javascript':
116
+ case 'typescript':
117
+ // Basic check: try parsing with Function constructor
118
+ // eslint-disable-next-line no-new-func
119
+ new Function(code);
120
+ return null;
121
+ case 'python':
122
+ // Basic check: look for obvious syntax errors
123
+ if (code.includes('def ') && !code.includes(':'))
124
+ return 'Missing colon after def';
125
+ return null;
126
+ case 'shell':
127
+ return null; // Shell is hard to validate statically
128
+ default:
129
+ return `Unsupported language: ${language}`;
130
+ }
131
+ }
132
+ catch (e) {
133
+ return e.message;
134
+ }
135
+ }
136
+ // ── Docker Execution ──────────────────────────────────
137
+ async executeInDocker(id, request, timeoutMs) {
138
+ const { code, language, memoryMb } = request;
139
+ const memory = memoryMb ?? this.config.defaultMemoryMb;
140
+ const startTime = Date.now();
141
+ // Determine Docker image and command
142
+ const { image, cmd, ext } = this.getDockerConfig(language);
143
+ // Write code to temp file
144
+ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'brain-sandbox-'));
145
+ const codeFile = path.join(tmpDir, `code${ext}`);
146
+ fs.writeFileSync(codeFile, code, 'utf-8');
147
+ try {
148
+ const dockerArgs = [
149
+ 'run', '--rm',
150
+ '--memory', `${memory}m`,
151
+ '--cpus', '1',
152
+ '--network', 'none',
153
+ '--read-only',
154
+ '-v', `${tmpDir}:/sandbox:ro`,
155
+ '-w', '/sandbox',
156
+ image,
157
+ ...cmd,
158
+ ];
159
+ const { stdout, stderr, exitCode, timedOut } = await this.runProcess('docker', dockerArgs, timeoutMs);
160
+ return {
161
+ id,
162
+ language,
163
+ stdout,
164
+ stderr,
165
+ exitCode,
166
+ durationMs: Date.now() - startTime,
167
+ timedOut,
168
+ name: request.name,
169
+ createdAt: Date.now(),
170
+ };
171
+ }
172
+ finally {
173
+ // Cleanup temp files
174
+ try {
175
+ fs.rmSync(tmpDir, { recursive: true, force: true });
176
+ }
177
+ catch { /* ignore */ }
178
+ }
179
+ }
180
+ // ── Local Execution ───────────────────────────────────
181
+ async executeLocal(id, request, timeoutMs) {
182
+ const { code, language } = request;
183
+ const startTime = Date.now();
184
+ // Write code to temp file
185
+ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'brain-sandbox-'));
186
+ const { ext, localCmd } = this.getLocalConfig(language);
187
+ const codeFile = path.join(tmpDir, `code${ext}`);
188
+ fs.writeFileSync(codeFile, code, 'utf-8');
189
+ try {
190
+ const cmd = localCmd(codeFile);
191
+ const { stdout, stderr, exitCode, timedOut } = await this.runProcess(cmd[0], cmd.slice(1), timeoutMs);
192
+ return {
193
+ id,
194
+ language,
195
+ stdout,
196
+ stderr,
197
+ exitCode,
198
+ durationMs: Date.now() - startTime,
199
+ timedOut,
200
+ name: request.name,
201
+ createdAt: Date.now(),
202
+ };
203
+ }
204
+ finally {
205
+ try {
206
+ fs.rmSync(tmpDir, { recursive: true, force: true });
207
+ }
208
+ catch { /* ignore */ }
209
+ }
210
+ }
211
+ // ── Process Runner ────────────────────────────────────
212
+ runProcess(cmd, args, timeoutMs) {
213
+ return new Promise((resolve) => {
214
+ let timedOut = false;
215
+ let child;
216
+ try {
217
+ child = execFile(cmd, args, {
218
+ timeout: timeoutMs,
219
+ maxBuffer: this.config.maxOutputSize,
220
+ windowsHide: true,
221
+ }, (error, stdout, stderr) => {
222
+ if (error && 'killed' in error && error.killed) {
223
+ timedOut = true;
224
+ }
225
+ resolve({
226
+ stdout: stdout ?? '',
227
+ stderr: stderr ?? '',
228
+ exitCode: error ? (typeof error.code === 'number' ? error.code : 1) : 0,
229
+ timedOut,
230
+ });
231
+ });
232
+ }
233
+ catch (e) {
234
+ resolve({
235
+ stdout: '',
236
+ stderr: e.message,
237
+ exitCode: 127, // command not found
238
+ timedOut: false,
239
+ });
240
+ }
241
+ });
242
+ }
243
+ // ── Language Config ───────────────────────────────────
244
+ getDockerConfig(language) {
245
+ switch (language) {
246
+ case 'typescript':
247
+ return { image: 'node:20-alpine', cmd: ['npx', '--yes', 'tsx', '/sandbox/code.ts'], ext: '.ts' };
248
+ case 'javascript':
249
+ return { image: 'node:20-alpine', cmd: ['node', '/sandbox/code.js'], ext: '.js' };
250
+ case 'python':
251
+ return { image: 'python:3.12-alpine', cmd: ['python', '/sandbox/code.py'], ext: '.py' };
252
+ case 'shell':
253
+ return { image: 'alpine:3.19', cmd: ['sh', '/sandbox/code.sh'], ext: '.sh' };
254
+ default:
255
+ throw new Error(`Unsupported language: ${language}`);
256
+ }
257
+ }
258
+ getLocalConfig(language) {
259
+ switch (language) {
260
+ case 'typescript':
261
+ return { ext: '.ts', localCmd: (f) => ['npx', '--yes', 'tsx', f] };
262
+ case 'javascript':
263
+ return { ext: '.js', localCmd: (f) => ['node', f] };
264
+ case 'python':
265
+ return { ext: '.py', localCmd: (f) => ['python', f] };
266
+ case 'shell':
267
+ return { ext: '.sh', localCmd: (f) => ['sh', f] };
268
+ default:
269
+ throw new Error(`Unsupported language: ${language}`);
270
+ }
271
+ }
272
+ // ── Docker Detection ──────────────────────────────────
273
+ /** Check if Docker is available on this system. */
274
+ async isDockerAvailable() {
275
+ if (this.dockerAvailable !== null)
276
+ return this.dockerAvailable;
277
+ try {
278
+ const { exitCode } = await this.runProcess('docker', ['info'], 5000);
279
+ this.dockerAvailable = exitCode === 0;
280
+ }
281
+ catch {
282
+ this.dockerAvailable = false;
283
+ }
284
+ return this.dockerAvailable;
285
+ }
286
+ /** Reset Docker availability cache. */
287
+ resetDockerCache() {
288
+ this.dockerAvailable = null;
289
+ }
290
+ // ── History ──────────────────────────────────────────
291
+ /** Get recent execution history. */
292
+ getHistory(limit = 50) {
293
+ return this.db.prepare('SELECT id, language, exit_code as exitCode, duration_ms as durationMs, timed_out as timedOut, name, error, created_at as createdAt FROM sandbox_executions ORDER BY created_at DESC LIMIT ?').all(limit).map(r => ({
294
+ ...r,
295
+ timedOut: !!r.timedOut,
296
+ }));
297
+ }
298
+ /** Get execution stats by language. */
299
+ getLanguageStats() {
300
+ try {
301
+ return this.db.prepare(`
302
+ SELECT language,
303
+ COUNT(*) as total,
304
+ ROUND(AVG(duration_ms)) as avgDuration,
305
+ ROUND(CAST(SUM(CASE WHEN exit_code = 0 THEN 1 ELSE 0 END) AS REAL) / COUNT(*), 3) as successRate
306
+ FROM sandbox_executions
307
+ GROUP BY language
308
+ ORDER BY total DESC
309
+ `).all();
310
+ }
311
+ catch {
312
+ return [];
313
+ }
314
+ }
315
+ // ── Status ──────────────────────────────────────────
316
+ getStatus() {
317
+ try {
318
+ const total = this.db.prepare('SELECT COUNT(*) as c FROM sandbox_executions').get().c;
319
+ const success = this.db.prepare('SELECT COUNT(*) as c FROM sandbox_executions WHERE exit_code = 0').get().c;
320
+ const timeouts = this.db.prepare('SELECT COUNT(*) as c FROM sandbox_executions WHERE timed_out = 1').get().c;
321
+ const avgDuration = this.db.prepare('SELECT COALESCE(AVG(duration_ms), 0) as v FROM sandbox_executions').get().v;
322
+ const languages = this.db.prepare('SELECT DISTINCT language FROM sandbox_executions').all().map(r => r.language);
323
+ return {
324
+ totalExecutions: total,
325
+ successCount: success,
326
+ failCount: total - success - timeouts,
327
+ timeoutCount: timeouts,
328
+ avgDurationMs: Math.round(avgDuration),
329
+ dockerAvailable: this.dockerAvailable ?? false,
330
+ languages,
331
+ };
332
+ }
333
+ catch {
334
+ return { totalExecutions: 0, successCount: 0, failCount: 0, timeoutCount: 0, avgDurationMs: 0, dockerAvailable: false, languages: [] };
335
+ }
336
+ }
337
+ // ── Private Helpers ───────────────────────────────────
338
+ truncate(str) {
339
+ return str.length > this.config.maxOutputSize
340
+ ? str.slice(0, this.config.maxOutputSize) + '\n... [truncated]'
341
+ : str;
342
+ }
343
+ persistResult(result) {
344
+ try {
345
+ this.stmtInsert.run(result.id, result.language, result.exitCode, result.durationMs, result.timedOut ? 1 : 0, result.name ?? null, result.stdout.slice(0, 500), // preview only
346
+ result.error ?? null);
347
+ }
348
+ catch (e) {
349
+ this.log.warn(`[CodeSandbox] Failed to persist: ${e.message}`);
350
+ }
351
+ }
352
+ }
353
+ //# sourceMappingURL=code-sandbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"code-sandbox.js","sourceRoot":"","sources":["../../src/sandbox/code-sandbox.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,QAAQ,EAAqB,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAyD/C,2DAA2D;AAE3D,MAAM,UAAU,mBAAmB,CAAC,EAAqB;IACvD,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;GAcP,CAAC,CAAC;AACL,CAAC;AAED,2DAA2D;AAE3D,MAAM,OAAO,WAAW;IAOZ;IANO,GAAG,GAAG,SAAS,EAAE,CAAC;IAClB,MAAM,CAA8B;IAC7C,eAAe,GAAmB,IAAI,CAAC;IACvC,UAAU,CAAqB;IAEvC,YACU,EAAqB,EAC7B,SAA4B,EAAE;QADtB,OAAE,GAAF,EAAE,CAAmB;QAG7B,mBAAmB,CAAC,EAAE,CAAC,CAAC;QAExB,IAAI,CAAC,MAAM,GAAG;YACZ,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,IAAI;YACzC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,IAAI,KAAK;YAClD,eAAe,EAAE,MAAM,CAAC,eAAe,IAAI,GAAG;YAC9C,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,MAAM;SAC9C,CAAC;QAEF,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,OAAO,CAC1B,+IAA+I,CAChJ,CAAC;IACJ,CAAC;IAED,yDAAyD;IAEzD,+CAA+C;IAC/C,KAAK,CAAC,OAAO,CAAC,OAAyB;QACrC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC;QACpE,MAAM,EAAE,GAAG,QAAQ,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAC1E,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,IAAI,MAAuB,CAAC;QAE5B,IAAI,CAAC;YACH,qCAAqC;YACrC,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,IAAI,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAE7E,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,EAAE,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;YAC9D,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,GAAG;gBACP,EAAE;gBACF,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,MAAM,EAAE,EAAE;gBACV,MAAM,EAAE,EAAE;gBACV,QAAQ,EAAE,CAAC;gBACX,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;gBAClC,QAAQ,EAAE,KAAK;gBACf,KAAK,EAAG,CAAW,CAAC,OAAO;gBAC3B,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;aACtB,CAAC;QACJ,CAAC;QAED,kBAAkB;QAClB,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAE7C,UAAU;QACV,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAE3B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,iDAAiD;IACjD,KAAK,CAAC,WAAW,CAAC,QAA4B;QAC5C,MAAM,OAAO,GAAsB,EAAE,CAAC;QACtC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;QACxC,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;OAGG;IACH,QAAQ,CAAC,IAAY,EAAE,QAAyB;QAC9C,IAAI,CAAC;YACH,QAAQ,QAAQ,EAAE,CAAC;gBACjB,KAAK,YAAY,CAAC;gBAClB,KAAK,YAAY;oBACf,qDAAqD;oBACrD,uCAAuC;oBACvC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;oBACnB,OAAO,IAAI,CAAC;gBACd,KAAK,QAAQ;oBACX,8CAA8C;oBAC9C,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;wBAAE,OAAO,yBAAyB,CAAC;oBACnF,OAAO,IAAI,CAAC;gBACd,KAAK,OAAO;oBACV,OAAO,IAAI,CAAC,CAAC,uCAAuC;gBACtD;oBACE,OAAO,yBAAyB,QAAQ,EAAE,CAAC;YAC/C,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAQ,CAAW,CAAC,OAAO,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,yDAAyD;IAEjD,KAAK,CAAC,eAAe,CAC3B,EAAU,EACV,OAAyB,EACzB,SAAiB;QAEjB,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;QAC7C,MAAM,MAAM,GAAG,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC;QACvD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,qCAAqC;QACrC,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;QAE3D,0BAA0B;QAC1B,MAAM,MAAM,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC;QACxE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,GAAG,EAAE,CAAC,CAAC;QACjD,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAE1C,IAAI,CAAC;YACH,MAAM,UAAU,GAAG;gBACjB,KAAK,EAAE,MAAM;gBACb,UAAU,EAAE,GAAG,MAAM,GAAG;gBACxB,QAAQ,EAAE,GAAG;gBACb,WAAW,EAAE,MAAM;gBACnB,aAAa;gBACb,IAAI,EAAE,GAAG,MAAM,cAAc;gBAC7B,IAAI,EAAE,UAAU;gBAChB,KAAK;gBACL,GAAG,GAAG;aACP,CAAC;YAEF,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAI,CAAC,UAAU,CAClE,QAAQ,EAAE,UAAU,EAAE,SAAS,CAChC,CAAC;YAEF,OAAO;gBACL,EAAE;gBACF,QAAQ;gBACR,MAAM;gBACN,MAAM;gBACN,QAAQ;gBACR,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;gBAClC,QAAQ;gBACR,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;aACtB,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,qBAAqB;YACrB,IAAI,CAAC;gBAAC,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QACrF,CAAC;IACH,CAAC;IAED,yDAAyD;IAEjD,KAAK,CAAC,YAAY,CACxB,EAAU,EACV,OAAyB,EACzB,SAAiB;QAEjB,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;QACnC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,0BAA0B;QAC1B,MAAM,MAAM,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC;QACxE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,GAAG,EAAE,CAAC,CAAC;QACjD,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAE1C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAC/B,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAI,CAAC,UAAU,CAClE,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,SAAS,CAChC,CAAC;YAEF,OAAO;gBACL,EAAE;gBACF,QAAQ;gBACR,MAAM;gBACN,MAAM;gBACN,QAAQ;gBACR,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;gBAClC,QAAQ;gBACR,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;aACtB,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC;gBAAC,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QACrF,CAAC;IACH,CAAC;IAED,yDAAyD;IAEjD,UAAU,CAChB,GAAW,EACX,IAAc,EACd,SAAiB;QAEjB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,IAAI,QAAQ,GAAG,KAAK,CAAC;YACrB,IAAI,KAAmB,CAAC;YAExB,IAAI,CAAC;gBACH,KAAK,GAAG,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE;oBAC1B,OAAO,EAAE,SAAS;oBAClB,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,aAAa;oBACpC,WAAW,EAAE,IAAI;iBAClB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;oBAC3B,IAAI,KAAK,IAAI,QAAQ,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;wBAC/C,QAAQ,GAAG,IAAI,CAAC;oBAClB,CAAC;oBACD,OAAO,CAAC;wBACN,MAAM,EAAE,MAAM,IAAI,EAAE;wBACpB,MAAM,EAAE,MAAM,IAAI,EAAE;wBACpB,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,OAAQ,KAAiC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAE,KAAiC,CAAC,IAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;wBAC3I,QAAQ;qBACT,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC;oBACN,MAAM,EAAE,EAAE;oBACV,MAAM,EAAG,CAAW,CAAC,OAAO;oBAC5B,QAAQ,EAAE,GAAG,EAAE,oBAAoB;oBACnC,QAAQ,EAAE,KAAK;iBAChB,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,yDAAyD;IAEjD,eAAe,CAAC,QAAyB;QAC/C,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,YAAY;gBACf,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,kBAAkB,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;YACnG,KAAK,YAAY;gBACf,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,kBAAkB,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;YACpF,KAAK,QAAQ;gBACX,OAAO,EAAE,KAAK,EAAE,oBAAoB,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE,kBAAkB,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;YAC1F,KAAK,OAAO;gBACV,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,kBAAkB,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;YAC/E;gBACE,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAEO,cAAc,CAAC,QAAyB;QAC9C,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,YAAY;gBACf,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC;YACrE,KAAK,YAAY;gBACf,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC;YACtD,KAAK,QAAQ;gBACX,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC;YACxD,KAAK,OAAO;gBACV,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;YACpD;gBACE,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED,yDAAyD;IAEzD,mDAAmD;IACnD,KAAK,CAAC,iBAAiB;QACrB,IAAI,IAAI,CAAC,eAAe,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC,eAAe,CAAC;QAE/D,IAAI,CAAC;YACH,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;YACrE,IAAI,CAAC,eAAe,GAAG,QAAQ,KAAK,CAAC,CAAC;QACxC,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;QAC/B,CAAC;QAED,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;IAED,uCAAuC;IACvC,gBAAgB;QACd,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;IAC9B,CAAC;IAED,wDAAwD;IAExD,oCAAoC;IACpC,UAAU,CAAC,KAAK,GAAG,EAAE;QAInB,OAAO,IAAI,CAAC,EAAE,CAAC,OAAO,CACpB,6LAA6L,CAC9L,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACrB,GAAI,CAA6B;YACjC,QAAQ,EAAE,CAAC,CAAE,CAA6B,CAAC,QAAQ;SACpD,CAAC,CAGA,CAAC;IACL,CAAC;IAED,uCAAuC;IACvC,gBAAgB;QACd,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;;;;;;;;OAQtB,CAAC,CAAC,GAAG,EAA0F,CAAC;QACnG,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED,uDAAuD;IAEvD,SAAS;QACP,IAAI,CAAC;YACH,MAAM,KAAK,GAAI,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,8CAA8C,CAAC,CAAC,GAAG,EAAoB,CAAC,CAAC,CAAC;YACzG,MAAM,OAAO,GAAI,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,kEAAkE,CAAC,CAAC,GAAG,EAAoB,CAAC,CAAC,CAAC;YAC/H,MAAM,QAAQ,GAAI,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,kEAAkE,CAAC,CAAC,GAAG,EAAoB,CAAC,CAAC,CAAC;YAChI,MAAM,WAAW,GAAI,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,mEAAmE,CAAC,CAAC,GAAG,EAAoB,CAAC,CAAC,CAAC;YACpI,MAAM,SAAS,GAAI,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,kDAAkD,CAAC,CAAC,GAAG,EAAkC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YAElJ,OAAO;gBACL,eAAe,EAAE,KAAK;gBACtB,YAAY,EAAE,OAAO;gBACrB,SAAS,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ;gBACrC,YAAY,EAAE,QAAQ;gBACtB,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC;gBACtC,eAAe,EAAE,IAAI,CAAC,eAAe,IAAI,KAAK;gBAC9C,SAAS;aACV,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,eAAe,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,eAAe,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;QACzI,CAAC;IACH,CAAC;IAED,yDAAyD;IAEjD,QAAQ,CAAC,GAAW;QAC1B,OAAO,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa;YAC3C,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,mBAAmB;YAC/D,CAAC,CAAC,GAAG,CAAC;IACV,CAAC;IAEO,aAAa,CAAC,MAAuB;QAC3C,IAAI,CAAC;YACH,IAAI,CAAC,UAAU,CAAC,GAAG,CACjB,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,UAAU,EAC9D,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,IAAI,IAAI,EAC5C,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,eAAe;YAC5C,MAAM,CAAC,KAAK,IAAI,IAAI,CACrB,CAAC;QACJ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,oCAAqC,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export { CodeSandbox, runSandboxMigration } from './code-sandbox.js';
2
+ export type { SandboxLanguage, ExecutionRequest, ExecutionResult, CodeSandboxConfig, CodeSandboxStatus, } from './code-sandbox.js';
@@ -0,0 +1,2 @@
1
+ export { CodeSandbox, runSandboxMigration } from './code-sandbox.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sandbox/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -24,6 +24,8 @@ export interface ProposalMeta {
24
24
  reason_code?: string;
25
25
  metrics_before?: Record<string, number>;
26
26
  metrics_after?: Record<string, number>;
27
+ /** Reference code snippet from absorbed repos — included in generation prompt as inspiration. */
28
+ referenceCode?: string;
27
29
  }
28
30
  export type ModificationStatus = 'proposed' | 'generating' | 'testing' | 'ready' | 'approved' | 'rejected' | 'applied' | 'rolled_back' | 'failed';
29
31
  export interface FileDiff {
@@ -71,6 +73,7 @@ export declare class SelfModificationEngine {
71
73
  private selfScanner;
72
74
  private ts;
73
75
  private recentGenerations;
76
+ private referenceCodeMap;
74
77
  private readonly stmtInsert;
75
78
  private readonly stmtUpdate;
76
79
  private readonly stmtGet;
@@ -71,6 +71,8 @@ export class SelfModificationEngine {
71
71
  ts = null;
72
72
  // Rate limiting
73
73
  recentGenerations = [];
74
+ // Ephemeral reference code snippets (not persisted in DB)
75
+ referenceCodeMap = new Map();
74
76
  // Prepared statements
75
77
  stmtInsert;
76
78
  stmtUpdate;
@@ -129,6 +131,9 @@ export class SelfModificationEngine {
129
131
  // Store structured proposal metadata if provided
130
132
  if (meta) {
131
133
  this.updateProposalMeta(id, meta);
134
+ if (meta.referenceCode) {
135
+ this.referenceCodeMap.set(id, meta.referenceCode);
136
+ }
132
137
  }
133
138
  this.log.info(`[self-mod] Proposed modification #${id}: ${title}${meta?.risk_level ? ` [risk: ${meta.risk_level}]` : ''}`);
134
139
  this.ts?.emit('self-modification', 'analyzing', `Proposed: ${title}`, 'notable');
@@ -194,6 +199,15 @@ export class SelfModificationEngine {
194
199
  if (fileContents.length > 0) {
195
200
  systemPrompt += '\n\n## Current Source Code of Target Files\n' + fileContents.join('\n\n');
196
201
  }
202
+ // Add reference implementation from absorbed repos if available
203
+ const refCode = this.referenceCodeMap.get(modificationId);
204
+ if (refCode) {
205
+ systemPrompt += '\n\n## Reference Implementation (from absorbed repos)\n' +
206
+ 'The following code snippet shows a similar implementation that scored well:\n' +
207
+ '```\n' + refCode + '\n```\n' +
208
+ "Adapt this approach to fit Brain's architecture.";
209
+ this.referenceCodeMap.delete(modificationId); // Clean up after use
210
+ }
197
211
  // User message
198
212
  const userMessage = [
199
213
  `## Task: ${mod.title}`,