Ferrell Synthetic Intelligence
Synchronize release candidate hardening
0d13723
Raw
History Blame Contribute Delete
9.11 kB
import http from 'node:http';
import { execFile } from 'node:child_process';
import { promises as fs } from 'node:fs';
import path from 'node:path';
import { ModelManager } from './model-manager.mjs';
import { CommunityStore } from '../community/store.mjs';
import { LspManager } from './lsp-manager.mjs';
import { DapManager } from './dap-manager.mjs';
import { WorkspaceManager } from './workspace-manager.mjs';
import { TrainingManager } from './training-manager.mjs';
import { ReplayStore } from './replay-store.mjs';
import { ArenaManager } from './arena-manager.mjs';
const HOST = '127.0.0.1';
const PORT = Number(process.env.AIDE_DAEMON_PORT || 4777);
const WORKSPACE = path.resolve(process.env.AIDE_WORKSPACE || process.cwd());
const MODEL_DIR = path.resolve(process.env.AIDE_MODEL_DIR || path.join(WORKSPACE, 'models'));
const MANIFEST = path.join(WORKSPACE, 'models', 'manifest.json');
const modelManager = new ModelManager({ manifestPath: MANIFEST, modelDir: MODEL_DIR, binaryPath: process.env.AIDE_LLAMA_SERVER || '/root/runtime/llama-b10333/llama-server' });
await modelManager.load().catch(() => {});
const communityStore = new CommunityStore(path.join(WORKSPACE, 'community', 'store.json'));
await communityStore.load().catch(() => {});
const lspManager = new LspManager({ manifestPath: path.join(WORKSPACE, 'languages', 'manifest.json'), workspace: WORKSPACE });
await lspManager.load().catch(() => {});
const dapManager = new DapManager({ manifestPath: path.join(WORKSPACE, 'debuggers', 'manifest.json'), workspace: WORKSPACE, pythonPath: process.env.AIDE_PYTHON || '' });
await dapManager.load().catch(() => {});
const workspaceManager = new WorkspaceManager(WORKSPACE);
const trainingManager = new TrainingManager({ manifestPath: path.join(WORKSPACE, 'training', 'manifest.json'), workspace: WORKSPACE });
await trainingManager.load().catch(() => {});
const replayStore = new ReplayStore(path.join(WORKSPACE, 'replays', 'store.json'));
await replayStore.load().catch(() => {});
const arenaManager = new ArenaManager({ modelManager, manifestPath: MANIFEST, suitePath: path.join(WORKSPACE, 'benchmarks', 'manifest.json') });
function json(response, status, body) {
const payload = JSON.stringify(body);
response.writeHead(status, {
'Content-Type': 'application/json; charset=utf-8',
'Content-Length': Buffer.byteLength(payload),
'Access-Control-Allow-Origin': 'http://127.0.0.1:4173',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type'
});
response.end(payload);
}
async function body(request) {
let data = '';
for await (const chunk of request) {
data += chunk;
if (Buffer.byteLength(data) > 16 * 1024) throw new Error('request too large');
}
return data ? JSON.parse(data) : {};
}
function runGit(args) {
return new Promise((resolve, reject) => {
execFile('git', args, { cwd: WORKSPACE, timeout: 5000, maxBuffer: 256 * 1024 }, (error, stdout, stderr) => {
if (error) reject(new Error(stderr.trim() || error.message));
else resolve(stdout);
});
});
}
async function workspaceSummary() {
const entries = await fs.readdir(WORKSPACE, { withFileTypes: true });
return entries.filter(entry => !entry.name.startsWith('.')).slice(0, 200).map(entry => ({
name: entry.name,
kind: entry.isDirectory() ? 'directory' : 'file'
}));
}
const server = http.createServer(async (request, response) => {
if (request.method === 'OPTIONS') return json(response, 204, {});
try {
if (request.method === 'GET' && request.url === '/health') {
return json(response, 200, { ok: true, service: 'aide-local-daemon', host: HOST, workspace: WORKSPACE });
}
if (request.method === 'GET' && request.url === '/api/workspace') {
return json(response, 200, { workspace: WORKSPACE, entries: await workspaceSummary() });
}
if (request.method === 'GET' && request.url.startsWith('/api/file?')) {
const relativePath = new URL(request.url, 'http://127.0.0.1').searchParams.get('path');
return json(response, 200, { path: relativePath, content: await workspaceManager.read(relativePath) });
}
if (request.method === 'POST' && request.url === '/api/file/write') {
const input = await body(request);
return json(response, 200, await workspaceManager.write(input.path, input.content, input.approved));
}
if (request.method === 'POST' && request.url === '/api/patch/apply') {
const input = await body(request);
return json(response, 200, await workspaceManager.applyPatch(input.patch, input.approved));
}
if (request.method === 'GET' && request.url === '/api/git/status') {
try {
return json(response, 200, { workspace: WORKSPACE, status: await runGit(['status', '--short']) });
} catch (error) {
return json(response, 200, { workspace: WORKSPACE, status: '', unavailable: error.message });
}
}
if (request.method === 'GET' && request.url === '/api/models/status') {
return json(response, 200, { models: modelManager.status() });
}
if (request.method === 'GET' && request.url === '/api/community') {
return json(response, 200, communityStore.list());
}
if (request.method === 'GET' && request.url === '/api/lsp/status') {
return json(response, 200, { servers: lspManager.status() });
}
if (request.method === 'GET' && request.url === '/api/dap/status') {
return json(response, 200, { adapters: dapManager.status() });
}
if (request.method === 'GET' && request.url === '/api/training/status') {
return json(response, 200, trainingManager.status());
}
if (request.method === 'GET' && request.url === '/api/replays') return json(response, 200, replayStore.list());
if (request.method === 'POST' && request.url === '/api/replays') return json(response, 201, { replay: await replayStore.add(await body(request)) });
if (request.method === 'POST' && request.url === '/api/arena/run') return json(response, 200, await arenaManager.run((await body(request)).approved));
if (request.method === 'POST' && request.url === '/api/training/start') {
const input = await body(request);
return json(response, 200, trainingManager.start(input.id, input.approved));
}
if (request.method === 'POST' && request.url === '/api/training/stop') {
return json(response, 200, trainingManager.stop());
}
if (request.method === 'POST' && request.url === '/api/dap/start') {
return json(response, 200, await dapManager.start((await body(request)).id));
}
if (request.method === 'POST' && request.url === '/api/dap/request') {
const input = await body(request);
return json(response, 200, await dapManager.request(input.id, input.request));
}
if (request.method === 'POST' && request.url === '/api/dap/stop') {
return json(response, 200, await dapManager.stop((await body(request)).id));
}
if (request.method === 'POST' && request.url === '/api/lsp/start') {
return json(response, 200, await lspManager.start((await body(request)).id));
}
if (request.method === 'POST' && request.url === '/api/lsp/request') {
const input = await body(request);
return json(response, 200, await lspManager.request(input.id, input.message));
}
if (request.method === 'POST' && request.url === '/api/lsp/notify') {
const input = await body(request);
return json(response, 200, lspManager.notify(input.id, input.message));
}
if (request.method === 'POST' && request.url === '/api/lsp/stop') {
return json(response, 200, await lspManager.stop((await body(request)).id));
}
if (request.method === 'POST' && request.url === '/api/community/items') {
const input = await body(request);
return json(response, 201, { item: await communityStore.add(input.type, input.item) });
}
if (request.method === 'PUT' && request.url === '/api/community/items') {
const input = await body(request);
return json(response, 200, { item: await communityStore.update(input.type, input.index, input.item) });
}
if (request.method === 'DELETE' && request.url === '/api/community/items') {
const input = await body(request);
return json(response, 200, { item: await communityStore.remove(input.type, input.index) });
}
if (request.method === 'POST' && request.url === '/api/models/start') {
return json(response, 200, await modelManager.start((await body(request)).id));
}
if (request.method === 'POST' && request.url === '/api/models/stop') {
const id = (await body(request)).id;
return json(response, 200, id ? await modelManager.stop(id) : (await modelManager.stopAll(), { status: 'stopped' }));
}
return json(response, 404, { error: 'not found' });
} catch (error) {
return json(response, 500, { error: 'local daemon error' });
}
});
server.listen(PORT, HOST, () => {
console.log(`AIDE local daemon listening on http://${HOST}:${PORT}`);
console.log(`workspace: ${WORKSPACE}`);
});