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;
|
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 {
|
export interface OutputLine {
|
||||||
ts: string;
|
ts: string;
|
||||||
type: "step" | "stdout" | "stderr" | "info" | "error" | "done";
|
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;
|
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 fully complete, trigger auto-commit and finish
|
||||||
if (opts.autoApprove) {
|
if (opts.autoApprove) {
|
||||||
await autoCommitAndDeploy(opts, task, emit);
|
await autoCommitAndDeploy(opts, task, emit);
|
||||||
|
|||||||
Reference in New Issue
Block a user