Skip to content

Add toggle to control buggy code and fixer usage #34

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-16-fixed_a_few_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
71 changes: 45 additions & 26 deletions app/api/generate/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ const benchify = new Benchify({
apiKey: process.env.BENCHIFY_API_KEY,
});

const debug = false;
const buggyCode = [
{
path: "src/App.tsx",
Expand All @@ -38,6 +37,8 @@ export default App;`
const extendedComponentSchema = componentSchema.extend({
existingFiles: benchifyFileSchema.optional(),
editInstruction: z.string().optional(),
useBuggyCode: z.boolean().optional().default(false),
useFixer: z.boolean().optional().default(false),
});

// Helper function to merge updated files with existing files
Expand Down Expand Up @@ -68,13 +69,15 @@ export async function POST(request: NextRequest) {
);
}

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

console.log('✅ Validation passed, API Request:', {
isEdit: !!(existingFiles && editInstruction),
filesCount: existingFiles?.length || 0,
editInstruction: editInstruction || 'none',
description: description || 'none'
description: description || 'none',
useBuggyCode,
useFixer
});

let filesToSandbox;
Expand All @@ -94,8 +97,8 @@ export async function POST(request: NextRequest) {
} else {
// Generate new app
console.log('🆕 Processing new generation request...');
if (debug) {
console.log('🐛 Debug mode: using buggy code');
if (useBuggyCode) {
console.log('🐛 Using buggy code as requested');
filesToSandbox = buggyCode;
} else {
console.log('🤖 Calling AI to generate app...');
Expand All @@ -105,28 +108,44 @@ export async function POST(request: NextRequest) {

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
// }))
// });

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
// };
// });
// }
// }

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

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

if (success && diff) {
console.log('✅ Fixer applied successfully');
repairedFiles = filesToSandbox.map(file => {
const patchResult = applyPatch(file.content, diff);
return {
...file,
content: typeof patchResult === 'string' ? patchResult : file.content
};
});
} else {
console.log('⚠️ Fixer ran but no fixes were applied');
}
} else {
console.log('⚠️ Fixer returned no data');
}
} catch (error) {
console.error('❌ Error running fixer:', error);
// Continue with original files if fixer fails
}
} else {
console.log('⏭️ Skipping fixer as requested');
}

console.log('🏗️ Creating sandbox...');
const sandboxResult = await createSandbox({ files: repairedFiles });
Expand Down
6 changes: 6 additions & 0 deletions app/chat/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ export default function ChatPage() {

const startGeneration = async (prompt: string) => {
try {
// Get toggle values from sessionStorage
const useBuggyCode = sessionStorage.getItem('useBuggyCode') === 'true';
const useFixer = sessionStorage.getItem('useFixer') === 'true';

const response = await fetch('/api/generate', {
method: 'POST',
headers: {
Expand All @@ -62,6 +66,8 @@ export default function ChatPage() {
type: 'component',
description: prompt,
preview: true,
useBuggyCode,
useFixer,
}),
});

Expand Down
6 changes: 6 additions & 0 deletions components/ui-builder/chat-interface.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ export function ChatInterface({ initialPrompt, currentFiles, onUpdateResult }: C
};
setMessages(prev => [...prev, thinkingMessage]);

// Get toggle values from sessionStorage
const useBuggyCode = sessionStorage.getItem('useBuggyCode') === 'true';
const useFixer = sessionStorage.getItem('useFixer') === 'true';

// Call the edit API
const response = await fetch('/api/generate', {
method: 'POST',
Expand All @@ -98,6 +102,8 @@ export function ChatInterface({ initialPrompt, currentFiles, onUpdateResult }: C
description: '', // Not used for edits
existingFiles: currentFiles,
editInstruction: editInstruction,
useBuggyCode,
useFixer,
}),
});

Expand Down
17 changes: 6 additions & 11 deletions components/ui-builder/error-display.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ ${errorDetails}

Please make the minimal changes necessary to resolve these errors while maintaining existing functionality.`;

// Get toggle values from sessionStorage
const useBuggyCode = sessionStorage.getItem('useBuggyCode') === 'true';
const useFixer = sessionStorage.getItem('useFixer') === 'true';

// Use the existing edit API
const response = await fetch('/api/generate', {
method: 'POST',
Expand All @@ -105,6 +109,8 @@ Please make the minimal changes necessary to resolve these errors while maintain
description: '',
existingFiles: currentFiles,
editInstruction: fixInstruction,
useBuggyCode,
useFixer,
}),
});

Expand Down Expand Up @@ -198,17 +204,6 @@ Please make the minimal changes necessary to resolve these errors while maintain
))}
</div>
</ScrollArea>

<div className="mt-6 p-4 bg-muted/50 rounded-lg">
<h4 className="text-sm font-medium mb-2">💡 Common Solutions:</h4>
<ul className="text-sm text-muted-foreground space-y-1">
<li>• Check for missing imports or typos in component names</li>
<li>• Verify that all props are properly typed</li>
<li>• Make sure all dependencies are correctly installed</li>
<li>• Try regenerating the component with more specific requirements</li>
{currentFiles && <li>• Use the &quot;Fix with AI&quot; button above for automatic error resolution</li>}
</ul>
</div>
</div>
</div>
);
Expand Down
75 changes: 73 additions & 2 deletions components/ui-builder/prompt-form.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// components/ui-builder/prompt-form.tsx
'use client';

import { useEffect } from 'react';
import { useRouter } from 'next/navigation';
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
Expand All @@ -15,11 +16,14 @@ import {
FormMessage,
} from "@/components/ui/form"
import { Textarea } from '@/components/ui/textarea';
import { Switch } from '@/components/ui/switch';

const formSchema = z.object({
description: z.string().min(10, {
message: "Description must be at least 10 characters.",
}),
useBuggyCode: z.boolean(),
useFixer: z.boolean(),
})

export function PromptForm() {
Expand All @@ -29,12 +33,30 @@ export function PromptForm() {
resolver: zodResolver(formSchema),
defaultValues: {
description: "",
useBuggyCode: false,
useFixer: false,
},
})

// Watch the useBuggyCode field to auto-populate description
const watchUseBuggyCode = form.watch('useBuggyCode');
const currentDescription = form.watch('description');

useEffect(() => {
const buggyCodeText = 'Create a simple React app with a title "Welcome to my app" and a Hello World message displayed in a div';

if (watchUseBuggyCode && currentDescription !== buggyCodeText) {
form.setValue('description', buggyCodeText);
} else if (!watchUseBuggyCode && currentDescription === buggyCodeText) {
form.setValue('description', '');
}
}, [watchUseBuggyCode]);

async function onSubmit(values: z.infer<typeof formSchema>) {
// Store the prompt in sessionStorage and navigate immediately
// Store the prompt and settings in sessionStorage and navigate immediately
sessionStorage.setItem('initialPrompt', values.description);
sessionStorage.setItem('useBuggyCode', values.useBuggyCode.toString());
sessionStorage.setItem('useFixer', values.useFixer.toString());
sessionStorage.removeItem('builderResult'); // Clear any previous result

// Navigate to the chat page immediately
Expand All @@ -43,7 +65,7 @@ export function PromptForm() {

return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
<FormField
control={form.control}
name="description"
Expand All @@ -61,6 +83,55 @@ export function PromptForm() {
</FormItem>
)}
/>

<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<FormField
control={form.control}
name="useBuggyCode"
render={({ field }) => (
<FormItem className="flex flex-row items-center justify-between rounded-lg border p-4">
<div className="space-y-0.5">
<FormLabel className="text-base">
Use Buggy Code
</FormLabel>
<div className="text-sm text-muted-foreground">
Use hardcoded code with issues for testing
</div>
</div>
<FormControl>
<Switch
checked={field.value}
onCheckedChange={field.onChange}
/>
</FormControl>
</FormItem>
)}
/>

<FormField
control={form.control}
name="useFixer"
render={({ field }) => (
<FormItem className="flex flex-row items-center justify-between rounded-lg border p-4">
<div className="space-y-0.5">
<FormLabel className="text-base">
Use Fixer
</FormLabel>
<div className="text-sm text-muted-foreground">
Apply Benchify fixer to repair code issues
</div>
</div>
<FormControl>
<Switch
checked={field.value}
onCheckedChange={field.onChange}
/>
</FormControl>
</FormItem>
)}
/>
</div>

<Button
type="submit"
className="w-full bg-primary text-primary-foreground hover:bg-primary/90"
Expand Down