Skip to content

Fixed a few errors #33

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: 06-13-fix_build_errors
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 33 additions & 25 deletions app/api/generate/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const benchify = new Benchify({
apiKey: process.env.BENCHIFY_API_KEY,
});

const debug = true;
const debug = false;
const buggyCode = [
{
path: "src/App.tsx",
Expand Down Expand Up @@ -54,12 +54,14 @@ function mergeFiles(existingFiles: z.infer<typeof benchifyFileSchema>, updatedFi

export async function POST(request: NextRequest) {
try {
console.log('🚀 API route started');
const body = await request.json();

// Validate the request using extended schema
const validationResult = extendedComponentSchema.safeParse(body);

if (!validationResult.success) {
console.log('❌ Validation failed:', validationResult.error.format());
return NextResponse.json(
{ error: 'Invalid request format', details: validationResult.error.format() },
{ status: 400 }
Expand All @@ -68,7 +70,7 @@ export async function POST(request: NextRequest) {

const { description, existingFiles, editInstruction } = validationResult.data;

console.log('API Request:', {
console.log('✅ Validation passed, API Request:', {
isEdit: !!(existingFiles && editInstruction),
filesCount: existingFiles?.length || 0,
editInstruction: editInstruction || 'none',
Expand All @@ -80,7 +82,7 @@ export async function POST(request: NextRequest) {
// Determine if this is an edit request or new generation
if (existingFiles && editInstruction) {
// Edit existing code (including error fixes)
console.log('Processing edit request...');
console.log('📝 Processing edit request...');
console.log('Existing files:', existingFiles.map(f => ({ path: f.path, contentLength: f.content.length })));

const updatedFiles = await editApp(existingFiles, editInstruction);
Expand All @@ -91,38 +93,44 @@ export async function POST(request: NextRequest) {
console.log('Final merged files:', filesToSandbox.map(f => ({ path: f.path, contentLength: f.content.length })));
} else {
// Generate new app
console.log('Processing new generation request...');
console.log('🆕 Processing new generation request...');
if (debug) {
console.log('🐛 Debug mode: using buggy code');
filesToSandbox = buggyCode;
} else {
console.log('🤖 Calling AI to generate app...');
filesToSandbox = await generateApp(description);
}
}

console.log('📦 Files ready for sandbox:', filesToSandbox.length);

// Repair the generated code using Benchify's API
const { data } = await benchify.fixer.run({
files: filesToSandbox.map(file => ({
path: file.path,
contents: file.content
}))
});
// const { data } = await benchify.fixer.run({
// files: filesToSandbox.map(file => ({
// path: file.path,
// contents: file.content
// }))
// });

let repairedFiles = filesToSandbox;
if (data) {
const { success, diff } = data;

if (success && diff) {
repairedFiles = filesToSandbox.map(file => {
const patchResult = applyPatch(file.content, diff);
return {
...file,
content: typeof patchResult === 'string' ? patchResult : file.content
};
});
}
}

// if (data) {
// const { success, diff } = data;

// if (success && diff) {
// repairedFiles = filesToSandbox.map(file => {
// const patchResult = applyPatch(file.content, diff);
// return {
// ...file,
// content: typeof patchResult === 'string' ? patchResult : file.content
// };
// });
// }
// }

console.log('🏗️ Creating sandbox...');
const sandboxResult = await createSandbox({ files: repairedFiles });
console.log('✅ Sandbox created successfully');

// Return the results to the client
return NextResponse.json({
Expand All @@ -135,7 +143,7 @@ export async function POST(request: NextRequest) {
...(editInstruction && { editInstruction }),
});
} catch (error) {
console.error('Error generating app:', error);
console.error('💥 Error in API route:', error);
return NextResponse.json(
{
error: 'Failed to generate app',
Expand Down
99 changes: 5 additions & 94 deletions lib/e2b.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,22 +154,17 @@ export async function createSandbox({ files }: { files: z.infer<typeof benchifyF

console.log('=== COMPILATION ERROR CHECK ===');

// Try multiple approaches to detect compilation errors
// Simplified approach - just try one quick check
try {
// Approach 1: Try to build the project
console.log('Trying npm run build...');
const buildCheck = await sandbox.commands.run('cd /app && timeout 10s npm run build 2>&1 || true');
console.log('Build check output:', buildCheck.stdout);
console.log('Build check stderr:', buildCheck.stderr);
console.log('Trying quick build check...');
const buildCheck = await sandbox.commands.run('cd /app && timeout 5s npm run build 2>&1 || true');
console.log('Build check output:', buildCheck.stdout?.substring(0, 500));

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ File Transformation and Writing

Ensure that input files are correctly transformed and written into the sandbox, adhering to the necessary transformation rules.

Outcome Example Input # Inputs % of Total
superjson.parse('{"json":[[[{"path":"a","conten... view full input 200 100.0%

view all inputs
The property-based test has passed, ensuring that input files are transformed and written into the sandbox, adhering to the transformation rules. The input files, [{"path":"a","content":"arguments"}], were successfully processed and transformed, resulting in no errors or failures during the dev server start and build process.

Unit Tests
// Unit Test for "File Transformation and Writing": Ensure that input files are correctly transformed and written into the sandbox, adhering to the necessary transformation rules.
function benchify_s(s) {
    return s.replace(/[^a-zA-Z0-9]/g, 'a');
}

it('benchify_s_exec_test_passing_0', () => {
  const args = superjson.parse(
    '{"json":[[[{"path":"a","content":"arguments"}]]]}',
  );

  benchify_s(...args);
});

if (buildCheck.stdout && (
buildCheck.stdout.includes('Unterminated string constant') ||
buildCheck.stdout.includes('SyntaxError') ||
buildCheck.stdout.includes('Unexpected token') ||
buildCheck.stdout.includes('Parse error') ||
buildCheck.stdout.includes('[plugin:vite:') ||
buildCheck.stdout.includes('Transform failed') ||
buildCheck.stdout.includes('Build failed')
buildCheck.stdout.includes('[plugin:vite:')
)) {
hasCompilationError = true;
compilationErrorOutput = buildCheck.stdout;
Expand All @@ -179,93 +174,9 @@ export async function createSandbox({ files }: { files: z.infer<typeof benchifyF
console.log('Build check failed:', buildError);
}

// Approach 2: Try to check TypeScript compilation
if (!hasCompilationError) {
try {
console.log('Trying tsc --noEmit...');
const tscCheck = await sandbox.commands.run('cd /app && timeout 10s npx tsc --noEmit 2>&1 || true');
console.log('TypeScript check output:', tscCheck.stdout);
console.log('TypeScript check stderr:', tscCheck.stderr);

if (tscCheck.stdout && (
tscCheck.stdout.includes('error TS') ||
tscCheck.stdout.includes('Unterminated string constant') ||
tscCheck.stdout.includes('SyntaxError')
)) {
hasCompilationError = true;
compilationErrorOutput = tscCheck.stdout;
console.log('✅ Found compilation error in TypeScript check');
}
} catch (tscError) {
console.log('TypeScript check failed:', tscError);
}
}

// Approach 3: Try to parse files directly with Babel/ESLint
if (!hasCompilationError) {
try {
console.log('Trying to parse main files...');
const parseCheck = await sandbox.commands.run('cd /app && timeout 10s npx babel src/App.tsx --presets=@babel/preset-typescript 2>&1 || true');
console.log('Parse check output:', parseCheck.stdout);
console.log('Parse check stderr:', parseCheck.stderr);

if (parseCheck.stderr && (
parseCheck.stderr.includes('Unterminated string constant') ||
parseCheck.stderr.includes('SyntaxError') ||
parseCheck.stderr.includes('Unexpected token')
)) {
hasCompilationError = true;
compilationErrorOutput = parseCheck.stderr;
console.log('✅ Found compilation error in parse check');
}
} catch (parseError) {
console.log('Parse check failed:', parseError);
}
}

// Approach 4: Check if the dev server is actually serving errors
if (!hasCompilationError) {
try {
console.log('Checking dev server response for errors...');
const responseCheck = await sandbox.commands.run('cd /app && timeout 5s curl -s http://localhost:5173 2>&1 || true');
console.log('Response check output:', responseCheck.stdout);

if (responseCheck.stdout && (
responseCheck.stdout.includes('SyntaxError') ||
responseCheck.stdout.includes('Unterminated string') ||
responseCheck.stdout.includes('Parse error') ||
responseCheck.stdout.includes('Transform failed')
)) {
hasCompilationError = true;
compilationErrorOutput = responseCheck.stdout;
console.log('✅ Found compilation error in dev server response');
}
} catch (responseError) {
console.log('Response check failed:', responseError);
}
}

// Approach 5: Check Vite logs more thoroughly
if (!hasCompilationError) {
try {
console.log('Checking for Vite process logs...');
const viteLogsCheck = await sandbox.commands.run('cd /app && ps aux | grep vite');
console.log('Vite processes:', viteLogsCheck.stdout);

// Try to get logs from the running Vite process
const viteLogCheck = await sandbox.commands.run('cd /app && timeout 3s strace -p $(pgrep -f "vite --host") 2>&1 | head -20 || true');
console.log('Vite process trace:', viteLogCheck.stdout);
} catch (viteError) {
console.log('Vite log check failed:', viteError);
}
}

console.log('=== COMPILATION ERROR CHECK SUMMARY ===');
console.log('Has compilation error:', hasCompilationError);
console.log('Compilation error output length:', compilationErrorOutput.length);
if (compilationErrorOutput) {
console.log('Compilation error preview:', compilationErrorOutput.substring(0, 500));
}

console.log('Dev server started, output checked');
console.log('Total build errors found:', buildErrors.length);
Expand Down
17 changes: 14 additions & 3 deletions lib/prompts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,26 @@ IMPORTANT: Only generate these application files:
- src/App.tsx (main app component)
- src/index.css (with Tailwind imports)
- src/components/* (your React components)
- package.json (only for additional dependencies you need)

DO NOT generate configuration files like:
The following are already provided in the template and should NOT be generated:
- package.json (already includes react, react-dom, vite, tailwindcss, @tailwindcss/vite, typescript)
- vite.config.ts
- tsconfig files
- eslint configs
- index.html

These configuration files are already part of the template.
Only generate a package.json if you need additional dependencies beyond:
- react, react-dom (UI framework)
- vite, @vitejs/plugin-react (build tool)
- tailwindcss, @tailwindcss/vite (styling)
- typescript (type checking)

If you do need additional packages, generate a minimal package.json with only:
{
"dependencies": {
"package-name": "version"
}
}

RESPONSE FORMAT:
You must return a valid JSON array of file objects. Each file object must have exactly this structure:
Expand Down