-
-
Notifications
You must be signed in to change notification settings - Fork 441
Refactor AI Generation with AI SDK v5 #210
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d529c62
aed7871
b645e4d
9a1627d
f04f8e8
c8398a7
9ebb2f4
fc3e80f
eb6a62d
10c1210
d21f6f4
9b099ca
7255d70
b892b61
9c68cae
57c92e2
d9fcca4
6ddf2c0
df39802
e014b2c
b4ee35a
8c02946
8a08265
e818d31
5c433ce
bc31efb
ae47a08
5f4ac1a
76ca58c
e5fb180
4a4b5b8
3f10d38
dd95ea8
e9b1b58
6c0ccd9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,68 @@ | ||||||||||||||||||||||||||
import { AIPromptData } from "@/types/ai"; | ||||||||||||||||||||||||||
import { buildUserContentPartsFromPromptData } from "@/utils/ai/message-converter"; | ||||||||||||||||||||||||||
import { baseProviderOptions, MODELS } from "@/utils/ai/providers"; | ||||||||||||||||||||||||||
import { smoothStream, streamText } from "ai"; | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
export async function POST(req: Request) { | ||||||||||||||||||||||||||
// TODO: Add session and subscription check, this should be a Pro only feature | ||||||||||||||||||||||||||
// TODO: Record AI usage, providing the model id to `recordAIUsage` function | ||||||||||||||||||||||||||
Comment on lines
+7
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The enhance-prompt API route is missing critical security checks and usage tracking. It currently allows unrestricted access to the AI prompt enhancement feature without session validation or subscription verification. View DetailsAnalysisThe TODO comments on lines 7-8 indicate that this API endpoint is missing essential security mechanisms:
This creates a security vulnerability where:
The implementation should add the same validation pattern used in the |
||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
const body = await req.json(); | ||||||||||||||||||||||||||
const { prompt: _prompt, promptData }: { prompt: string; promptData: AIPromptData } = body; | ||||||||||||||||||||||||||
const userContentParts = buildUserContentPartsFromPromptData(promptData); | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
Comment on lines
+10
to
+13
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Validate request body and fail fast with 400 on invalid input. - const body = await req.json();
- const { prompt: _prompt, promptData }: { prompt: string; promptData: AIPromptData } = body;
+ const body = await req.json();
+ const { promptData }: { prompt: string; promptData: AIPromptData } = body ?? {};
+ if (!promptData || typeof promptData.content !== "string") {
+ return new Response(JSON.stringify({ error: "Invalid body: promptData.content is required" }), {
+ status: 400,
+ headers: { "content-type": "application/json" },
+ });
+ } 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||
const result = streamText({ | ||||||||||||||||||||||||||
system: ENHANCE_PROMPT_SYSTEM, | ||||||||||||||||||||||||||
messages: [ | ||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||
role: "user", | ||||||||||||||||||||||||||
content: userContentParts, | ||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||
], | ||||||||||||||||||||||||||
model: MODELS.promptEnhancement, | ||||||||||||||||||||||||||
providerOptions: baseProviderOptions, | ||||||||||||||||||||||||||
experimental_transform: smoothStream({ | ||||||||||||||||||||||||||
delayInMs: 10, | ||||||||||||||||||||||||||
chunking: "word", | ||||||||||||||||||||||||||
}), | ||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
return result.toUIMessageStreamResponse(); | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
const ENHANCE_PROMPT_SYSTEM = `# Role | ||||||||||||||||||||||||||
You are a prompt refinement specialist for a shadcn/ui theme generator. Rewrite the user's input into a precise, ready-to-use prompt that preserves the original intent, language, and tone. Write as the requester of the theme, not as an assistant. | ||||||||||||||||||||||||||
# Core principles | ||||||||||||||||||||||||||
- Language matching: respond in the exact same language as the user | ||||||||||||||||||||||||||
- Cultural context: respect regional expressions, slang, and cultural references | ||||||||||||||||||||||||||
- Length limit: output must NOT exceed 500 characters | ||||||||||||||||||||||||||
- If when analyzing the user's prompt you recognize a vibe, style, or visual reference, include it in the output. | ||||||||||||||||||||||||||
# Mentions | ||||||||||||||||||||||||||
- User input may include mentions like @Current Theme or @PresetName. Mentions are always in the format of @[label]. | ||||||||||||||||||||||||||
- Mentions are predefined styles that are intended to be used as the base or reference for the theme. | ||||||||||||||||||||||||||
- Preserve them verbatim in the output text (same labels, same order if possible). | ||||||||||||||||||||||||||
- Do not invent new mentions. Only keep and reposition mentions that appear in the user's prompt or in the provided mention list. | ||||||||||||||||||||||||||
- Avoid repeating the same mention multiple times. | ||||||||||||||||||||||||||
# Enhancement guidelines | ||||||||||||||||||||||||||
- If the prompt is vague, add concrete visual details (colors, mood, typography, style references) | ||||||||||||||||||||||||||
- If it mentions a brand or style, include relevant design characteristics | ||||||||||||||||||||||||||
- If it's already detailed, clarify ambiguous parts and tighten wording | ||||||||||||||||||||||||||
- Preserve any specific requests (colors, fonts, mood, etc.) | ||||||||||||||||||||||||||
- Add context that helps the theme generator understand the desired aesthetic | ||||||||||||||||||||||||||
# Output rules | ||||||||||||||||||||||||||
- Output a single line of plain text suitable to paste into the Generate Theme tool | ||||||||||||||||||||||||||
- No greetings or meta commentary; do not address the user | ||||||||||||||||||||||||||
- Do not narrate with phrases like "I'm seeing", "let's", "alright", or "what you want is" | ||||||||||||||||||||||||||
- No bullets, no quotes, no markdown, no JSON | ||||||||||||||||||||||||||
# What NOT to do | ||||||||||||||||||||||||||
- Don't change the user's core request | ||||||||||||||||||||||||||
- Don't add conflicting style directions | ||||||||||||||||||||||||||
- Don't exceed 500 characters | ||||||||||||||||||||||||||
- Don't use a different language than the user | ||||||||||||||||||||||||||
- Do not list the mentions' properties in the enhanced prompt. | ||||||||||||||||||||||||||
- Do not use em dashes (—)`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Disable image controls while uploading or when max reached.
Also gate the hidden input to prevent concurrent uploads.
📝 Committable suggestion
🤖 Prompt for AI Agents