Skip to content

Commit 4989894

Browse files
authored
Add fix with AI functionality BEN-1080 (#30)
### TL;DR Added an "Fix with AI" feature that automatically resolves build errors in generated UI components. ### What changed? - Added a "Fix with AI" button to the error display component that sends detected errors to the API for automatic fixing - Created a new `handleUpdateResult` function in the chat page to centralize result update logic - Connected the error fixing flow to the main application by passing the necessary props and callbacks - Enabled debug mode in the generate route - Added clarifying comment about error fixes in the edit request handling code - Improved error display UI with better guidance for users ### How to test? 1. Generate a UI component that produces build errors 2. When errors appear, click the "Fix with AI" button in the error display 3. Verify that the system attempts to fix the errors and updates the component code 4. Check that the fixed code is properly displayed and the errors are resolved ### Why make this change? This feature improves the user experience by providing an automated way to fix build errors without requiring manual intervention. Users can now resolve technical issues with a single click rather than having to understand and fix complex code problems themselves, making the tool more accessible to users with varying levels of technical expertise.
2 parents be0391c + f262d09 commit 4989894

File tree

5 files changed

+109
-14
lines changed

5 files changed

+109
-14
lines changed

app/api/generate/route.ts

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

15-
const debug = false;
15+
const debug = true;
1616
const buggyCode = [
1717
{
1818
path: "src/App.tsx",
@@ -79,7 +79,7 @@ export async function POST(request: NextRequest) {
7979

8080
// Determine if this is an edit request or new generation
8181
if (existingFiles && editInstruction) {
82-
// Edit existing code
82+
// Edit existing code (including error fixes)
8383
console.log('Processing edit request...');
8484
console.log('Existing files:', existingFiles.map(f => ({ path: f.path, contentLength: f.content.length })));
8585

app/chat/page.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ export default function ChatPage() {
8282
}
8383
};
8484

85+
const handleUpdateResult = (updatedResult: GenerationResult) => {
86+
setResult(updatedResult);
87+
// Save updated result to sessionStorage
88+
sessionStorage.setItem('builderResult', JSON.stringify(updatedResult));
89+
};
90+
8591
// Show loading spinner if we don't have prompt yet
8692
if (!initialPrompt) {
8793
return (
@@ -101,11 +107,7 @@ export default function ChatPage() {
101107
<ChatInterface
102108
initialPrompt={initialPrompt}
103109
currentFiles={result?.repairedFiles || result?.originalFiles}
104-
onUpdateResult={(updatedResult) => {
105-
setResult(updatedResult);
106-
// Save updated result to sessionStorage
107-
sessionStorage.setItem('builderResult', JSON.stringify(updatedResult));
108-
}}
110+
onUpdateResult={handleUpdateResult}
109111
/>
110112
</div>
111113

@@ -118,6 +120,7 @@ export default function ChatPage() {
118120
prompt={initialPrompt}
119121
buildErrors={result?.buildErrors}
120122
hasErrors={result?.hasErrors}
123+
onFixComplete={handleUpdateResult}
121124
/>
122125
</div>
123126
</div>

components/ui-builder/error-display.tsx

Lines changed: 91 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
'use client';
22

3-
import { AlertCircle, Code, FileX, Terminal } from 'lucide-react';
3+
import { useState } from 'react';
4+
import { AlertCircle, Code, FileX, Terminal, Wand2 } from 'lucide-react';
45
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
56
import { Badge } from '@/components/ui/badge';
7+
import { Button } from '@/components/ui/button';
68
import { ScrollArea } from '@/components/ui/scroll-area';
9+
import { benchifyFileSchema } from '@/lib/schemas';
10+
import { z } from 'zod';
711

812
interface BuildError {
913
type: 'typescript' | 'build' | 'runtime';
@@ -15,9 +19,13 @@ interface BuildError {
1519

1620
interface ErrorDisplayProps {
1721
errors: BuildError[];
22+
currentFiles?: z.infer<typeof benchifyFileSchema>;
23+
onFixComplete?: (result: any) => void;
1824
}
1925

20-
export function ErrorDisplay({ errors }: ErrorDisplayProps) {
26+
export function ErrorDisplay({ errors, currentFiles, onFixComplete }: ErrorDisplayProps) {
27+
const [isFixing, setIsFixing] = useState(false);
28+
2129
const getErrorIcon = (type: BuildError['type']) => {
2230
switch (type) {
2331
case 'typescript':
@@ -52,15 +60,94 @@ export function ErrorDisplay({ errors }: ErrorDisplayProps) {
5260
return acc;
5361
}, {} as Record<string, BuildError[]>);
5462

63+
const handleFixWithAI = async () => {
64+
if (!currentFiles || errors.length === 0 || isFixing) return;
65+
66+
setIsFixing(true);
67+
68+
try {
69+
// Format errors into an edit instruction
70+
const errorDetails = errors.map(error => {
71+
let errorInfo = `${error.type.toUpperCase()} ERROR: ${error.message}`;
72+
if (error.file) {
73+
errorInfo += ` (in ${error.file}`;
74+
if (error.line) errorInfo += ` at line ${error.line}`;
75+
if (error.column) errorInfo += `, column ${error.column}`;
76+
errorInfo += ')';
77+
}
78+
return errorInfo;
79+
}).join('\n\n');
80+
81+
const fixInstruction = `Fix the following build errors:
82+
83+
${errorDetails}
84+
85+
Please make the minimal changes necessary to resolve these errors while maintaining existing functionality.`;
86+
87+
// Use the existing edit API
88+
const response = await fetch('/api/generate', {
89+
method: 'POST',
90+
headers: {
91+
'Content-Type': 'application/json',
92+
},
93+
body: JSON.stringify({
94+
type: 'component',
95+
description: '',
96+
existingFiles: currentFiles,
97+
editInstruction: fixInstruction,
98+
}),
99+
});
100+
101+
if (!response.ok) {
102+
throw new Error('Failed to fix errors with AI');
103+
}
104+
105+
const fixResult = await response.json();
106+
107+
// Notify parent component of the fix result
108+
if (onFixComplete) {
109+
onFixComplete(fixResult);
110+
}
111+
112+
} catch (error) {
113+
console.error('Error fixing with AI:', error);
114+
// Could add error toast here
115+
} finally {
116+
setIsFixing(false);
117+
}
118+
};
119+
55120
return (
56121
<div className="w-full h-full flex items-center justify-center rounded-md border bg-background p-6">
57122
<div className="w-full max-w-2xl">
58123
<div className="text-center mb-6">
59124
<AlertCircle className="h-12 w-12 text-destructive mx-auto mb-4" />
60125
<h3 className="text-lg font-semibold mb-2">Build Errors Detected</h3>
61-
<p className="text-muted-foreground text-sm">
126+
<p className="text-muted-foreground text-sm mb-4">
62127
Your project has some issues that need to be fixed before it can run properly.
63128
</p>
129+
130+
{/* Fix with AI Button */}
131+
{currentFiles && (
132+
<Button
133+
onClick={handleFixWithAI}
134+
disabled={isFixing}
135+
className="mb-4"
136+
size="sm"
137+
>
138+
{isFixing ? (
139+
<>
140+
<div className="animate-spin rounded-full h-4 w-4 border-b-2 border-current mr-2" />
141+
Fixing with AI...
142+
</>
143+
) : (
144+
<>
145+
<Wand2 className="h-4 w-4 mr-2" />
146+
Fix with AI
147+
</>
148+
)}
149+
</Button>
150+
)}
64151
</div>
65152

66153
<ScrollArea className="max-h-96">
@@ -109,6 +196,7 @@ export function ErrorDisplay({ errors }: ErrorDisplayProps) {
109196
<li>• Verify that all props are properly typed</li>
110197
<li>• Make sure all dependencies are correctly installed</li>
111198
<li>• Try regenerating the component with more specific requirements</li>
199+
{currentFiles && <li>• Use the "Fix with AI" button above for automatic error resolution</li>}
112200
</ul>
113201
</div>
114202
</div>

components/ui-builder/preview-card.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ interface PreviewCardProps {
5252
prompt?: string;
5353
buildErrors?: BuildError[];
5454
hasErrors?: boolean;
55+
onFixComplete?: (result: any) => void;
5556
}
5657

5758
export function PreviewCard({
@@ -60,7 +61,8 @@ export function PreviewCard({
6061
isGenerating = false,
6162
prompt,
6263
buildErrors = [],
63-
hasErrors = false
64+
hasErrors = false,
65+
onFixComplete
6466
}: PreviewCardProps) {
6567
const files = code || [];
6668
const [currentStep, setCurrentStep] = useState(0);
@@ -147,7 +149,11 @@ export function PreviewCard({
147149
</div>
148150
) : hasErrors && buildErrors.length > 0 ? (
149151
// Show build errors if there are any
150-
<ErrorDisplay errors={buildErrors} />
152+
<ErrorDisplay
153+
errors={buildErrors}
154+
currentFiles={files}
155+
onFixComplete={onFixComplete}
156+
/>
151157
) : previewUrl ? (
152158
// Show the actual preview iframe when ready
153159
<div className="w-full h-full overflow-hidden rounded-md border bg-background">

lib/openai.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ const fileSchema = z.object({
1717
content: z.string()
1818
});
1919

20-
21-
2220
// Generate a new application using AI SDK
2321
export async function generateApp(
2422
description: string,

0 commit comments

Comments
 (0)