@@ -3,7 +3,6 @@ import type { NextRequest } from "next/server";
33import { NextResponse } from "next/server" ;
44import OpenAI from "openai" ;
55
6- import { MODELS } from "@/lib/providers" ;
76import {
87 DIVIDER ,
98 FOLLOW_UP_SYSTEM_PROMPT ,
@@ -14,7 +13,7 @@ import {
1413
1514export async function POST ( request : NextRequest ) {
1615 const body = await request . json ( ) ;
17- const { prompt, model, redesignMarkdown, html, apiKey, customModel , baseUrl } = body ;
16+ const { prompt, model, redesignMarkdown, html, apiKey, baseUrl } = body ;
1817
1918 const openai = new OpenAI ( {
2019 apiKey : apiKey || process . env . OPENAI_API_KEY || "" ,
@@ -28,23 +27,11 @@ export async function POST(request: NextRequest) {
2827 ) ;
2928 }
3029
31- const selectedModel = MODELS . find (
32- ( m ) => m . value === model || m . label === model
33- ) ;
34- if ( ! selectedModel ) {
35- return NextResponse . json (
36- { ok : false , error : "Invalid model selected" } ,
37- { status : 400 }
38- ) ;
39- }
40-
4130 try {
42- // Create a stream response
4331 const encoder = new TextEncoder ( ) ;
4432 const stream = new TransformStream ( ) ;
4533 const writer = stream . writable . getWriter ( ) ;
4634
47- // Start the response
4835 const response = new NextResponse ( stream . readable , {
4936 headers : {
5037 "Content-Type" : "text/plain; charset=utf-8" ,
@@ -57,12 +44,10 @@ export async function POST(request: NextRequest) {
5744 let completeResponse = "" ;
5845 try {
5946 const chatCompletion = await openai . chat . completions . create ( {
60- model : customModel || selectedModel . value ,
47+ model,
48+ stream : true ,
6149 messages : [
62- {
63- role : "system" ,
64- content : INITIAL_SYSTEM_PROMPT ,
65- } ,
50+ { role : "system" , content : INITIAL_SYSTEM_PROMPT } ,
6651 {
6752 role : "user" ,
6853 content : redesignMarkdown
@@ -72,16 +57,19 @@ export async function POST(request: NextRequest) {
7257 : prompt ,
7358 } ,
7459 ] ,
75- stream : true ,
7660 } ) ;
7761
7862 for await ( const chunk of chatCompletion ) {
7963 const content = chunk . choices [ 0 ] ?. delta ?. content || "" ;
80- await writer . write ( encoder . encode ( content ) ) ;
64+ if ( ! content ) continue ;
8165 completeResponse += content ;
82- if ( completeResponse . includes ( "</html>" ) ) {
83- break ;
84- }
66+ await writer . write ( encoder . encode ( content ) ) ;
67+ }
68+
69+ if ( ! completeResponse . trim ( ) ) {
70+ await writer . write (
71+ encoder . encode ( "\n[ERROR] Model returned empty response.\n" )
72+ ) ;
8573 }
8674 } catch ( error : any ) {
8775 await writer . write (
@@ -95,7 +83,7 @@ export async function POST(request: NextRequest) {
9583 )
9684 ) ;
9785 } finally {
98- await writer ? .close ( ) ;
86+ await writer . close ( ) ;
9987 }
10088 } ) ( ) ;
10189
@@ -114,10 +102,18 @@ export async function POST(request: NextRequest) {
114102
115103export async function PUT ( request : NextRequest ) {
116104 const body = await request . json ( ) ;
117- const { prompt, html, previousPrompt, selectedElementHtml, apiKey, model, baseUrl, customModel } = body ;
105+ const {
106+ prompt,
107+ html,
108+ previousPrompt,
109+ selectedElementHtml,
110+ apiKey,
111+ model,
112+ baseUrl,
113+ } = body ;
118114
119115 const openai = new OpenAI ( {
120- apiKey : apiKey || process . env . OPENAI_API_KEY ,
116+ apiKey : apiKey || process . env . OPENAI_API_KEY || "" ,
121117 baseURL : baseUrl || process . env . OPENAI_BASE_URL ,
122118 } ) ;
123119
@@ -128,116 +124,95 @@ export async function PUT(request: NextRequest) {
128124 ) ;
129125 }
130126
131- const selectedModel = MODELS . find (
132- ( m ) => m . value === model || m . label === model
133- ) ;
134- if ( ! selectedModel ) {
135- return NextResponse . json (
136- { ok : false , error : "Invalid model selected" } ,
137- { status : 400 }
138- ) ;
139- }
140-
141127 try {
142128 const response = await openai . chat . completions . create ( {
143- model : customModel || selectedModel . value ,
129+ model,
144130 messages : [
145- {
146- role : "system" ,
147- content : FOLLOW_UP_SYSTEM_PROMPT ,
148- } ,
131+ { role : "system" , content : FOLLOW_UP_SYSTEM_PROMPT } ,
149132 {
150133 role : "user" ,
151- content : previousPrompt
152- ? previousPrompt
153- : "You are modifying the HTML file based on the user's request." ,
134+ content :
135+ previousPrompt ||
136+ "You are modifying the HTML file based on the user's request." ,
154137 } ,
155138 {
156139 role : "assistant" ,
157- content : `The current code is: \n\`\`\`html\n${ html } \n\`\`\` ${ selectedElementHtml
158- ? `\n\nYou have to update ONLY the following element, NOTHING ELSE: \n\n\`\`\`html\n${ selectedElementHtml } \n\`\`\``
159- : "" }
160- ` ,
161- } ,
162- {
163- role : "user" ,
164- content : prompt ,
140+ content : `The current code is: \n\`\`\`html\n${ html } \n\`\`\` ${
141+ selectedElementHtml
142+ ? `\n\nYou have to update ONLY the following element, NOTHING ELSE: \n\n\`\`\`html\n${ selectedElementHtml } \n\`\`\``
143+ : ""
144+ } `,
165145 } ,
146+ { role : "user" , content : prompt } ,
166147 ] ,
167148 } ) ;
168149
169- const chunk = response . choices [ 0 ] ?. message ?. content ;
170- if ( ! chunk ) {
150+ const chunk = response . choices [ 0 ] ?. message ?. content || "" ;
151+ if ( ! chunk . trim ( ) ) {
171152 return NextResponse . json (
172- { ok : false , message : "No content returned from the model " } ,
153+ { ok : false , message : "Model returned empty response " } ,
173154 { status : 400 }
174155 ) ;
175156 }
176157
177- if ( chunk ) {
178- const updatedLines : number [ ] [ ] = [ ] ;
179- let newHtml = html ;
180- let position = 0 ;
181- let moreBlocks = true ;
182-
183- while ( moreBlocks ) {
184- const searchStartIndex = chunk . indexOf ( SEARCH_START , position ) ;
185- if ( searchStartIndex === - 1 ) {
186- moreBlocks = false ;
187- continue ;
188- }
158+ // aplica os blocos de modificação SEARCH_START...DIVIDER...REPLACE_END
159+ let newHtml = html ;
160+ const updatedLines : number [ ] [ ] = [ ] ;
161+ let position = 0 ;
162+ let moreBlocks = true ;
163+
164+ while ( moreBlocks ) {
165+ const searchStartIndex = chunk . indexOf ( SEARCH_START , position ) ;
166+ if ( searchStartIndex === - 1 ) {
167+ moreBlocks = false ;
168+ continue ;
169+ }
189170
190- const dividerIndex = chunk . indexOf ( DIVIDER , searchStartIndex ) ;
191- if ( dividerIndex === - 1 ) {
192- moreBlocks = false ;
193- continue ;
194- }
171+ const dividerIndex = chunk . indexOf ( DIVIDER , searchStartIndex ) ;
172+ if ( dividerIndex === - 1 ) {
173+ moreBlocks = false ;
174+ continue ;
175+ }
195176
196- const replaceEndIndex = chunk . indexOf ( REPLACE_END , dividerIndex ) ;
197- if ( replaceEndIndex === - 1 ) {
198- moreBlocks = false ;
199- continue ;
200- }
177+ const replaceEndIndex = chunk . indexOf ( REPLACE_END , dividerIndex ) ;
178+ if ( replaceEndIndex === - 1 ) {
179+ moreBlocks = false ;
180+ continue ;
181+ }
201182
202- const searchBlock = chunk . substring (
203- searchStartIndex + SEARCH_START . length ,
204- dividerIndex
205- ) ;
206- const replaceBlock = chunk . substring (
207- dividerIndex + DIVIDER . length ,
208- replaceEndIndex
209- ) ;
183+ const searchBlock = chunk . substring (
184+ searchStartIndex + SEARCH_START . length ,
185+ dividerIndex
186+ ) ;
187+ const replaceBlock = chunk . substring (
188+ dividerIndex + DIVIDER . length ,
189+ replaceEndIndex
190+ ) ;
210191
211- if ( searchBlock . trim ( ) === "" ) {
212- newHtml = `${ replaceBlock } \n${ newHtml } ` ;
213- updatedLines . push ( [ 1 , replaceBlock . split ( "\n" ) . length ] ) ;
214- } else {
215- const blockPosition = newHtml . indexOf ( searchBlock ) ;
216- if ( blockPosition !== - 1 ) {
217- const beforeText = newHtml . substring ( 0 , blockPosition ) ;
218- const startLineNumber = beforeText . split ( "\n" ) . length ;
219- const replaceLines = replaceBlock . split ( "\n" ) . length ;
220- const endLineNumber = startLineNumber + replaceLines - 1 ;
221-
222- updatedLines . push ( [ startLineNumber , endLineNumber ] ) ;
223- newHtml = newHtml . replace ( searchBlock , replaceBlock ) ;
224- }
192+ if ( searchBlock . trim ( ) === "" ) {
193+ newHtml = `${ replaceBlock } \n${ newHtml } ` ;
194+ updatedLines . push ( [ 1 , replaceBlock . split ( "\n" ) . length ] ) ;
195+ } else {
196+ const blockPosition = newHtml . indexOf ( searchBlock ) ;
197+ if ( blockPosition !== - 1 ) {
198+ const beforeText = newHtml . substring ( 0 , blockPosition ) ;
199+ const startLineNumber = beforeText . split ( "\n" ) . length ;
200+ const replaceLines = replaceBlock . split ( "\n" ) . length ;
201+ const endLineNumber = startLineNumber + replaceLines - 1 ;
202+
203+ updatedLines . push ( [ startLineNumber , endLineNumber ] ) ;
204+ newHtml = newHtml . replace ( searchBlock , replaceBlock ) ;
225205 }
226-
227- position = replaceEndIndex + REPLACE_END . length ;
228206 }
229207
230- return NextResponse . json ( {
231- ok : true ,
232- html : newHtml ,
233- updatedLines,
234- } ) ;
235- } else {
236- return NextResponse . json (
237- { ok : false , message : "No content returned from the model" } ,
238- { status : 400 }
239- ) ;
208+ position = replaceEndIndex + REPLACE_END . length ;
240209 }
210+
211+ return NextResponse . json ( {
212+ ok : true ,
213+ html : newHtml ,
214+ updatedLines,
215+ } ) ;
241216 } catch ( error : any ) {
242217 return NextResponse . json (
243218 {
@@ -248,4 +223,4 @@ export async function PUT(request: NextRequest) {
248223 { status : 500 }
249224 ) ;
250225 }
251- }
226+ }
0 commit comments