feat: implement self-correcting compile loop (Ralph Loop) inside cloud agent runner
This commit is contained in:
@@ -15,6 +15,50 @@ import { resolvePrompt } from "./prompts/loader";
|
||||
|
||||
const MAX_TURNS = 45;
|
||||
|
||||
function runBuildVerification(
|
||||
repoRoot: string,
|
||||
appPath: string,
|
||||
): { success: boolean; error?: string } {
|
||||
const fs = require("fs") as typeof import("fs");
|
||||
const path = require("path") as typeof import("path");
|
||||
const { execSync } = require("child_process");
|
||||
|
||||
const absoluteAppPath = path.join(repoRoot, appPath);
|
||||
const pkgJsonPath = path.join(absoluteAppPath, "package.json");
|
||||
|
||||
if (!fs.existsSync(pkgJsonPath)) {
|
||||
return { success: true }; // No package.json, skip build check
|
||||
}
|
||||
|
||||
try {
|
||||
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, "utf8"));
|
||||
// Only verify if there is an explicit build script
|
||||
if (!pkg.scripts || !pkg.scripts.build) {
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
console.log(
|
||||
`[Ralph Loop] Running automatic build verification: npm run build inside ${absoluteAppPath}...`,
|
||||
);
|
||||
// Run npm run build with a 45s timeout to prevent hanging
|
||||
execSync("npm run build", {
|
||||
cwd: absoluteAppPath,
|
||||
stdio: "pipe",
|
||||
timeout: 45000,
|
||||
});
|
||||
return { success: true };
|
||||
} catch (err: any) {
|
||||
const stderr = err.stderr
|
||||
? err.stderr.toString()
|
||||
: err.message || String(err);
|
||||
console.warn(`[Ralph Loop] Build verification failed:`, stderr);
|
||||
return {
|
||||
success: false,
|
||||
error: stderr.slice(-3000), // Cap the log length to avoid flooding the prompt context
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export interface OutputLine {
|
||||
ts: string;
|
||||
type: "step" | "stdout" | "stderr" | "info" | "error" | "done";
|
||||
@@ -354,6 +398,37 @@ Do NOT run git commit or git push — the platform handles committing after you
|
||||
continue;
|
||||
}
|
||||
|
||||
// ── Cloud Build Verification (Ralph Loop integration) ──
|
||||
if (opts.repoRoot && ralphIteration < 3) {
|
||||
await emit({
|
||||
ts: now(),
|
||||
type: "info",
|
||||
text: "🔍 [Ralph Loop] Initiating automatic build verification...",
|
||||
});
|
||||
|
||||
const verification = runBuildVerification(opts.repoRoot, opts.appPath);
|
||||
if (!verification.success) {
|
||||
ralphIteration++;
|
||||
await emit({
|
||||
ts: now(),
|
||||
type: "error",
|
||||
text: `❌ [Ralph Loop] Build verification failed (iteration ${ralphIteration}/3). Feeding compilation errors back to the model...`,
|
||||
});
|
||||
|
||||
history.push({
|
||||
role: "user",
|
||||
content: `Your previous edits completed, but the project's build check failed with compilation errors. Please fix these errors immediately so the build compiles clean:\n\n\`\`\`text\n${verification.error}\n\`\`\``,
|
||||
});
|
||||
continue;
|
||||
} else {
|
||||
await emit({
|
||||
ts: now(),
|
||||
type: "info",
|
||||
text: "🟢 [Ralph Loop] Build verification passed successfully! 0 errors.",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// If fully complete, trigger auto-commit and finish
|
||||
if (opts.autoApprove) {
|
||||
await autoCommitAndDeploy(opts, task, emit);
|
||||
|
||||
Reference in New Issue
Block a user