feat(messages): add new prompts and translations for generating examples

This commit is contained in:
Fatih Kadir Akın
2025-12-29 01:23:21 +03:00
parent a2d313bbbf
commit e09e688c3d
17 changed files with 357 additions and 15 deletions
+7 -1
View File
@@ -1224,6 +1224,12 @@
"onlyPromptsChat": "يتم دعم استيراد {library} فقط.",
"desktopOnly": "للحاسوب فقط",
"desktopOnlyDescription": "يتطلب منشئ الأوامر شاشة أكبر ليعمل بشكل صحيح. يرجى فتح هذه الصفحة على جهاز كمبيوتر مكتبي أو محمول.",
"browsePrompts": "تصفح الأوامر"
"browsePrompts": "تصفح الأوامر",
"random": "عشوائي",
"generateRandom": "إنشاء مثال عشوائي بالذكاء الاصطناعي",
"loginToGenerate": "يرجى تسجيل الدخول لإنشاء الأمثلة",
"rateLimitExceeded": "يرجى الانتظار {seconds} ثانية قبل الإنشاء مرة أخرى",
"generateFailed": "فشل في إنشاء المثال",
"exampleGenerated": "تم إنشاء مثال جديد!"
}
}
+7 -1
View File
@@ -1224,6 +1224,12 @@
"onlyPromptsChat": "Nur {library}-Importe werden unterstützt.",
"desktopOnly": "Nur für Desktop",
"desktopOnlyDescription": "Der Prompt Builder benötigt einen größeren Bildschirm. Bitte öffnen Sie diese Seite auf einem Desktop- oder Laptop-Computer.",
"browsePrompts": "Prompts durchsuchen"
"browsePrompts": "Prompts durchsuchen",
"random": "Zufällig",
"generateRandom": "Zufälliges Beispiel mit KI generieren",
"loginToGenerate": "Bitte anmelden, um Beispiele zu generieren",
"rateLimitExceeded": "Bitte warten Sie {seconds} Sekunden, bevor Sie erneut generieren",
"generateFailed": "Beispiel konnte nicht generiert werden",
"exampleGenerated": "Neues Beispiel generiert!"
}
}
+7 -1
View File
@@ -1224,6 +1224,12 @@
"onlyPromptsChat": "Υποστηρίζονται μόνο εισαγωγές {library}.",
"desktopOnly": "Μόνο για υπολογιστή",
"desktopOnlyDescription": "Ο Prompt Builder απαιτεί μεγαλύτερη οθόνη για να λειτουργήσει σωστά. Παρακαλώ ανοίξτε αυτή τη σελίδα σε επιτραπέζιο ή φορητό υπολογιστή.",
"browsePrompts": "Περιήγηση Prompts"
"browsePrompts": "Περιήγηση Prompts",
"random": "Τυχαίο",
"generateRandom": "Δημιουργία τυχαίου παραδείγματος με AI",
"loginToGenerate": "Συνδεθείτε για να δημιουργήσετε παραδείγματα",
"rateLimitExceeded": "Περιμένετε {seconds} δευτερόλεπτα πριν δημιουργήσετε ξανά",
"generateFailed": "Αποτυχία δημιουργίας παραδείγματος",
"exampleGenerated": "Δημιουργήθηκε νέο παράδειγμα!"
}
}
+7 -1
View File
@@ -1224,6 +1224,12 @@
"onlyPromptsChat": "Only {library} imports are supported.",
"desktopOnly": "Desktop Only",
"desktopOnlyDescription": "The Prompt Builder requires a larger screen to work properly. Please open this page on a desktop or laptop computer.",
"browsePrompts": "Browse Prompts"
"browsePrompts": "Browse Prompts",
"random": "Random",
"generateRandom": "Generate a random example with AI",
"loginToGenerate": "Please log in to generate examples",
"rateLimitExceeded": "Please wait {seconds} seconds before generating again",
"generateFailed": "Failed to generate example",
"exampleGenerated": "New example generated!"
}
}
+7 -1
View File
@@ -1224,6 +1224,12 @@
"onlyPromptsChat": "Solo se admiten importaciones de {library}.",
"desktopOnly": "Solo escritorio",
"desktopOnlyDescription": "El Constructor de Prompts requiere una pantalla más grande para funcionar correctamente. Por favor, abre esta página en una computadora de escritorio o portátil.",
"browsePrompts": "Explorar Prompts"
"browsePrompts": "Explorar Prompts",
"random": "Aleatorio",
"generateRandom": "Generar ejemplo aleatorio con IA",
"loginToGenerate": "Inicia sesión para generar ejemplos",
"rateLimitExceeded": "Espera {seconds} segundos antes de generar de nuevo",
"generateFailed": "Error al generar ejemplo",
"exampleGenerated": "¡Nuevo ejemplo generado!"
}
}
+7 -1
View File
@@ -1224,6 +1224,12 @@
"onlyPromptsChat": "Seuls les imports {library} sont pris en charge.",
"desktopOnly": "Bureau uniquement",
"desktopOnlyDescription": "Le Prompt Builder nécessite un écran plus grand pour fonctionner correctement. Veuillez ouvrir cette page sur un ordinateur de bureau ou portable.",
"browsePrompts": "Parcourir les Prompts"
"browsePrompts": "Parcourir les Prompts",
"random": "Aléatoire",
"generateRandom": "Générer un exemple aléatoire avec l'IA",
"loginToGenerate": "Veuillez vous connecter pour générer des exemples",
"rateLimitExceeded": "Veuillez attendre {seconds} secondes avant de générer à nouveau",
"generateFailed": "Échec de la génération de l'exemple",
"exampleGenerated": "Nouvel exemple généré !"
}
}
+7 -1
View File
@@ -1224,6 +1224,12 @@
"onlyPromptsChat": "נתמכים רק ייבואים של {library}.",
"desktopOnly": "למחשב בלבד",
"desktopOnlyDescription": "בונה הפרומפטים דורש מסך גדול יותר כדי לפעול כראוי. אנא פתח דף זה במחשב שולחני או נייד.",
"browsePrompts": "עיין בפרומפטים"
"browsePrompts": "עיין בפרומפטים",
"random": "אקראי",
"generateRandom": "צור דוגמה אקראית עם AI",
"loginToGenerate": "התחבר כדי ליצור דוגמאות",
"rateLimitExceeded": "המתן {seconds} שניות לפני יצירה נוספת",
"generateFailed": "יצירת הדוגמה נכשלה",
"exampleGenerated": "דוגמה חדשה נוצרה!"
}
}
+7 -1
View File
@@ -1224,6 +1224,12 @@
"onlyPromptsChat": "Sono supportate solo le importazioni di {library}.",
"desktopOnly": "Solo Desktop",
"desktopOnlyDescription": "Il Prompt Builder richiede uno schermo più grande per funzionare correttamente. Si prega di aprire questa pagina su un computer desktop o laptop.",
"browsePrompts": "Esplora Prompt"
"browsePrompts": "Esplora Prompt",
"random": "Casuale",
"generateRandom": "Genera esempio casuale con AI",
"loginToGenerate": "Accedi per generare esempi",
"rateLimitExceeded": "Attendi {seconds} secondi prima di generare di nuovo",
"generateFailed": "Generazione esempio fallita",
"exampleGenerated": "Nuovo esempio generato!"
}
}
+7 -1
View File
@@ -1224,6 +1224,12 @@
"onlyPromptsChat": "{library}のインポートのみがサポートされています。",
"desktopOnly": "デスクトップ専用",
"desktopOnlyDescription": "プロンプトビルダーは、正常に動作するために大きな画面が必要です。デスクトップまたはラップトップコンピュータでこのページを開いてください。",
"browsePrompts": "プロンプトを閲覧"
"browsePrompts": "プロンプトを閲覧",
"random": "ランダム",
"generateRandom": "AIでランダムな例を生成",
"loginToGenerate": "例を生成するにはログインしてください",
"rateLimitExceeded": "再生成まで{seconds}秒お待ちください",
"generateFailed": "例の生成に失敗しました",
"exampleGenerated": "新しい例が生成されました!"
}
}
+7 -1
View File
@@ -1224,6 +1224,12 @@
"onlyPromptsChat": "{library} 가져오기만 지원됩니다.",
"desktopOnly": "데스크톱 전용",
"desktopOnlyDescription": "프롬프트 빌더는 제대로 작동하려면 더 큰 화면이 필요합니다. 데스크톱이나 노트북 컴퓨터에서 이 페이지를 열어주세요.",
"browsePrompts": "프롬프트 둘러보기"
"browsePrompts": "프롬프트 둘러보기",
"random": "랜덤",
"generateRandom": "AI로 랜덤 예제 생성",
"loginToGenerate": "예제를 생성하려면 로그인하세요",
"rateLimitExceeded": "다시 생성하려면 {seconds}초 기다려주세요",
"generateFailed": "예제 생성 실패",
"exampleGenerated": "새 예제가 생성되었습니다!"
}
}
+7 -1
View File
@@ -1224,6 +1224,12 @@
"onlyPromptsChat": "Apenas importações de {library} são suportadas.",
"desktopOnly": "Apenas Desktop",
"desktopOnlyDescription": "O Prompt Builder requer uma tela maior para funcionar corretamente. Por favor, abra esta página em um computador desktop ou laptop.",
"browsePrompts": "Explorar Prompts"
"browsePrompts": "Explorar Prompts",
"random": "Aleatório",
"generateRandom": "Gerar exemplo aleatório com IA",
"loginToGenerate": "Faça login para gerar exemplos",
"rateLimitExceeded": "Aguarde {seconds} segundos antes de gerar novamente",
"generateFailed": "Falha ao gerar exemplo",
"exampleGenerated": "Novo exemplo gerado!"
}
}
+7 -1
View File
@@ -1224,6 +1224,12 @@
"onlyPromptsChat": "Поддерживаются только импорты {library}.",
"desktopOnly": "Только для ПК",
"desktopOnlyDescription": "Конструктор промптов требует большего экрана для корректной работы. Пожалуйста, откройте эту страницу на настольном компьютере или ноутбуке.",
"browsePrompts": "Просмотреть промпты"
"browsePrompts": "Просмотреть промпты",
"random": "Случайный",
"generateRandom": "Сгенерировать случайный пример с помощью ИИ",
"loginToGenerate": "Войдите, чтобы генерировать примеры",
"rateLimitExceeded": "Подождите {seconds} секунд перед повторной генерацией",
"generateFailed": "Не удалось сгенерировать пример",
"exampleGenerated": "Новый пример сгенерирован!"
}
}
+7 -1
View File
@@ -1224,6 +1224,12 @@
"onlyPromptsChat": "Sadece {library} importları destekleniyor.",
"desktopOnly": "Yalnızca Masaüstü",
"desktopOnlyDescription": "Prompt Oluşturucu düzgün çalışması için daha büyük bir ekran gerektirir. Lütfen bu sayfayı bir masaüstü veya dizüstü bilgisayarda açın.",
"browsePrompts": "Promptlara Göz At"
"browsePrompts": "Promptlara Göz At",
"random": "Rastgele",
"generateRandom": "AI ile rastgele örnek oluştur",
"loginToGenerate": "Örnek oluşturmak için giriş yapın",
"rateLimitExceeded": "Tekrar oluşturmak için {seconds} saniye bekleyin",
"generateFailed": "Örnek oluşturulamadı",
"exampleGenerated": "Yeni örnek oluşturuldu!"
}
}
+7 -1
View File
@@ -1224,6 +1224,12 @@
"onlyPromptsChat": "仅支持 {library} 导入。",
"desktopOnly": "仅限桌面端",
"desktopOnlyDescription": "提示词构建器需要更大的屏幕才能正常工作。请在台式电脑或笔记本电脑上打开此页面。",
"browsePrompts": "浏览提示词"
"browsePrompts": "浏览提示词",
"random": "随机",
"generateRandom": "使用AI生成随机示例",
"loginToGenerate": "请登录以生成示例",
"rateLimitExceeded": "请等待{seconds}秒后再生成",
"generateFailed": "生成示例失败",
"exampleGenerated": "新示例已生成!"
}
}
@@ -0,0 +1,155 @@
import { NextRequest } from "next/server";
import OpenAI from "openai";
import { auth } from "@/lib/auth";
import { getConfig } from "@/lib/config";
import { loadPrompt, interpolatePrompt } from "@/lib/ai/load-prompt";
import { TYPE_DEFINITIONS } from "@/data/type-definitions";
import {
EXAMPLE_VIDEO,
EXAMPLE_AUDIO,
EXAMPLE_IMAGE,
EXAMPLE_CHAT,
DEFAULT_CODE,
} from "@/components/ide/examples";
const generateExamplePrompt = loadPrompt("src/lib/ai/generate-example.prompt.yml");
const GENERATIVE_MODEL = process.env.OPENAI_GENERATIVE_MODEL || "gpt-4o";
// Rate limiting: 1 request per minute per user
const RATE_LIMIT_WINDOW_MS = 60 * 1000;
const RATE_LIMIT_MAX_REQUESTS = 1;
const rateLimitStore = new Map<string, { count: number; resetAt: number }>();
function checkRateLimit(userId: string): { allowed: boolean; remaining: number; resetIn: number } {
const now = Date.now();
const userLimit = rateLimitStore.get(userId);
if (!userLimit || now > userLimit.resetAt) {
rateLimitStore.set(userId, { count: 1, resetAt: now + RATE_LIMIT_WINDOW_MS });
return { allowed: true, remaining: RATE_LIMIT_MAX_REQUESTS - 1, resetIn: RATE_LIMIT_WINDOW_MS };
}
if (userLimit.count >= RATE_LIMIT_MAX_REQUESTS) {
return { allowed: false, remaining: 0, resetIn: userLimit.resetAt - now };
}
userLimit.count++;
return { allowed: true, remaining: RATE_LIMIT_MAX_REQUESTS - userLimit.count, resetIn: userLimit.resetAt - now };
}
export async function POST(request: NextRequest) {
const session = await auth();
if (!session?.user) {
return new Response(JSON.stringify({ error: "Unauthorized. Please log in to generate examples." }), {
status: 401,
headers: { "Content-Type": "application/json" },
});
}
// Check rate limit
const userId = session.user.id || session.user.email || "anonymous";
const rateLimit = checkRateLimit(userId);
if (!rateLimit.allowed) {
return new Response(JSON.stringify({
error: "Rate limit exceeded. You can generate one example per minute.",
resetIn: Math.ceil(rateLimit.resetIn / 1000)
}), {
status: 429,
headers: {
"Content-Type": "application/json",
"X-RateLimit-Remaining": "0",
"X-RateLimit-Reset": String(Math.ceil(rateLimit.resetIn / 1000)),
},
});
}
const config = await getConfig();
if (!config.features.aiGeneration) {
return new Response(JSON.stringify({ error: "AI generation is not enabled" }), {
status: 403,
headers: { "Content-Type": "application/json" },
});
}
const apiKey = process.env.OPENAI_API_KEY;
if (!apiKey) {
return new Response(JSON.stringify({ error: "OpenAI API key not configured" }), {
status: 500,
headers: { "Content-Type": "application/json" },
});
}
try {
const openai = new OpenAI({
apiKey,
baseURL: process.env.OPENAI_BASE_URL || undefined,
});
// Prepare existing examples summary
const existingExamples = `
### Video Example (Samurai in bamboo forest theme)
${EXAMPLE_VIDEO.substring(0, 500)}...
### Audio Example (Synthwave music theme)
${EXAMPLE_AUDIO.substring(0, 500)}...
### Image Example (Library in tree theme)
${EXAMPLE_IMAGE.substring(0, 500)}...
### Chat Example (Code reviewer theme)
${EXAMPLE_CHAT}
### Default Builder Example (TypeScript code review theme)
${DEFAULT_CODE}
`;
// Build messages with interpolated variables
const systemMessage = generateExamplePrompt.messages.find(m => m.role === "system");
const userMessage = generateExamplePrompt.messages.find(m => m.role === "user");
const messages: OpenAI.Chat.ChatCompletionMessageParam[] = [
{
role: "system",
content: interpolatePrompt(systemMessage?.content || "", {
typeDefinitions: TYPE_DEFINITIONS,
}),
},
{
role: "user",
content: interpolatePrompt(userMessage?.content || "", {
existingExamples,
}),
},
];
const response = await openai.chat.completions.create({
model: GENERATIVE_MODEL,
messages,
temperature: generateExamplePrompt.modelParameters?.temperature || 0.9,
max_tokens: generateExamplePrompt.modelParameters?.maxTokens || 2000,
});
const generatedCode = response.choices[0]?.message?.content || "";
// Clean up the response - remove markdown code blocks if present
let cleanCode = generatedCode.trim();
if (cleanCode.startsWith("```typescript") || cleanCode.startsWith("```ts")) {
cleanCode = cleanCode.replace(/^```(?:typescript|ts)\n?/, "").replace(/\n?```$/, "");
} else if (cleanCode.startsWith("```")) {
cleanCode = cleanCode.replace(/^```\n?/, "").replace(/\n?```$/, "");
}
return new Response(JSON.stringify({ code: cleanCode.trim() }), {
status: 200,
headers: { "Content-Type": "application/json" },
});
} catch (error) {
console.error("Generate example error:", error);
return new Response(JSON.stringify({ error: "Failed to generate example" }), {
status: 500,
headers: { "Content-Type": "application/json" },
});
}
}
+54 -1
View File
@@ -6,7 +6,8 @@ import Editor from "@monaco-editor/react";
import { useTheme } from "next-themes";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Button } from "@/components/ui/button";
import { Copy, Play, RotateCcw, Code2, FileJson, FileText, Video, Music, Image as ImageIcon, MessageSquare, Sparkles, Terminal, AlertCircle, XCircle, ChevronDown, ChevronUp, ChevronRight } from "lucide-react";
import { Copy, Play, RotateCcw, Code2, FileJson, FileText, Video, Music, Image as ImageIcon, MessageSquare, Sparkles, Terminal, AlertCircle, XCircle, ChevronDown, ChevronUp, ChevronRight, Dices, Loader2 } from "lucide-react";
import { useSession } from "next-auth/react";
import { toast } from "sonner";
import { RunPromptButton } from "@/components/prompts/run-prompt-button";
@@ -50,7 +51,9 @@ import {
export function PromptIde() {
const t = useTranslations("ide");
const { theme } = useTheme();
const { data: session } = useSession();
const [code, setCode] = useState(EXAMPLE_IMAGE);
const [isGenerating, setIsGenerating] = useState(false);
const [output, setOutput] = useState<string>("");
const [outputFormat, setOutputFormat] = useState<OutputFormat>("markdown");
const [error, setError] = useState<string | null>(null);
@@ -521,6 +524,41 @@ export function PromptIde() {
setError(null);
}, []);
const generateExample = useCallback(async () => {
if (!session?.user) {
toast.error(t("loginToGenerate"));
return;
}
setIsGenerating(true);
try {
const response = await fetch("/api/prompt-builder/generate-example", {
method: "POST",
headers: { "Content-Type": "application/json" },
});
const data = await response.json();
if (!response.ok) {
if (response.status === 429) {
toast.error(t("rateLimitExceeded", { seconds: data.resetIn }));
} else {
toast.error(data.error || t("generateFailed"));
}
return;
}
if (data.code) {
setCode(data.code);
toast.success(t("exampleGenerated"));
}
} catch {
toast.error(t("generateFailed"));
} finally {
setIsGenerating(false);
}
}, [session, t]);
// Console resize handlers
const handleResizeStart = useCallback((e: React.MouseEvent) => {
e.preventDefault();
@@ -658,6 +696,21 @@ export function PromptIde() {
<Sparkles className="h-3 w-3" />
OpenAI
</Button>
<Button
variant="ghost"
size="sm"
className="h-6 text-xs gap-1 px-2"
onClick={generateExample}
disabled={isGenerating || !session?.user}
title={!session?.user ? t("loginToGenerate") : t("generateRandom")}
>
{isGenerating ? (
<Loader2 className="h-3 w-3 animate-spin" />
) : (
<Dices className="h-3 w-3" />
)}
{t("random")}
</Button>
</div>
</div>
<div className="flex-1">
+50
View File
@@ -0,0 +1,50 @@
name: Generate Example Code
description: Generates creative example code using the prompts.chat library API
model: openai/gpt-4o
modelParameters:
temperature: 0.9
maxTokens: 2000
messages:
- role: system
content: |
You are an expert TypeScript developer who creates creative and inspiring example code using the prompts.chat library.
Your task is to generate a NEW, CREATIVE example that demonstrates the prompts.chat API.
The example should be different from the provided examples - pick a unique theme, domain, or use case.
## API Reference (TypeScript Definitions)
STRICTLY USE THESE TYPES AND METHODS
{{typeDefinitions}}
## Guidelines
1. Pick ONE builder type to focus on: `video()`, `audio()`, `image()` or `chat()`
2. Choose a CREATIVE and UNIQUE theme (not samurai, not library, not code review - something fresh!)
3. Use the fluent chainable API extensively to showcase its power
4. Add helpful comments explaining each section
5. Include the export default block with appropriate output properties:
- For video/audio/image: use `prompt.structure` for json/yaml, `prompt.prompt` for markdown
- For chat: use `prompt.messages` for json/yaml, `prompt.systemPrompt` for markdown
- For builder: use `prompt` for json/yaml, `prompt.content` for markdown
## Creative Theme Ideas (pick something NOT in these lists)
- Sci-fi, fantasy, horror, romance, mystery genres
- Nature, space, underwater, urban, rural settings
- Historical periods, future scenarios
- Different cultures and art styles
- Emotional journeys, action sequences
- Abstract concepts, surreal imagery
## Output Format
Return ONLY the TypeScript code, starting with the import statement.
No markdown code blocks, no explanations - just the raw code.
- role: user
content: |
## Existing Examples (DO NOT copy these themes)
{{existingExamples}}
Generate a completely NEW and CREATIVE example using the prompts.chat library.
Pick a fresh theme that's different from all the examples above.