Skip to content

Commit 00e6d31

Browse files
authored
Add toggle to control buggy code and fixer usage (#34)
### TL;DR Added debugging options to enable buggy code generation and code fixing capabilities. ### What changed? - Removed the hardcoded `debug` flag and replaced it with user-configurable options - Added two new parameters to the component schema: `useBuggyCode` and `useFixer` - Implemented the Benchify fixer functionality that was previously commented out - Added UI toggles in the prompt form for users to enable/disable these features - Added session storage to persist these settings across page navigation - Passed these settings through all API calls (new generation and edits) - Added detailed logging for the fixer process - Removed the "Common Solutions" section from the error display component - Auto-populates the description field with sample text when buggy code is enabled ### How to test? 1. Navigate to the prompt form and toggle "Use Buggy Code" on 2. Notice how the description field auto-populates with sample text 3. Toggle "Use Fixer" on to test the code repair functionality 4. Submit the form and observe the generated code 5. Check the console logs to verify the fixer is being called when enabled 6. Verify that these settings persist when navigating between pages ### Why make this change? This change provides developers with better debugging tools to test the application's error handling and code fixing capabilities. The toggles make it easy to generate intentionally buggy code for testing purposes and to evaluate the effectiveness of the Benchify fixer. This will help in development, testing, and demonstrating the application's resilience to code errors.
2 parents b260c55 + a193e27 commit 00e6d31

File tree

5 files changed

+136
-39
lines changed

5 files changed

+136
-39
lines changed

app/api/generate/route.ts

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ const benchify = new Benchify({
1212
apiKey: process.env.BENCHIFY_API_KEY,
1313
});
1414

15-
const debug = false;
1615
const buggyCode = [
1716
{
1817
path: "src/App.tsx",
@@ -38,6 +37,8 @@ export default App;`
3837
const extendedComponentSchema = componentSchema.extend({
3938
existingFiles: benchifyFileSchema.optional(),
4039
editInstruction: z.string().optional(),
40+
useBuggyCode: z.boolean().optional().default(false),
41+
useFixer: z.boolean().optional().default(false),
4142
});
4243

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

71-
const { description, existingFiles, editInstruction } = validationResult.data;
72+
const { description, existingFiles, editInstruction, useBuggyCode, useFixer } = validationResult.data;
7273

7374
console.log('✅ Validation passed, API Request:', {
7475
isEdit: !!(existingFiles && editInstruction),
7576
filesCount: existingFiles?.length || 0,
7677
editInstruction: editInstruction || 'none',
77-
description: description || 'none'
78+
description: description || 'none',
79+
useBuggyCode,
80+
useFixer
7881
});
7982

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

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

108-
// Repair the generated code using Benchify's API
109-
// const { data } = await benchify.fixer.run({
110-
// files: filesToSandbox.map(file => ({
111-
// path: file.path,
112-
// contents: file.content
113-
// }))
114-
// });
115-
116111
let repairedFiles = filesToSandbox;
117-
// if (data) {
118-
// const { success, diff } = data;
119-
120-
// if (success && diff) {
121-
// repairedFiles = filesToSandbox.map(file => {
122-
// const patchResult = applyPatch(file.content, diff);
123-
// return {
124-
// ...file,
125-
// content: typeof patchResult === 'string' ? patchResult : file.content
126-
// };
127-
// });
128-
// }
129-
// }
112+
113+
// Repair the generated code using Benchify's API if requested
114+
if (useFixer) {
115+
console.log('🔧 Running Benchify fixer...');
116+
try {
117+
const { data } = await benchify.fixer.run({
118+
files: filesToSandbox.map(file => ({
119+
path: file.path,
120+
contents: file.content
121+
}))
122+
});
123+
124+
if (data) {
125+
const { success, diff } = data;
126+
127+
if (success && diff) {
128+
console.log('✅ Fixer applied successfully');
129+
repairedFiles = filesToSandbox.map(file => {
130+
const patchResult = applyPatch(file.content, diff);
131+
return {
132+
...file,
133+
content: typeof patchResult === 'string' ? patchResult : file.content
134+
};
135+
});
136+
} else {
137+
console.log('⚠️ Fixer ran but no fixes were applied');
138+
}
139+
} else {
140+
console.log('⚠️ Fixer returned no data');
141+
}
142+
} catch (error) {
143+
console.error('❌ Error running fixer:', error);
144+
// Continue with original files if fixer fails
145+
}
146+
} else {
147+
console.log('⏭️ Skipping fixer as requested');
148+
}
130149

131150
console.log('🏗️ Creating sandbox...');
132151
const sandboxResult = await createSandbox({ files: repairedFiles });

app/chat/page.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ export default function ChatPage() {
5353

5454
const startGeneration = async (prompt: string) => {
5555
try {
56+
// Get toggle values from sessionStorage
57+
const useBuggyCode = sessionStorage.getItem('useBuggyCode') === 'true';
58+
const useFixer = sessionStorage.getItem('useFixer') === 'true';
59+
5660
const response = await fetch('/api/generate', {
5761
method: 'POST',
5862
headers: {
@@ -62,6 +66,8 @@ export default function ChatPage() {
6266
type: 'component',
6367
description: prompt,
6468
preview: true,
69+
useBuggyCode,
70+
useFixer,
6571
}),
6672
});
6773

components/ui-builder/chat-interface.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ export function ChatInterface({ initialPrompt, currentFiles, onUpdateResult }: C
8787
};
8888
setMessages(prev => [...prev, thinkingMessage]);
8989

90+
// Get toggle values from sessionStorage
91+
const useBuggyCode = sessionStorage.getItem('useBuggyCode') === 'true';
92+
const useFixer = sessionStorage.getItem('useFixer') === 'true';
93+
9094
// Call the edit API
9195
const response = await fetch('/api/generate', {
9296
method: 'POST',
@@ -98,6 +102,8 @@ export function ChatInterface({ initialPrompt, currentFiles, onUpdateResult }: C
98102
description: '', // Not used for edits
99103
existingFiles: currentFiles,
100104
editInstruction: editInstruction,
105+
useBuggyCode,
106+
useFixer,
101107
}),
102108
});
103109

components/ui-builder/error-display.tsx

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ ${errorDetails}
9494
9595
Please make the minimal changes necessary to resolve these errors while maintaining existing functionality.`;
9696

97+
// Get toggle values from sessionStorage
98+
const useBuggyCode = sessionStorage.getItem('useBuggyCode') === 'true';
99+
const useFixer = sessionStorage.getItem('useFixer') === 'true';
100+
97101
// Use the existing edit API
98102
const response = await fetch('/api/generate', {
99103
method: 'POST',
@@ -105,6 +109,8 @@ Please make the minimal changes necessary to resolve these errors while maintain
105109
description: '',
106110
existingFiles: currentFiles,
107111
editInstruction: fixInstruction,
112+
useBuggyCode,
113+
useFixer,
108114
}),
109115
});
110116

@@ -198,17 +204,6 @@ Please make the minimal changes necessary to resolve these errors while maintain
198204
))}
199205
</div>
200206
</ScrollArea>
201-
202-
<div className="mt-6 p-4 bg-muted/50 rounded-lg">
203-
<h4 className="text-sm font-medium mb-2">💡 Common Solutions:</h4>
204-
<ul className="text-sm text-muted-foreground space-y-1">
205-
<li>• Check for missing imports or typos in component names</li>
206-
<li>• Verify that all props are properly typed</li>
207-
<li>• Make sure all dependencies are correctly installed</li>
208-
<li>• Try regenerating the component with more specific requirements</li>
209-
{currentFiles && <li>• Use the &quot;Fix with AI&quot; button above for automatic error resolution</li>}
210-
</ul>
211-
</div>
212207
</div>
213208
</div>
214209
);

components/ui-builder/prompt-form.tsx

Lines changed: 73 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// components/ui-builder/prompt-form.tsx
22
'use client';
33

4+
import { useEffect } from 'react';
45
import { useRouter } from 'next/navigation';
56
import { zodResolver } from "@hookform/resolvers/zod"
67
import { useForm } from "react-hook-form"
@@ -15,11 +16,14 @@ import {
1516
FormMessage,
1617
} from "@/components/ui/form"
1718
import { Textarea } from '@/components/ui/textarea';
19+
import { Switch } from '@/components/ui/switch';
1820

1921
const formSchema = z.object({
2022
description: z.string().min(10, {
2123
message: "Description must be at least 10 characters.",
2224
}),
25+
useBuggyCode: z.boolean(),
26+
useFixer: z.boolean(),
2327
})
2428

2529
export function PromptForm() {
@@ -29,12 +33,30 @@ export function PromptForm() {
2933
resolver: zodResolver(formSchema),
3034
defaultValues: {
3135
description: "",
36+
useBuggyCode: false,
37+
useFixer: false,
3238
},
3339
})
3440

41+
// Watch the useBuggyCode field to auto-populate description
42+
const watchUseBuggyCode = form.watch('useBuggyCode');
43+
const currentDescription = form.watch('description');
44+
45+
useEffect(() => {
46+
const buggyCodeText = 'Create a simple React app with a title "Welcome to my app" and a Hello World message displayed in a div';
47+
48+
if (watchUseBuggyCode && currentDescription !== buggyCodeText) {
49+
form.setValue('description', buggyCodeText);
50+
} else if (!watchUseBuggyCode && currentDescription === buggyCodeText) {
51+
form.setValue('description', '');
52+
}
53+
}, [watchUseBuggyCode]);
54+
3555
async function onSubmit(values: z.infer<typeof formSchema>) {
36-
// Store the prompt in sessionStorage and navigate immediately
56+
// Store the prompt and settings in sessionStorage and navigate immediately
3757
sessionStorage.setItem('initialPrompt', values.description);
58+
sessionStorage.setItem('useBuggyCode', values.useBuggyCode.toString());
59+
sessionStorage.setItem('useFixer', values.useFixer.toString());
3860
sessionStorage.removeItem('builderResult'); // Clear any previous result
3961

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

4466
return (
4567
<Form {...form}>
46-
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
68+
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
4769
<FormField
4870
control={form.control}
4971
name="description"
@@ -61,6 +83,55 @@ export function PromptForm() {
6183
</FormItem>
6284
)}
6385
/>
86+
87+
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
88+
<FormField
89+
control={form.control}
90+
name="useBuggyCode"
91+
render={({ field }) => (
92+
<FormItem className="flex flex-row items-center justify-between rounded-lg border p-4">
93+
<div className="space-y-0.5">
94+
<FormLabel className="text-base">
95+
Use Buggy Code
96+
</FormLabel>
97+
<div className="text-sm text-muted-foreground">
98+
Use hardcoded code with issues for testing
99+
</div>
100+
</div>
101+
<FormControl>
102+
<Switch
103+
checked={field.value}
104+
onCheckedChange={field.onChange}
105+
/>
106+
</FormControl>
107+
</FormItem>
108+
)}
109+
/>
110+
111+
<FormField
112+
control={form.control}
113+
name="useFixer"
114+
render={({ field }) => (
115+
<FormItem className="flex flex-row items-center justify-between rounded-lg border p-4">
116+
<div className="space-y-0.5">
117+
<FormLabel className="text-base">
118+
Use Fixer
119+
</FormLabel>
120+
<div className="text-sm text-muted-foreground">
121+
Apply Benchify fixer to repair code issues
122+
</div>
123+
</div>
124+
<FormControl>
125+
<Switch
126+
checked={field.value}
127+
onCheckedChange={field.onChange}
128+
/>
129+
</FormControl>
130+
</FormItem>
131+
)}
132+
/>
133+
</div>
134+
64135
<Button
65136
type="submit"
66137
className="w-full bg-primary text-primary-foreground hover:bg-primary/90"

0 commit comments

Comments
 (0)