@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.
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/research/research-orchestrator.d.ts +4 -0
- package/dist/research/research-orchestrator.js +62 -1
- package/dist/research/research-orchestrator.js.map +1 -1
- package/dist/sandbox/code-sandbox.d.ts +117 -0
- package/dist/sandbox/code-sandbox.js +353 -0
- package/dist/sandbox/code-sandbox.js.map +1 -0
- package/dist/sandbox/index.d.ts +2 -0
- package/dist/sandbox/index.js +2 -0
- package/dist/sandbox/index.js.map +1 -0
- package/dist/self-modification/self-modification-engine.d.ts +3 -0
- package/dist/self-modification/self-modification-engine.js +14 -0
- package/dist/self-modification/self-modification-engine.js.map +1 -1
- package/package.json +1 -1
|
@@ -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 @@
|
|
|
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}`,
|