Skip to content

Commit 8f2ea02

Browse files
fix: settings for localhost calls
1 parent fafa74b commit 8f2ea02

File tree

2 files changed

+99
-126
lines changed

2 files changed

+99
-126
lines changed

app/api/ask-ai/route.ts

Lines changed: 88 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import type { NextRequest } from "next/server";
33
import { NextResponse } from "next/server";
44
import OpenAI from "openai";
55

6-
import { MODELS } from "@/lib/providers";
76
import {
87
DIVIDER,
98
FOLLOW_UP_SYSTEM_PROMPT,
@@ -14,7 +13,7 @@ import {
1413

1514
export 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

115103
export 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+
}

components/editor/ask-ai/index.tsx

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,6 @@ export function AskAI({
5454
const [hasAsked, setHasAsked] = useState(false);
5555
const [previousPrompt, setPreviousPrompt] = useState("");
5656
const [provider, setProvider] = useLocalStorage("provider", "auto");
57-
const [model, setModel] = useLocalStorage(
58-
"model",
59-
typeof window !== "undefined"
60-
? localStorage.getItem("openai_model") || MODELS[0].value
61-
: MODELS[0].value
62-
);
6357
const [openProvider, setOpenProvider] = useState(false);
6458
const [providerError, setProviderError] = useState("");
6559
const [think, setThink] = useState<string | undefined>(undefined);
@@ -68,6 +62,11 @@ export function AskAI({
6862
const [controller, setController] = useState<AbortController | null>(null);
6963
const [isFollowUp, setIsFollowUp] = useState(true);
7064

65+
const getModel = () =>
66+
typeof window !== "undefined"
67+
? localStorage.getItem("openai_model") || "gpt-4o-mini"
68+
: "gpt-4o-mini";
69+
7170
const callAi = async (redesignMarkdown?: string) => {
7271
if (isAiWorking) return;
7372
if (!redesignMarkdown && !prompt.trim()) return;
@@ -91,7 +90,7 @@ export function AskAI({
9190
: "";
9291
const apiKey = localStorage.getItem("openai_api_key");
9392
const baseUrl = localStorage.getItem("openai_base_url");
94-
const customModel = localStorage.getItem("openai_model");
93+
const model = getModel();
9594
const request = await fetch("/api/ask-ai", {
9695
method: "PUT",
9796
body: JSON.stringify({
@@ -103,7 +102,6 @@ export function AskAI({
103102
selectedElementHtml,
104103
apiKey,
105104
baseUrl,
106-
customModel,
107105
}),
108106
headers: {
109107
"Content-Type": "application/json",
@@ -128,7 +126,7 @@ export function AskAI({
128126
} else {
129127
const apiKey = localStorage.getItem("openai_api_key");
130128
const baseUrl = localStorage.getItem("openai_base_url");
131-
const customModel = localStorage.getItem("openai_model");
129+
const model = getModel();
132130
const request = await fetch("/api/ask-ai", {
133131
method: "POST",
134132
body: JSON.stringify({
@@ -139,7 +137,6 @@ export function AskAI({
139137
redesignMarkdown,
140138
apiKey,
141139
baseUrl,
142-
customModel,
143140
}),
144141
headers: {
145142
"Content-Type": "application/json",
@@ -188,7 +185,6 @@ export function AskAI({
188185
setPrompt("");
189186
setisAiWorking(false);
190187
setHasAsked(true);
191-
setModel(MODELS[0].value);
192188
if (audio.current) audio.current.play();
193189

194190
// Now we have the complete HTML including </html>, so set it to be sure
@@ -418,9 +414,11 @@ export function AskAI({
418414
<div className="flex items-center justify-end gap-2">
419415
<Settings
420416
provider={provider as string}
421-
model={model as string}
417+
model={getModel()}
422418
onChange={setProvider}
423-
onModelChange={setModel}
419+
onModelChange={(newModel: string) => {
420+
localStorage.setItem("openai_model", newModel);
421+
}}
424422
open={openProvider}
425423
error={providerError}
426424
isFollowUp={!isSameHtml && isFollowUp}

0 commit comments

Comments
 (0)