File size: 2,918 Bytes
3c7404b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | import { exec, execFile } from 'node:child_process';
import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import { promisify } from 'node:util';
const execAsync = promisify(exec);
const execFileAsync = promisify(execFile);
const AGENT_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..', '..');
const HF_PULL_SCRIPT = resolve(AGENT_ROOT, 'scripts', 'hf_pull_script.py');
const RUN_OPENCODE_SCRIPT = resolve(AGENT_ROOT, 'scripts', 'run_opencode.py');
export type BackendAgentAction =
| { action: 'agent.help' }
| { action: 'sin.backend.health' }
| { action: 'sin.backend.code.generate'; prompt: string; contextDir?: string }
| { action: 'sin.backend.code.review'; targetDir: string };
export async function executeBackendAgentAction(action: BackendAgentAction): Promise<unknown> {
switch (action.action) {
case 'agent.help':
return {
ok: true,
agent: 'sin-backend',
mandate: 'CEO Elite Architect for 2026 Supabase + A2A Micro-Agent backends.',
actions: ['sin.backend.health', 'sin.backend.code.generate', 'sin.backend.code.review'],
};
case 'sin.backend.health':
return {
ok: true,
agent: 'sin-backend',
primaryModel: 'opencode/qwen3.6-plus-free',
fallbackModel: 'opencode/nemotron-3-super-free',
team: 'Team - Coding',
status: 'Elite 2026 Backend Architect Online',
};
case 'sin.backend.code.generate':
return await executeOpenCode(action.prompt, action.contextDir);
case 'sin.backend.code.review':
return await executeOpenCode(`Review the backend in ${action.targetDir} according to 2026 A2A and Supabase-native architectural standards. Forbid monolithic REST APIs.`, action.targetDir);
}
}
async function executeOpenCode(prompt: string, dir?: string) {
await execFileAsync('python3', [HF_PULL_SCRIPT], { cwd: AGENT_ROOT }).catch(() => {
console.warn('Rotator token pull failed, using cached auth if available');
});
const options = dir ? { cwd: dir } : {};
try {
const { stdout } = await execFileAsync('python3', [RUN_OPENCODE_SCRIPT, '--model', 'opencode/qwen3.6-plus-free', '--agent', 'sin-executor-solo', '--cwd', dir || AGENT_ROOT, '--timeout-sec', '900', '--prompt', prompt], { cwd: AGENT_ROOT });
const result = JSON.parse(stdout) as { ok: boolean; stdout: string; stderr: string; timeout: boolean; returncode: number };
if (!result.ok) {
throw new Error(result.timeout ? `${result.stderr || result.stdout || 'opencode_timeout'}\nagent_timeout:900s` : (result.stderr || result.stdout || `opencode_returncode_${result.returncode}`));
}
return {
ok: true,
expertAnalysis: result.stdout,
warnings: result.stderr || undefined,
};
} catch (error: any) {
throw new Error(`Master Architect Execution Failed: ${error.message}`);
}
}
|