mirror of
https://github.com/jjbrunton/Sauci.git
synced 2026-10-31 18:19:43 +00:00
Update
This commit is contained in:
1 parent
edcc5a6670
commit
1b3f1d9409
45 files changed
+14500
-185
No files matched your search
@@ -3,6 +3,7 @@ import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Checkbox } from '@/components/ui/checkbox';
|
||||
import { Textarea } from '@/components/ui/textarea';
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
@@ -44,6 +45,8 @@ export function AiGeneratorDialog({
|
||||
// Default tone based on pack's explicit flag (5 for explicit packs, 3 for non-explicit)
|
||||
const [tone, setTone] = useState<ToneLevel>(context?.isExplicit ? 5 : 3);
|
||||
const isExplicit = tone >= 4; // For other generators that still use boolean
|
||||
const [crudeLang, setCrudeLang] = useState(false);
|
||||
const [inspiration, setInspiration] = useState('');
|
||||
|
||||
// Update tone when dialog opens with new context
|
||||
useEffect(() => {
|
||||
@@ -65,26 +68,26 @@ export function AiGeneratorDialog({
|
||||
setLoading(true);
|
||||
try {
|
||||
if (type === 'pack') {
|
||||
const result = await generatePack(context?.categoryName, isExplicit);
|
||||
const result = await generatePack(context?.categoryName, isExplicit, crudeLang, inspiration || undefined);
|
||||
setGeneratedPack(result);
|
||||
} else if (type === 'questions') {
|
||||
if (!context?.packName) {
|
||||
toast.error('Pack name is required');
|
||||
return;
|
||||
}
|
||||
const result = await generateQuestions(context.packName, count, undefined, tone, context.packDescription || undefined, context.existingQuestions);
|
||||
const result = await generateQuestions(context.packName, count, undefined, tone, context.packDescription || undefined, context.existingQuestions, crudeLang, inspiration || undefined);
|
||||
setGeneratedQuestions(result);
|
||||
// Select all questions by default
|
||||
setSelectedQuestionIndices(new Set(result.map((_, i) => i)));
|
||||
} else if (type === 'category-ideas') {
|
||||
const result = await suggestCategories(context?.existingCategories || [], isExplicit);
|
||||
const result = await suggestCategories(context?.existingCategories || [], isExplicit, crudeLang, inspiration || undefined);
|
||||
setGeneratedIdeas(result);
|
||||
} else if (type === 'category-pack-ideas') {
|
||||
if (!context?.categoryName) {
|
||||
toast.error('Category name is required');
|
||||
return;
|
||||
}
|
||||
const result = await suggestPacks(context.categoryName, context?.existingPacks || [], isExplicit);
|
||||
const result = await suggestPacks(context.categoryName, context?.existingPacks || [], isExplicit, crudeLang, inspiration || undefined);
|
||||
setGeneratedPackIdeas(result);
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -136,6 +139,8 @@ export function AiGeneratorDialog({
|
||||
setGeneratedIdeas([]);
|
||||
setGeneratedPackIdeas([]);
|
||||
setSelectedQuestionIndices(new Set());
|
||||
setCrudeLang(false);
|
||||
setInspiration('');
|
||||
onOpenChange(false);
|
||||
};
|
||||
|
||||
@@ -212,6 +217,33 @@ export function AiGeneratorDialog({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Crude Language Toggle */}
|
||||
<div className="flex items-center space-x-2">
|
||||
<Switch
|
||||
id="crude-lang"
|
||||
checked={crudeLang}
|
||||
onCheckedChange={setCrudeLang}
|
||||
/>
|
||||
<Label htmlFor="crude-lang">Crude Language</Label>
|
||||
<span className="text-xs text-muted-foreground">(vulgar, raw, everyday explicit words)</span>
|
||||
</div>
|
||||
|
||||
{/* Inspiration/Suggestions Textarea */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="inspiration">Inspiration / Suggestions (optional)</Label>
|
||||
<Textarea
|
||||
id="inspiration"
|
||||
placeholder="Provide any themes, ideas, or guidance for the AI to consider..."
|
||||
value={inspiration}
|
||||
onChange={(e) => setInspiration(e.target.value)}
|
||||
rows={3}
|
||||
className="resize-none"
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Add freetext suggestions to guide the AI generation
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Context info */}
|
||||
{context?.categoryName && (
|
||||
<div className="rounded-md bg-muted p-3 text-sm">
|
||||
|
||||
@@ -58,13 +58,26 @@ export interface GeneratedQuestion {
|
||||
intensity: number;
|
||||
}
|
||||
|
||||
export async function generatePack(categoryName?: string, explicit: boolean = false): Promise<GeneratedPack> {
|
||||
export async function generatePack(
|
||||
categoryName?: string,
|
||||
explicit: boolean = false,
|
||||
crudeLang: boolean = false,
|
||||
inspiration?: string
|
||||
): Promise<GeneratedPack> {
|
||||
const openai = getOpenAI();
|
||||
|
||||
const explicitInstruction = explicit
|
||||
? 'Include bold, spicy, and uncensored themes (NSFW is allowed).'
|
||||
: 'Do NOT include any explicit or NSFW themes. Keep it romantic, emotional, playful, and clean.';
|
||||
|
||||
const crudeLangInstruction = crudeLang
|
||||
? 'Use crude, vulgar, and raw language. Be blunt and use everyday explicit words.'
|
||||
: 'Use tasteful, refined language. Avoid crude or vulgar terms even for explicit content.';
|
||||
|
||||
const inspirationInstruction = inspiration
|
||||
? `\n\nINSPIRATION/GUIDANCE FROM ADMIN:\n${inspiration}\n\nUse the above inspiration to guide your generation.`
|
||||
: '';
|
||||
|
||||
const appContext = `This is an ACTIVITY-FOCUSED app where couples swipe on activity proposals.
|
||||
Each partner independently swipes Like/Dislike/Maybe, and when both swipe positively they "match".
|
||||
Packs contain collections of activities to try together (date ideas, intimate experiences, adventures, challenges, etc.).
|
||||
@@ -78,6 +91,7 @@ This is NOT a Q&A app - it's about discovering shared interests in activities.`;
|
||||
The pack should contain a themed collection of activities couples can explore together.
|
||||
|
||||
${explicitInstruction}
|
||||
${crudeLangInstruction}${inspirationInstruction}
|
||||
|
||||
Return a JSON object with:
|
||||
- name: A catchy, engaging pack name (3-6 words) that evokes activities/experiences
|
||||
@@ -91,6 +105,7 @@ This is NOT a Q&A app - it's about discovering shared interests in activities.`;
|
||||
The pack should contain a themed collection of activities couples can explore together.
|
||||
|
||||
${explicitInstruction}
|
||||
${crudeLangInstruction}${inspirationInstruction}
|
||||
|
||||
Return a JSON object with:
|
||||
- name: A catchy, engaging pack name (3-6 words) that evokes activities/experiences
|
||||
@@ -198,12 +213,22 @@ export async function generateQuestions(
|
||||
intensity?: number,
|
||||
tone: ToneLevel = 3,
|
||||
packDescription?: string,
|
||||
existingQuestions?: string[]
|
||||
existingQuestions?: string[],
|
||||
crudeLang: boolean = false,
|
||||
inspiration?: string
|
||||
): Promise<GeneratedQuestion[]> {
|
||||
const openai = getOpenAI();
|
||||
const isClean = tone === 0;
|
||||
const isExplicit = tone >= 4;
|
||||
|
||||
const crudeLangInstruction = crudeLang
|
||||
? '\n\nCRUDE LANGUAGE: Use crude, vulgar, raw language throughout. Be blunt, direct, and use everyday explicit words like people actually use in real life. Avoid euphemisms or clinical terms.'
|
||||
: '\n\nLANGUAGE STYLE: Use tasteful, refined language. Avoid crude or vulgar terms. For explicit content, use direct but non-crude terms (e.g., "oral sex" not "blowjob", "have sex" not "fuck").';
|
||||
|
||||
const inspirationInstruction = inspiration
|
||||
? `\n\nINSPIRATION/GUIDANCE FROM ADMIN:\n${inspiration}\n\nUse the above inspiration to guide the types of questions you generate.`
|
||||
: '';
|
||||
|
||||
const intensityInstruction = isClean
|
||||
? 'All questions should be intensity level 1 (non-physical activities).'
|
||||
: intensity
|
||||
@@ -266,7 +291,7 @@ CRITICAL: Generate completely NEW and DIFFERENT questions. Do not repeat any of
|
||||
${INTENSITY_GUIDE_SHORT}
|
||||
|
||||
${intensityInstruction}
|
||||
${toneInstruction}${explicitWarning}
|
||||
${toneInstruction}${explicitWarning}${crudeLangInstruction}${inspirationInstruction}
|
||||
|
||||
IMPORTANT: The app uses a swipe-based interface (Like/Dislike/Maybe).
|
||||
Cards should be "Proposals" for specific actions, NOT interview questions.
|
||||
@@ -371,7 +396,9 @@ export interface GeneratedCategoryIdea {
|
||||
|
||||
export async function suggestCategories(
|
||||
existingCategories: string[],
|
||||
explicit: boolean
|
||||
explicit: boolean,
|
||||
crudeLang: boolean = false,
|
||||
inspiration?: string
|
||||
): Promise<GeneratedCategoryIdea[]> {
|
||||
const openai = getOpenAI();
|
||||
const existingList = existingCategories.length > 0
|
||||
@@ -382,6 +409,14 @@ export async function suggestCategories(
|
||||
? 'Include bold, spicy, and explicitly intimate categories (NSFW is allowed).'
|
||||
: 'Do NOT include any explicit or NSFW themes. Keep it romantic, emotional, playful, and clean.';
|
||||
|
||||
const crudeLangInstruction = crudeLang
|
||||
? '\nUse crude, vulgar, and raw language in the names and descriptions.'
|
||||
: '\nUse tasteful, refined language. Avoid crude or vulgar terms.';
|
||||
|
||||
const inspirationInstruction = inspiration
|
||||
? `\n\nINSPIRATION/GUIDANCE FROM ADMIN:\n${inspiration}\n\nUse the above inspiration to guide your category suggestions.`
|
||||
: '';
|
||||
|
||||
const prompt = `Here are the current categories in our couples' activity/intimacy app: ${existingList}.
|
||||
|
||||
IMPORTANT - HOW THE APP WORKS:
|
||||
@@ -392,7 +427,7 @@ IMPORTANT - HOW THE APP WORKS:
|
||||
- This is NOT a Q&A app - it's about discovering shared interests in activities to do together
|
||||
|
||||
Suggest 5 NEW, UNIQUE category ideas that differ from the existing ones.
|
||||
${explicitInstruction}
|
||||
${explicitInstruction}${crudeLangInstruction}${inspirationInstruction}
|
||||
|
||||
Return a JSON object with an "ideas" array containing 5 objects, where each object has:
|
||||
- name: Category name (1-3 words)
|
||||
@@ -429,7 +464,9 @@ export interface GeneratedPackIdea {
|
||||
export async function suggestPacks(
|
||||
categoryName: string,
|
||||
existingPacks: string[],
|
||||
explicit: boolean
|
||||
explicit: boolean,
|
||||
crudeLang: boolean = false,
|
||||
inspiration?: string
|
||||
): Promise<GeneratedPackIdea[]> {
|
||||
const openai = getOpenAI();
|
||||
const existingList = existingPacks.length > 0
|
||||
@@ -440,6 +477,14 @@ export async function suggestPacks(
|
||||
? 'Include bold, spicy, and uncensored pack ideas (NSFW is allowed).'
|
||||
: 'Do NOT include any explicit or NSFW themes. Keep it romantic, emotional, playful, and clean.';
|
||||
|
||||
const crudeLangInstruction = crudeLang
|
||||
? '\nUse crude, vulgar, and raw language in the pack names and descriptions.'
|
||||
: '\nUse tasteful, refined language. Avoid crude or vulgar terms.';
|
||||
|
||||
const inspirationInstruction = inspiration
|
||||
? `\n\nINSPIRATION/GUIDANCE FROM ADMIN:\n${inspiration}\n\nUse the above inspiration to guide your pack suggestions.`
|
||||
: '';
|
||||
|
||||
const prompt = `We are building activity packs for the category "${categoryName}" in a couples' intimacy app.
|
||||
|
||||
IMPORTANT - HOW THE APP WORKS:
|
||||
@@ -459,7 +504,7 @@ PACK THEMES should focus on:
|
||||
Existing packs in this category: ${existingList}.
|
||||
|
||||
Suggest 5 NEW, UNIQUE pack ideas that fit this category and differ from existing ones.
|
||||
${explicitInstruction}
|
||||
${explicitInstruction}${crudeLangInstruction}${inspirationInstruction}
|
||||
|
||||
Return a JSON object with an "ideas" array containing 5 objects, where each object has:
|
||||
- name: Pack name (catchy, 3-6 words) - should evoke activities/experiences, not questions
|
||||
|
||||
Reference in new issue
Block a user