Spaces:
Running
Running
Add prompt when redesign website
Browse files
app/api/ask/route.ts
CHANGED
|
@@ -80,12 +80,6 @@ export async function POST(request: NextRequest) {
|
|
| 80 |
billTo = "huggingface";
|
| 81 |
}
|
| 82 |
|
| 83 |
-
let rewrittenPrompt = redesignMarkdown ? `Here is my current design as a markdown:\n\n${redesignMarkdown}\n\nNow, please create a new design based on this markdown. Use the images in the markdown.` : prompt;
|
| 84 |
-
|
| 85 |
-
if (enhancedSettings.isActive) {
|
| 86 |
-
// rewrittenPrompt = await rewritePrompt(rewrittenPrompt, enhancedSettings, { token, billTo }, selectedModel.value, selectedProvider.provider);
|
| 87 |
-
}
|
| 88 |
-
|
| 89 |
try {
|
| 90 |
const encoder = new TextEncoder();
|
| 91 |
const stream = new TransformStream();
|
|
@@ -107,8 +101,8 @@ export async function POST(request: NextRequest) {
|
|
| 107 |
? INITIAL_SYSTEM_PROMPT_LIGHT
|
| 108 |
: INITIAL_SYSTEM_PROMPT;
|
| 109 |
|
| 110 |
-
const userPrompt =
|
| 111 |
-
|
| 112 |
const chatCompletion = client.chatCompletionStream(
|
| 113 |
{
|
| 114 |
model: selectedModel.value + (provider !== "auto" ? `:${provider}` : ""),
|
|
@@ -117,6 +111,10 @@ export async function POST(request: NextRequest) {
|
|
| 117 |
role: "system",
|
| 118 |
content: systemPrompt,
|
| 119 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
| 120 |
{
|
| 121 |
role: "user",
|
| 122 |
content: userPrompt + (enhancedSettings.isActive ? `1. I want to use the following primary color: ${enhancedSettings.primaryColor} (eg: bg-${enhancedSettings.primaryColor}-500).
|
|
|
|
| 80 |
billTo = "huggingface";
|
| 81 |
}
|
| 82 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
try {
|
| 84 |
const encoder = new TextEncoder();
|
| 85 |
const stream = new TransformStream();
|
|
|
|
| 101 |
? INITIAL_SYSTEM_PROMPT_LIGHT
|
| 102 |
: INITIAL_SYSTEM_PROMPT;
|
| 103 |
|
| 104 |
+
const userPrompt = prompt;
|
| 105 |
+
|
| 106 |
const chatCompletion = client.chatCompletionStream(
|
| 107 |
{
|
| 108 |
model: selectedModel.value + (provider !== "auto" ? `:${provider}` : ""),
|
|
|
|
| 111 |
role: "system",
|
| 112 |
content: systemPrompt,
|
| 113 |
},
|
| 114 |
+
...(redesignMarkdown ? [{
|
| 115 |
+
role: "assistant",
|
| 116 |
+
content: `User will ask you to redesign the site based on this markdown. Use the same images as the site, but you can improve the content and the design. Here is the markdown: ${redesignMarkdown}`
|
| 117 |
+
}] : []),
|
| 118 |
{
|
| 119 |
role: "user",
|
| 120 |
content: userPrompt + (enhancedSettings.isActive ? `1. I want to use the following primary color: ${enhancedSettings.primaryColor} (eg: bg-${enhancedSettings.primaryColor}-500).
|
components/editor/ask-ai/index.tsx
CHANGED
|
@@ -22,6 +22,7 @@ import { Settings } from "./settings";
|
|
| 22 |
import { useProModal } from "@/components/contexts/pro-context";
|
| 23 |
import { MAX_FREE_PROJECTS } from "@/lib/utils";
|
| 24 |
import { PROMPTS_FOR_AI } from "@/lib/prompts";
|
|
|
|
| 25 |
|
| 26 |
export const AskAi = ({
|
| 27 |
project,
|
|
@@ -52,6 +53,9 @@ export const AskAi = ({
|
|
| 52 |
const { openProModal } = useProModal();
|
| 53 |
const [openProvider, setOpenProvider] = useState(false);
|
| 54 |
const [providerError, setProviderError] = useState("");
|
|
|
|
|
|
|
|
|
|
| 55 |
const refThink = useRef<HTMLDivElement>(null);
|
| 56 |
|
| 57 |
const [enhancedSettings, setEnhancedSettings, removeEnhancedSettings] =
|
|
@@ -76,7 +80,7 @@ export const AskAi = ({
|
|
| 76 |
}
|
| 77 |
});
|
| 78 |
|
| 79 |
-
const callAi = async (redesignMarkdown?: string) => {
|
| 80 |
removePromptStorage();
|
| 81 |
if (user && !user.isPro && projects.length >= MAX_FREE_PROJECTS)
|
| 82 |
return openProModal([]);
|
|
@@ -218,6 +222,15 @@ export const AskAi = ({
|
|
| 218 |
/>
|
| 219 |
</div>
|
| 220 |
)}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 221 |
<div className="w-full relative flex items-center justify-between">
|
| 222 |
{(isAiWorking || isUploading || isThinking || isLoadingProject) && (
|
| 223 |
<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">
|
|
@@ -259,6 +272,8 @@ export const AskAi = ({
|
|
| 259 |
placeholder={
|
| 260 |
selectedElement
|
| 261 |
? `Ask DeepSite about ${selectedElement.tagName.toLowerCase()}...`
|
|
|
|
|
|
|
| 262 |
: isFollowUp && (!isSameHtml || pages?.length > 1)
|
| 263 |
? "Ask DeepSite for edits"
|
| 264 |
: "Ask DeepSite anything..."
|
|
@@ -303,7 +318,13 @@ export const AskAi = ({
|
|
| 303 |
onClose={setOpenProvider}
|
| 304 |
/>
|
| 305 |
{!isNew && <Uploader project={project} />}
|
| 306 |
-
{isNew &&
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 307 |
{!isNew && !isSameHtml && <Selector />}
|
| 308 |
</div>
|
| 309 |
<div className="flex items-center justify-end gap-2">
|
|
@@ -312,9 +333,11 @@ export const AskAi = ({
|
|
| 312 |
variant="outline"
|
| 313 |
className="!rounded-md"
|
| 314 |
disabled={
|
| 315 |
-
|
|
|
|
|
|
|
| 316 |
}
|
| 317 |
-
onClick={() => callAi()}
|
| 318 |
>
|
| 319 |
<ArrowUp className="size-4" />
|
| 320 |
</Button>
|
|
|
|
| 22 |
import { useProModal } from "@/components/contexts/pro-context";
|
| 23 |
import { MAX_FREE_PROJECTS } from "@/lib/utils";
|
| 24 |
import { PROMPTS_FOR_AI } from "@/lib/prompts";
|
| 25 |
+
import { SelectedRedesignUrl } from "./selected-redesign-url";
|
| 26 |
|
| 27 |
export const AskAi = ({
|
| 28 |
project,
|
|
|
|
| 53 |
const { openProModal } = useProModal();
|
| 54 |
const [openProvider, setOpenProvider] = useState(false);
|
| 55 |
const [providerError, setProviderError] = useState("");
|
| 56 |
+
const [redesignData, setRedesignData] = useState<
|
| 57 |
+
undefined | { markdown: string; url: string }
|
| 58 |
+
>(undefined);
|
| 59 |
const refThink = useRef<HTMLDivElement>(null);
|
| 60 |
|
| 61 |
const [enhancedSettings, setEnhancedSettings, removeEnhancedSettings] =
|
|
|
|
| 80 |
}
|
| 81 |
});
|
| 82 |
|
| 83 |
+
const callAi = async (redesignMarkdown?: string | undefined) => {
|
| 84 |
removePromptStorage();
|
| 85 |
if (user && !user.isPro && projects.length >= MAX_FREE_PROJECTS)
|
| 86 |
return openProModal([]);
|
|
|
|
| 222 |
/>
|
| 223 |
</div>
|
| 224 |
)}
|
| 225 |
+
{redesignData && (
|
| 226 |
+
<div className="px-4 pt-3">
|
| 227 |
+
<SelectedRedesignUrl
|
| 228 |
+
url={redesignData.url}
|
| 229 |
+
isAiWorking={isAiWorking}
|
| 230 |
+
onDelete={() => setRedesignData(undefined)}
|
| 231 |
+
/>
|
| 232 |
+
</div>
|
| 233 |
+
)}
|
| 234 |
<div className="w-full relative flex items-center justify-between">
|
| 235 |
{(isAiWorking || isUploading || isThinking || isLoadingProject) && (
|
| 236 |
<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">
|
|
|
|
| 272 |
placeholder={
|
| 273 |
selectedElement
|
| 274 |
? `Ask DeepSite about ${selectedElement.tagName.toLowerCase()}...`
|
| 275 |
+
: redesignData
|
| 276 |
+
? "Ask DeepSite anything about the redesign of your site..."
|
| 277 |
: isFollowUp && (!isSameHtml || pages?.length > 1)
|
| 278 |
? "Ask DeepSite for edits"
|
| 279 |
: "Ask DeepSite anything..."
|
|
|
|
| 318 |
onClose={setOpenProvider}
|
| 319 |
/>
|
| 320 |
{!isNew && <Uploader project={project} />}
|
| 321 |
+
{isNew && (
|
| 322 |
+
<ReImagine
|
| 323 |
+
onRedesign={(md, url) =>
|
| 324 |
+
setRedesignData({ markdown: md, url: url })
|
| 325 |
+
}
|
| 326 |
+
/>
|
| 327 |
+
)}
|
| 328 |
{!isNew && !isSameHtml && <Selector />}
|
| 329 |
</div>
|
| 330 |
<div className="flex items-center justify-end gap-2">
|
|
|
|
| 333 |
variant="outline"
|
| 334 |
className="!rounded-md"
|
| 335 |
disabled={
|
| 336 |
+
!!redesignData?.url?.trim()
|
| 337 |
+
? false
|
| 338 |
+
: isAiWorking || isUploading || isThinking || !prompt.trim()
|
| 339 |
}
|
| 340 |
+
onClick={() => callAi(redesignData?.markdown)}
|
| 341 |
>
|
| 342 |
<ArrowUp className="size-4" />
|
| 343 |
</Button>
|
components/editor/ask-ai/re-imagine.tsx
CHANGED
|
@@ -13,11 +13,12 @@ import Loading from "@/components/loading";
|
|
| 13 |
import { api } from "@/lib/api";
|
| 14 |
import { useAi } from "@/hooks/useAi";
|
| 15 |
import { useEditor } from "@/hooks/useEditor";
|
|
|
|
| 16 |
|
| 17 |
export function ReImagine({
|
| 18 |
onRedesign,
|
| 19 |
}: {
|
| 20 |
-
onRedesign: (md: string) => void;
|
| 21 |
}) {
|
| 22 |
const [url, setUrl] = useState<string>("");
|
| 23 |
const [open, setOpen] = useState(false);
|
|
@@ -49,8 +50,8 @@ export function ReImagine({
|
|
| 49 |
});
|
| 50 |
if (response?.data?.ok) {
|
| 51 |
setOpen(false);
|
|
|
|
| 52 |
setUrl("");
|
| 53 |
-
onRedesign(response.data.markdown);
|
| 54 |
toast.success("DeepSite is redesigning your site! Let him cook... 🔥");
|
| 55 |
} else {
|
| 56 |
toast.error(response?.data?.error || "Failed to redesign the site.");
|
|
@@ -117,6 +118,11 @@ export function ReImagine({
|
|
| 117 |
}
|
| 118 |
setUrl(inputUrl);
|
| 119 |
}}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 120 |
className="!bg-white !border-neutral-300 !text-neutral-800 !placeholder:text-neutral-400 selection:!bg-blue-100"
|
| 121 |
/>
|
| 122 |
</div>
|
|
|
|
| 13 |
import { api } from "@/lib/api";
|
| 14 |
import { useAi } from "@/hooks/useAi";
|
| 15 |
import { useEditor } from "@/hooks/useEditor";
|
| 16 |
+
import classNames from "classnames";
|
| 17 |
|
| 18 |
export function ReImagine({
|
| 19 |
onRedesign,
|
| 20 |
}: {
|
| 21 |
+
onRedesign: (md: string, url: string) => void;
|
| 22 |
}) {
|
| 23 |
const [url, setUrl] = useState<string>("");
|
| 24 |
const [open, setOpen] = useState(false);
|
|
|
|
| 50 |
});
|
| 51 |
if (response?.data?.ok) {
|
| 52 |
setOpen(false);
|
| 53 |
+
onRedesign(response.data.markdown, url.trim());
|
| 54 |
setUrl("");
|
|
|
|
| 55 |
toast.success("DeepSite is redesigning your site! Let him cook... 🔥");
|
| 56 |
} else {
|
| 57 |
toast.error(response?.data?.error || "Failed to redesign the site.");
|
|
|
|
| 118 |
}
|
| 119 |
setUrl(inputUrl);
|
| 120 |
}}
|
| 121 |
+
onKeyDown={(e) => {
|
| 122 |
+
if (e.key === "Enter") {
|
| 123 |
+
handleClick();
|
| 124 |
+
}
|
| 125 |
+
}}
|
| 126 |
className="!bg-white !border-neutral-300 !text-neutral-800 !placeholder:text-neutral-400 selection:!bg-blue-100"
|
| 127 |
/>
|
| 128 |
</div>
|
components/editor/ask-ai/selected-redesign-url.tsx
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import classNames from "classnames";
|
| 2 |
+
import { Paintbrush, XCircle } from "lucide-react";
|
| 3 |
+
|
| 4 |
+
export const SelectedRedesignUrl = ({
|
| 5 |
+
url,
|
| 6 |
+
isAiWorking = false,
|
| 7 |
+
onDelete,
|
| 8 |
+
}: {
|
| 9 |
+
url: string;
|
| 10 |
+
isAiWorking: boolean;
|
| 11 |
+
onDelete?: () => void;
|
| 12 |
+
}) => {
|
| 13 |
+
return (
|
| 14 |
+
<div
|
| 15 |
+
className={classNames(
|
| 16 |
+
"border border-emerald-500/50 bg-emerald-500/10 rounded-xl p-1.5 pr-3 max-w-max hover:brightness-110 transition-all duration-200 ease-in-out",
|
| 17 |
+
{
|
| 18 |
+
"cursor-pointer": !isAiWorking,
|
| 19 |
+
"opacity-50 cursor-not-allowed": isAiWorking,
|
| 20 |
+
}
|
| 21 |
+
)}
|
| 22 |
+
onClick={() => {
|
| 23 |
+
if (!isAiWorking && onDelete) {
|
| 24 |
+
onDelete();
|
| 25 |
+
}
|
| 26 |
+
}}
|
| 27 |
+
>
|
| 28 |
+
<div className="flex items-center justify-start gap-2">
|
| 29 |
+
<div className="rounded-lg bg-emerald-500/20 size-6 flex items-center justify-center">
|
| 30 |
+
<Paintbrush className="text-emerald-300 size-3.5" />
|
| 31 |
+
</div>
|
| 32 |
+
<p className="text-sm font-semibold text-emerald-200">{url}</p>
|
| 33 |
+
<XCircle className="text-emerald-300 size-4 hover:text-emerald-200 transition-colors" />
|
| 34 |
+
</div>
|
| 35 |
+
</div>
|
| 36 |
+
);
|
| 37 |
+
};
|