Skip to content

Commit cd43e84

Browse files
author
Juan Castaño
committed
Move edit logic into open AI file
1 parent b84248f commit cd43e84

File tree

2 files changed

+71
-65
lines changed

2 files changed

+71
-65
lines changed

app/api/generate/route.ts

Lines changed: 5 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// app/api/generate/route.ts
22
import { NextRequest, NextResponse } from 'next/server';
3-
import { generateApp, editApp } from '@/lib/openai';
3+
import { processAppRequest } from '@/lib/openai';
44
import { createSandbox } from '@/lib/e2b';
55
import { componentSchema } from '@/lib/schemas';
66
import { Benchify } from 'benchify';
@@ -12,27 +12,6 @@ const benchify = new Benchify({
1212
apiKey: process.env.BENCHIFY_API_KEY,
1313
});
1414

15-
const buggyCode = [
16-
{
17-
path: "src/App.tsx",
18-
content: `import React from 'react';
19-
20-
const App = () => {
21-
const message = "Hello World; // Missing closing quote
22-
const title = 'Welcome to my app';
23-
24-
return (
25-
<div>
26-
<h1>{title}</h1>
27-
<p>{message}</p>
28-
</div>
29-
);
30-
};
31-
32-
export default App;`
33-
}
34-
];
35-
3615
// Extended schema to support editing
3716
const extendedComponentSchema = componentSchema.extend({
3817
existingFiles: benchifyFileSchema.optional(),
@@ -41,18 +20,6 @@ const extendedComponentSchema = componentSchema.extend({
4120
useFixer: z.boolean().optional().default(false),
4221
});
4322

44-
// Helper function to merge updated files with existing files
45-
function mergeFiles(existingFiles: z.infer<typeof benchifyFileSchema>, updatedFiles: z.infer<typeof benchifyFileSchema>): z.infer<typeof benchifyFileSchema> {
46-
const existingMap = new Map(existingFiles.map(file => [file.path, file]));
47-
48-
// Apply updates
49-
updatedFiles.forEach(updatedFile => {
50-
existingMap.set(updatedFile.path, updatedFile);
51-
});
52-
53-
return Array.from(existingMap.values());
54-
}
55-
5623
export async function POST(request: NextRequest) {
5724
try {
5825
console.log('🚀 API route started');
@@ -80,31 +47,8 @@ export async function POST(request: NextRequest) {
8047
useFixer
8148
});
8249

83-
let filesToSandbox;
84-
85-
// Determine if this is an edit request or new generation
86-
if (existingFiles && editInstruction) {
87-
// Edit existing code (including error fixes)
88-
console.log('📝 Processing edit request...');
89-
console.log('Existing files:', existingFiles.map(f => ({ path: f.path, contentLength: f.content.length })));
90-
91-
const updatedFiles = await editApp(existingFiles, editInstruction);
92-
console.log('Updated files from AI:', updatedFiles.map(f => ({ path: f.path, contentLength: f.content.length })));
93-
94-
// Merge the updated files with the existing files
95-
filesToSandbox = mergeFiles(existingFiles, updatedFiles);
96-
console.log('Final merged files:', filesToSandbox.map(f => ({ path: f.path, contentLength: f.content.length })));
97-
} else {
98-
// Generate new app
99-
console.log('🆕 Processing new generation request...');
100-
if (useBuggyCode) {
101-
console.log('🐛 Using buggy code as requested');
102-
filesToSandbox = buggyCode;
103-
} else {
104-
console.log('🤖 Calling AI to generate app...');
105-
filesToSandbox = await generateApp(description);
106-
}
107-
}
50+
// Process the app request using centralized logic
51+
const filesToSandbox = await processAppRequest(description, existingFiles, editInstruction, useBuggyCode);
10852

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

@@ -115,7 +59,7 @@ export async function POST(request: NextRequest) {
11559
console.log('🔧 Running Benchify fixer...');
11660
try {
11761
const { data } = await benchify.fixer.run({
118-
files: filesToSandbox.map(file => ({
62+
files: filesToSandbox.map((file: { path: string; content: string }) => ({
11963
path: file.path,
12064
contents: file.content
12165
}))
@@ -126,7 +70,7 @@ export async function POST(request: NextRequest) {
12670

12771
if (success && diff) {
12872
console.log('✅ Fixer applied successfully');
129-
repairedFiles = filesToSandbox.map(file => {
73+
repairedFiles = filesToSandbox.map((file: { path: string; content: string }) => {
13074
const patchResult = applyPatch(file.content, diff);
13175
return {
13276
...file,

lib/openai.ts

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,25 @@ export async function generateApp(
5353
}
5454
}
5555

56-
// Edit existing application using AI SDK
56+
// Helper function to merge updated files with existing files
57+
function mergeFiles(existingFiles: z.infer<typeof benchifyFileSchema>, updatedFiles: z.infer<typeof benchifyFileSchema>): z.infer<typeof benchifyFileSchema> {
58+
const existingMap = new Map(existingFiles.map(file => [file.path, file]));
59+
60+
// Apply updates
61+
updatedFiles.forEach(updatedFile => {
62+
existingMap.set(updatedFile.path, updatedFile);
63+
});
64+
65+
return Array.from(existingMap.values());
66+
}
67+
68+
// Edit existing application using AI SDK and merge results
5769
export async function editApp(
5870
existingFiles: z.infer<typeof benchifyFileSchema>,
5971
editInstruction: string,
60-
): Promise<Array<{ path: string; content: string }>> {
72+
): Promise<z.infer<typeof benchifyFileSchema>> {
6173
console.log("Editing app with instruction: ", editInstruction);
74+
console.log('Existing files:', existingFiles.map(f => ({ path: f.path, contentLength: f.content.length })));
6275

6376
try {
6477
const { elementStream } = streamObject({
@@ -81,11 +94,60 @@ export async function editApp(
8194
throw new Error("Failed to generate updated files - received empty response");
8295
}
8396

84-
console.log("Generated updated files: ", updatedFiles);
97+
console.log("Generated updated files: ", updatedFiles.map(f => ({ path: f.path, contentLength: f.content.length })));
98+
99+
// Merge the updated files with the existing files
100+
const mergedFiles = mergeFiles(existingFiles, updatedFiles);
101+
console.log('Final merged files:', mergedFiles.map(f => ({ path: f.path, contentLength: f.content.length })));
85102

86-
return updatedFiles;
103+
return mergedFiles;
87104
} catch (error) {
88105
console.error('Error editing app:', error);
89106
throw error;
90107
}
108+
}
109+
110+
// Main function to handle both generation and editing
111+
export async function processAppRequest(
112+
description: string,
113+
existingFiles?: z.infer<typeof benchifyFileSchema>,
114+
editInstruction?: string,
115+
useBuggyCode: boolean = false
116+
): Promise<z.infer<typeof benchifyFileSchema>> {
117+
// Determine if this is an edit request or new generation
118+
if (existingFiles && editInstruction) {
119+
// Edit existing code (including error fixes)
120+
console.log('📝 Processing edit request...');
121+
return await editApp(existingFiles, editInstruction);
122+
} else {
123+
// Generate new app
124+
console.log('🆕 Processing new generation request...');
125+
if (useBuggyCode) {
126+
console.log('🐛 Using buggy code as requested');
127+
// Return the buggy code in the expected format
128+
return [
129+
{
130+
path: "src/App.tsx",
131+
content: `import React from 'react';
132+
133+
const App = () => {
134+
const message = "Hello World; // Missing closing quote
135+
const title = 'Welcome to my app';
136+
137+
return (
138+
<div>
139+
<h1>{title}</h1>
140+
<p>{message}</p>
141+
</div>
142+
);
143+
};
144+
145+
export default App;`
146+
}
147+
];
148+
} else {
149+
console.log('🤖 Calling AI to generate app...');
150+
return await generateApp(description);
151+
}
152+
}
91153
}

0 commit comments

Comments
 (0)