diff --git a/app/api/ask/route.ts b/app/api/ask/route.ts index 74041b2dc4bcdb53574abacc010ddca884beb110..6a871c52c7748eef3a01b9392d2100fbb6370fb1 100644 --- a/app/api/ask/route.ts +++ b/app/api/ask/route.ts @@ -18,6 +18,7 @@ import { UPDATE_PAGE_END, PROMPT_FOR_PROJECT_NAME, } from "@/lib/prompts"; +import { calculateMaxTokens, estimateInputTokens, getProviderSpecificConfig } from "@/lib/max-tokens"; import MY_TOKEN_KEY from "@/lib/get-cookie-name"; import { Page } from "@/types"; import { createRepo, RepoDesignation, uploadFiles } from "@huggingface/hub"; @@ -25,6 +26,7 @@ import { isAuthenticated } from "@/lib/auth"; import { getBestProvider } from "@/lib/best-provider"; import { rewritePrompt } from "@/lib/rewrite-prompt"; import { COLORS } from "@/lib/utils"; +import { templates } from "@/lib/templates"; const ipAddresses = new Map(); @@ -122,6 +124,21 @@ export async function POST(request: NextRequest) { // let completeResponse = ""; try { const client = new InferenceClient(token); + + // Calculate dynamic max_tokens based on provider and input size + const systemPrompt = INITIAL_SYSTEM_PROMPT + (enhancedSettings.isActive ? ` +Here are some examples of designs that you can inspire from: +${templates.map((template) => `- ${template}`).join("\n")} +IMPORTANT: Use the templates as inspiration, but do not copy them exactly. +Try to create a unique design, based on the templates, but not exactly like them, mostly depending on the user's prompt. These are just examples, do not copy them exactly. +` : ""); + + const userPrompt = `${rewrittenPrompt}${redesignMarkdown ? `\n\nHere 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.` : ""} : ""}`; + + const estimatedInputTokens = estimateInputTokens(systemPrompt, userPrompt); + const dynamicMaxTokens = calculateMaxTokens(selectedProvider, estimatedInputTokens, true); + const providerConfig = getProviderSpecificConfig(selectedProvider, dynamicMaxTokens); + const chatCompletion = client.chatCompletionStream( { model: selectedModel.value, @@ -129,14 +146,14 @@ export async function POST(request: NextRequest) { messages: [ { role: "system", - content: INITIAL_SYSTEM_PROMPT, + content: systemPrompt, }, { role: "user", - content: `${rewrittenPrompt}${redesignMarkdown ? `\n\nHere 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.` : ""} : ""}` + content: userPrompt }, ], - max_tokens: 65_536, + ...providerConfig, }, billTo ? { billTo } : {} ); @@ -297,6 +314,21 @@ export async function PUT(request: NextRequest) { const selectedProvider = await getBestProvider(selectedModel.value, provider) try { + // Calculate dynamic max_tokens for PUT request + const systemPrompt = FOLLOW_UP_SYSTEM_PROMPT + (isNew ? PROMPT_FOR_PROJECT_NAME : ""); + const userContext = previousPrompts + ? `Also here are the previous prompts:\n\n${previousPrompts.map((p: string) => `- ${p}`).join("\n")}` + : "You are modifying the HTML file based on the user's request."; + const assistantContext = `${ + selectedElementHtml + ? `\n\nYou have to update ONLY the following element, NOTHING ELSE: \n\n\`\`\`html\n${selectedElementHtml}\n\`\`\` Could be in multiple pages, if so, update all the pages.` + : "" + }. Current pages: ${pages?.map((p: Page) => `- ${p.path} \n${p.html}`).join("\n")}. ${files?.length > 0 ? `Current images: ${files?.map((f: string) => `- ${f}`).join("\n")}.` : ""}`; + + const estimatedInputTokens = estimateInputTokens(systemPrompt, prompt, userContext + assistantContext); + const dynamicMaxTokens = calculateMaxTokens(selectedProvider, estimatedInputTokens, false); + const providerConfig = getProviderSpecificConfig(selectedProvider, dynamicMaxTokens); + const response = await client.chatCompletion( { model: selectedModel.value, @@ -304,33 +336,22 @@ export async function PUT(request: NextRequest) { messages: [ { role: "system", - content: FOLLOW_UP_SYSTEM_PROMPT + (isNew ? PROMPT_FOR_PROJECT_NAME : ""), + content: systemPrompt, }, { role: "user", - content: previousPrompts - ? `Also here are the previous prompts:\n\n${previousPrompts.map((p: string) => `- ${p}`).join("\n")}` - : "You are modifying the HTML file based on the user's request.", + content: userContext, }, { role: "assistant", - - content: `${ - selectedElementHtml - ? `\n\nYou have to update ONLY the following element, NOTHING ELSE: \n\n\`\`\`html\n${selectedElementHtml}\n\`\`\` Could be in multiple pages, if so, update all the pages.` - : "" - }. Current pages: ${pages?.map((p: Page) => `- ${p.path} \n${p.html}`).join("\n")}. ${files?.length > 0 ? `Current images: ${files?.map((f: string) => `- ${f}`).join("\n")}.` : ""}`, + content: assistantContext, }, { role: "user", content: prompt, }, ], - ...(selectedProvider.provider !== "sambanova" - ? { - max_tokens: 65_536, - } - : {}), + ...providerConfig, }, billTo ? { billTo } : {} ); diff --git a/assets/deepseek.svg b/assets/deepseek.svg new file mode 100644 index 0000000000000000000000000000000000000000..dc224e43a4d68070ca6eed494476c8ddd900bf80 --- /dev/null +++ b/assets/deepseek.svg @@ -0,0 +1 @@ +DeepSeek \ No newline at end of file diff --git a/assets/kimi.svg b/assets/kimi.svg new file mode 100644 index 0000000000000000000000000000000000000000..4355c522a2dece99e187d9e5c898a66313f4a374 --- /dev/null +++ b/assets/kimi.svg @@ -0,0 +1 @@ +Kimi \ No newline at end of file diff --git a/assets/qwen.svg b/assets/qwen.svg new file mode 100644 index 0000000000000000000000000000000000000000..a4bb382a6359b82c581fd3e7fb7169fe8fba1657 --- /dev/null +++ b/assets/qwen.svg @@ -0,0 +1 @@ +Qwen \ No newline at end of file diff --git a/components/editor/ask-ai/fake-ask.tsx b/components/editor/ask-ai/fake-ask.tsx new file mode 100644 index 0000000000000000000000000000000000000000..a5ba64265964d6e8d37c1ddd7d451ebb4d77f47c --- /dev/null +++ b/components/editor/ask-ai/fake-ask.tsx @@ -0,0 +1,75 @@ +import { useState } from "react"; +import { useLocalStorage } from "react-use"; +import { ArrowUp } from "lucide-react"; +import { useRouter } from "next/navigation"; + +import { Button } from "@/components/ui/button"; +import { useLoginModal } from "@/components/contexts/login-context"; +import { PromptBuilder } from "./prompt-builder"; +import { EnhancedSettings } from "@/types"; +import { Settings } from "./settings"; + +export const FakeAskAi = () => { + const router = useRouter(); + const [prompt, setPrompt] = useState(""); + const [openProvider, setOpenProvider] = useState(false); + const [enhancedSettings, setEnhancedSettings, removeEnhancedSettings] = + useLocalStorage("deepsite-enhancedSettings", { + isActive: true, + primaryColor: undefined, + secondaryColor: undefined, + theme: undefined, + }); + const [, setPromptStorage] = useLocalStorage("prompt", ""); + + const callAi = async () => { + setPromptStorage(prompt); + router.push("/projects/new"); + }; + + // todo redirect to login + set prompt in storage, then redirect to projects/new + set the prompt in the state + + return ( +
+
+
+