Spaces:
Build error
Build error
update
Browse files
app/api/ask-ai/route.ts
CHANGED
|
@@ -197,7 +197,7 @@ export async function PUT(request: NextRequest) {
|
|
| 197 |
const userToken = request.cookies.get(MY_TOKEN_KEY())?.value;
|
| 198 |
|
| 199 |
const body = await request.json();
|
| 200 |
-
const { prompt,
|
| 201 |
body;
|
| 202 |
|
| 203 |
if (!prompt || pages.length === 0) {
|
|
@@ -270,8 +270,8 @@ export async function PUT(request: NextRequest) {
|
|
| 270 |
},
|
| 271 |
{
|
| 272 |
role: "user",
|
| 273 |
-
content:
|
| 274 |
-
?
|
| 275 |
: "You are modifying the HTML file based on the user's request.",
|
| 276 |
},
|
| 277 |
{
|
|
|
|
| 197 |
const userToken = request.cookies.get(MY_TOKEN_KEY())?.value;
|
| 198 |
|
| 199 |
const body = await request.json();
|
| 200 |
+
const { prompt, previousPrompts, provider, selectedElementHtml, model, pages, files, } =
|
| 201 |
body;
|
| 202 |
|
| 203 |
if (!prompt || pages.length === 0) {
|
|
|
|
| 270 |
},
|
| 271 |
{
|
| 272 |
role: "user",
|
| 273 |
+
content: previousPrompts
|
| 274 |
+
? `Also here are the previous prompts:\n\n${previousPrompts.map((p: string) => `- ${p}`).join("\n")}`
|
| 275 |
: "You are modifying the HTML file based on the user's request.",
|
| 276 |
},
|
| 277 |
{
|
app/api/me/projects/[namespace]/[repoId]/route.ts
CHANGED
|
@@ -172,6 +172,10 @@ export async function PUT(
|
|
| 172 |
};
|
| 173 |
|
| 174 |
const files: File[] = [];
|
|
|
|
|
|
|
|
|
|
|
|
|
| 175 |
pages.forEach((page: Page) => {
|
| 176 |
const file = new File([page.html], page.path, { type: "text/html" });
|
| 177 |
files.push(file);
|
|
@@ -188,7 +192,6 @@ export async function PUT(
|
|
| 188 |
{
|
| 189 |
$set: {
|
| 190 |
prompts: [
|
| 191 |
-
...(project && "prompts" in project ? project.prompts : []),
|
| 192 |
...prompts,
|
| 193 |
],
|
| 194 |
},
|
|
|
|
| 172 |
};
|
| 173 |
|
| 174 |
const files: File[] = [];
|
| 175 |
+
const promptsFile = new File([prompts.join("\n")], "prompts.txt", {
|
| 176 |
+
type: "text/plain",
|
| 177 |
+
});
|
| 178 |
+
files.push(promptsFile);
|
| 179 |
pages.forEach((page: Page) => {
|
| 180 |
const file = new File([page.html], page.path, { type: "text/html" });
|
| 181 |
files.push(file);
|
|
|
|
| 192 |
{
|
| 193 |
$set: {
|
| 194 |
prompts: [
|
|
|
|
| 195 |
...prompts,
|
| 196 |
],
|
| 197 |
},
|
app/api/me/projects/route.ts
CHANGED
|
@@ -96,7 +96,10 @@ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-
|
|
| 96 |
const readmeFile = new File([readme], "README.md", {
|
| 97 |
type: "text/markdown",
|
| 98 |
});
|
| 99 |
-
const
|
|
|
|
|
|
|
|
|
|
| 100 |
pages.forEach((page: Page) => {
|
| 101 |
const file = new File([page.html], page.path, { type: "text/html" });
|
| 102 |
files.push(file);
|
|
|
|
| 96 |
const readmeFile = new File([readme], "README.md", {
|
| 97 |
type: "text/markdown",
|
| 98 |
});
|
| 99 |
+
const promptsFile = new File([prompts.join("\n")], "prompts.txt", {
|
| 100 |
+
type: "text/plain",
|
| 101 |
+
});
|
| 102 |
+
const files = [readmeFile, promptsFile];
|
| 103 |
pages.forEach((page: Page) => {
|
| 104 |
const file = new File([page.html], page.path, { type: "text/html" });
|
| 105 |
files.push(file);
|
components/editor/ask-ai/index.tsx
CHANGED
|
@@ -72,7 +72,6 @@ export function AskAI({
|
|
| 72 |
|
| 73 |
const [open, setOpen] = useState(false);
|
| 74 |
const [prompt, setPrompt] = useState("");
|
| 75 |
-
const [previousPrompt, setPreviousPrompt] = useState("");
|
| 76 |
const [provider, setProvider] = useLocalStorage("provider", "auto");
|
| 77 |
const [model, setModel] = useLocalStorage("model", MODELS[0].value);
|
| 78 |
const [openProvider, setOpenProvider] = useState(false);
|
|
@@ -121,7 +120,7 @@ export function AskAI({
|
|
| 121 |
prompt,
|
| 122 |
model,
|
| 123 |
provider,
|
| 124 |
-
|
| 125 |
selectedElementHtml,
|
| 126 |
selectedFiles
|
| 127 |
);
|
|
@@ -132,7 +131,6 @@ export function AskAI({
|
|
| 132 |
}
|
| 133 |
|
| 134 |
if (result?.success) {
|
| 135 |
-
setPreviousPrompt(prompt);
|
| 136 |
setPrompt("");
|
| 137 |
}
|
| 138 |
} else if (isFollowUp && pages.length > 1 && isSameHtml) {
|
|
@@ -152,7 +150,6 @@ export function AskAI({
|
|
| 152 |
}
|
| 153 |
|
| 154 |
if (result?.success) {
|
| 155 |
-
setPreviousPrompt(prompt);
|
| 156 |
setPrompt("");
|
| 157 |
}
|
| 158 |
} else {
|
|
@@ -173,7 +170,6 @@ export function AskAI({
|
|
| 173 |
}
|
| 174 |
|
| 175 |
if (result?.success) {
|
| 176 |
-
setPreviousPrompt(prompt);
|
| 177 |
setPrompt("");
|
| 178 |
if (selectedModel?.isThinker) {
|
| 179 |
setModel(MODELS[0].value);
|
|
@@ -285,13 +281,11 @@ export function AskAI({
|
|
| 285 |
)}
|
| 286 |
<div className="w-full relative flex items-center justify-between">
|
| 287 |
{(isAiWorking || isUploading) && (
|
| 288 |
-
<div className="absolute bg-neutral-800
|
| 289 |
<div className="flex items-center justify-start gap-2">
|
| 290 |
<Loading overlay={false} className="!size-4" />
|
| 291 |
<p className="text-neutral-400 text-sm">
|
| 292 |
-
{isUploading
|
| 293 |
-
? "Uploading images..."
|
| 294 |
-
: `AI is ${isThinking ? "thinking" : "coding"}...`}
|
| 295 |
</p>
|
| 296 |
</div>
|
| 297 |
{isAiWorking && (
|
|
|
|
| 72 |
|
| 73 |
const [open, setOpen] = useState(false);
|
| 74 |
const [prompt, setPrompt] = useState("");
|
|
|
|
| 75 |
const [provider, setProvider] = useLocalStorage("provider", "auto");
|
| 76 |
const [model, setModel] = useLocalStorage("model", MODELS[0].value);
|
| 77 |
const [openProvider, setOpenProvider] = useState(false);
|
|
|
|
| 120 |
prompt,
|
| 121 |
model,
|
| 122 |
provider,
|
| 123 |
+
previousPrompts,
|
| 124 |
selectedElementHtml,
|
| 125 |
selectedFiles
|
| 126 |
);
|
|
|
|
| 131 |
}
|
| 132 |
|
| 133 |
if (result?.success) {
|
|
|
|
| 134 |
setPrompt("");
|
| 135 |
}
|
| 136 |
} else if (isFollowUp && pages.length > 1 && isSameHtml) {
|
|
|
|
| 150 |
}
|
| 151 |
|
| 152 |
if (result?.success) {
|
|
|
|
| 153 |
setPrompt("");
|
| 154 |
}
|
| 155 |
} else {
|
|
|
|
| 170 |
}
|
| 171 |
|
| 172 |
if (result?.success) {
|
|
|
|
| 173 |
setPrompt("");
|
| 174 |
if (selectedModel?.isThinker) {
|
| 175 |
setModel(MODELS[0].value);
|
|
|
|
| 281 |
)}
|
| 282 |
<div className="w-full relative flex items-center justify-between">
|
| 283 |
{(isAiWorking || isUploading) && (
|
| 284 |
+
<div className="absolute bg-neutral-800 top-0 left-4 w-[calc(100%-30px)] h-full z-1 flex items-start pt-3.5 justify-between max-lg:text-sm">
|
| 285 |
<div className="flex items-center justify-start gap-2">
|
| 286 |
<Loading overlay={false} className="!size-4" />
|
| 287 |
<p className="text-neutral-400 text-sm">
|
| 288 |
+
{isUploading ? "Uploading images..." : "AI is working..."}
|
|
|
|
|
|
|
| 289 |
</p>
|
| 290 |
</div>
|
| 291 |
{isAiWorking && (
|
components/editor/ask-ai/uploader.tsx
CHANGED
|
@@ -187,6 +187,7 @@ export const Uploader = ({
|
|
| 187 |
size="iconXs"
|
| 188 |
variant="outline"
|
| 189 |
className="!border-neutral-600 !text-neutral-400 !hover:!border-neutral-500 hover:!text-neutral-300"
|
|
|
|
| 190 |
>
|
| 191 |
<Images className="size-4" />
|
| 192 |
</Button>
|
|
|
|
| 187 |
size="iconXs"
|
| 188 |
variant="outline"
|
| 189 |
className="!border-neutral-600 !text-neutral-400 !hover:!border-neutral-500 hover:!text-neutral-300"
|
| 190 |
+
onClick={() => setOpen(true)}
|
| 191 |
>
|
| 192 |
<Images className="size-4" />
|
| 193 |
</Button>
|
components/editor/index.tsx
CHANGED
|
@@ -39,10 +39,11 @@ export const AppEditor = ({
|
|
| 39 |
images?: string[];
|
| 40 |
isNew?: boolean;
|
| 41 |
}) => {
|
|
|
|
| 42 |
const [htmlStorage, , removeHtmlStorage] = useLocalStorage("pages");
|
| 43 |
const [, copyToClipboard] = useCopyToClipboard();
|
| 44 |
const { htmlHistory, setHtmlHistory, prompts, setPrompts, pages, setPages } =
|
| 45 |
-
useEditor(initialPages);
|
| 46 |
|
| 47 |
const searchParams = useSearchParams();
|
| 48 |
const router = useRouter();
|
|
@@ -292,7 +293,7 @@ export const AppEditor = ({
|
|
| 292 |
images={images}
|
| 293 |
currentPage={currentPageData}
|
| 294 |
htmlHistory={htmlHistory}
|
| 295 |
-
previousPrompts={
|
| 296 |
onSuccess={(newPages, p: string) => {
|
| 297 |
const currentHistory = [...htmlHistory];
|
| 298 |
currentHistory.unshift({
|
|
|
|
| 39 |
images?: string[];
|
| 40 |
isNew?: boolean;
|
| 41 |
}) => {
|
| 42 |
+
console.log(project?.prompts);
|
| 43 |
const [htmlStorage, , removeHtmlStorage] = useLocalStorage("pages");
|
| 44 |
const [, copyToClipboard] = useCopyToClipboard();
|
| 45 |
const { htmlHistory, setHtmlHistory, prompts, setPrompts, pages, setPages } =
|
| 46 |
+
useEditor(initialPages, project?.prompts ?? []);
|
| 47 |
|
| 48 |
const searchParams = useSearchParams();
|
| 49 |
const router = useRouter();
|
|
|
|
| 293 |
images={images}
|
| 294 |
currentPage={currentPageData}
|
| 295 |
htmlHistory={htmlHistory}
|
| 296 |
+
previousPrompts={prompts}
|
| 297 |
onSuccess={(newPages, p: string) => {
|
| 298 |
const currentHistory = [...htmlHistory];
|
| 299 |
currentHistory.unshift({
|
hooks/useCallAi.ts
CHANGED
|
@@ -237,7 +237,7 @@ export const useCallAi = ({
|
|
| 237 |
}
|
| 238 |
};
|
| 239 |
|
| 240 |
-
const callAiFollowUp = async (prompt: string, model: string | undefined, provider: string | undefined,
|
| 241 |
if (isAiWorking) return;
|
| 242 |
if (!prompt.trim()) return;
|
| 243 |
|
|
@@ -254,7 +254,7 @@ export const useCallAi = ({
|
|
| 254 |
body: JSON.stringify({
|
| 255 |
prompt,
|
| 256 |
provider,
|
| 257 |
-
|
| 258 |
model,
|
| 259 |
pages,
|
| 260 |
selectedElementHtml,
|
|
|
|
| 237 |
}
|
| 238 |
};
|
| 239 |
|
| 240 |
+
const callAiFollowUp = async (prompt: string, model: string | undefined, provider: string | undefined, previousPrompts: string[], selectedElementHtml?: string, files?: string[]) => {
|
| 241 |
if (isAiWorking) return;
|
| 242 |
if (!prompt.trim()) return;
|
| 243 |
|
|
|
|
| 254 |
body: JSON.stringify({
|
| 255 |
prompt,
|
| 256 |
provider,
|
| 257 |
+
previousPrompts,
|
| 258 |
model,
|
| 259 |
pages,
|
| 260 |
selectedElementHtml,
|
hooks/useEditor.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { defaultHTML } from "@/lib/consts";
|
|
| 2 |
import { HtmlHistory, Page } from "@/types";
|
| 3 |
import { useState } from "react";
|
| 4 |
|
| 5 |
-
export const useEditor = (initialPages?: Page[]) => {
|
| 6 |
/**
|
| 7 |
* State to manage the HTML content of the editor.
|
| 8 |
* This will be the main content that users edit.
|
|
@@ -23,7 +23,9 @@ export const useEditor = (initialPages?: Page[]) => {
|
|
| 23 |
* State to manage the prompts used for generating HTML content.
|
| 24 |
* This can be used to track what prompts were used in the editor.
|
| 25 |
*/
|
| 26 |
-
const [prompts, setPrompts] = useState<string[]>(
|
|
|
|
|
|
|
| 27 |
|
| 28 |
|
| 29 |
return {
|
|
|
|
| 2 |
import { HtmlHistory, Page } from "@/types";
|
| 3 |
import { useState } from "react";
|
| 4 |
|
| 5 |
+
export const useEditor = (initialPages?: Page[], initialPrompts?: string[]) => {
|
| 6 |
/**
|
| 7 |
* State to manage the HTML content of the editor.
|
| 8 |
* This will be the main content that users edit.
|
|
|
|
| 23 |
* State to manage the prompts used for generating HTML content.
|
| 24 |
* This can be used to track what prompts were used in the editor.
|
| 25 |
*/
|
| 26 |
+
const [prompts, setPrompts] = useState<string[]>(
|
| 27 |
+
initialPrompts ?? []
|
| 28 |
+
);
|
| 29 |
|
| 30 |
|
| 31 |
return {
|