wondersheets/server/prompts.js

273 lines
12 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Activity-specific prompts for worksheet generation.
* Each prompt is tailored to produce optimal SVG output for its activity type.
*/
const baseRules = `
MANDATORY STYLE & QUALITY RULES — MUST FOLLOW EXACTLY:
- Depict the theme literally and recognizably using standard, cute children's illustration style (e.g. animals look like real animals with big eyes/smiles; no invented blobs, hybrids, pigtails/bows on wrong things, distorted proportions, extra random parts).
- Every visible element MUST be FULLY CLOSED paths (use Z/z to close <path>, or <circle>/<ellipse>/<polygon>/<rect>). NO open paths, NO <line>, NO <polyline> unless closed, NO stroke-only lines without enclosed fill regions.
- Forbidden forever: blobs, distorted/wrong anatomy, floating disconnected lines/parts, random dots/scribbles/noise/artifacts, self-intersecting paths making uncolorable slivers, cut-off/incomplete shapes, inconsistent stroke widths, tiny details, fill="none" on main objects (except holes), any greyscale/shading.
- Stroke: #000000 solid (no dasharray except for traceable writing). Fill: #ffffff on all colorable regions.
- ViewBox: exactly '0 0 500 500'. MAXIMIZE PAGE USAGE. Use the full 500x500 canvas with MINIMAL margins (10-20px). Make the main subject FILL the available space.
- Attributes: single quotes ' only for all XML.
- SVG: complete valid XML — <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 500 500'> ... </svg>. Use smooth curves (C, Q, S) for natural shapes.
- High-quality kid style: bold thick outlines, big simple shapes, cute friendly expressions (big round eyes as circles/ovals, smiling curved mouth), balanced proportions (big head for cuteness), no complexity/noise.
`;
const ageRules = (age) => `
AGE-SPECIFIC RULES — STRICT:
${age <= 4 ?
`- For age ${age}: Ultra-simple (12 huge objects max), stroke width 610px, very large regions (410 total), cartoon-big features, no small details/textures/patterns inside.` :
`- For age ${age}: Slightly more complex (36 elements), stroke 35px, allow small closed interior shapes (e.g. spots as tiny circles), but still bold and clear.`
}
`;
const jsonStructure = (sectionType) => `
Return ONLY valid JSON. No other text, no explanations.
JSON exactly this structure:
{
"title": "Short fun title",
"subtitle": "Clear one-sentence kid instruction",
"sections": [
{
"id": "${sectionType}-main",
"type": "${sectionType}",
"content_svg": "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 500 500'>...FULL complete valid SVG code here...</svg>"
}
]
}
CRITICAL: content_svg MUST be a string with single quotes in SVG attributes. Paths smooth and 100% closed.
`;
export const activityPrompts = {
coloring: (theme, age) => `
You are a professional illustrator of high-quality children's coloring books. Create a BEAUTIFUL, ENGAGING coloring page.
Theme: ${theme}
Age: ${age} years old
YOUR MISSION: Create ONE stunning coloring page featuring the theme in a way that makes children excited to color it.
⚠️ STRICT ACTIVITY RESTRICTION — THIS IS A COLORING PAGE ONLY:
- DO NOT include any numbers, digits, or numerals of any kind
- DO NOT include any letters, words, text, or alphabet characters
- DO NOT include any counting exercises or number recognition
- DO NOT include any mazes, paths to follow, or puzzles
- DO NOT include any tracing lines, dotted lines, or writing practice
- DO NOT include any educational exercises — ONLY pure illustration for coloring
- The ONLY activity is coloring inside the outlined shapes
COLORING PAGE SPECIFIC RULES:
- Create ONE main cute subject (or 2-3 closely related elements) as the centerpiece
- Design 8-20 large, clearly defined CLOSED areas perfect for coloring
- Each colorable region should be satisfyingly large — kids love filling big spaces
- Add cute details that enhance the theme: accessories, background elements, decorations
- Characters should have friendly expressions: big round eyes, gentle smiles
- Include a simple ground line or setting context (grass, clouds, water) if appropriate
- Balance white space — not too crowded, not too empty
- Make outlines bold and confident so young hands can color inside easily
COMPOSITION TIPS:
- Center the main subject or use rule-of-thirds for dynamic layouts
- Vary the sizes of colorable regions for visual interest
- Add 2-4 small decorative elements (stars, hearts, flowers) around the main subject
- Ensure all shapes are CLOSED and ready to be filled with color
${baseRules}
${ageRules(age)}
${jsonStructure('coloring')}
`,
writing: (theme, age) => `
You are an educational illustrator creating handwriting practice worksheets for young children.
Theme: ${theme}
Age: ${age} years old
YOUR MISSION: Create a clean, professional tracing practice worksheet.
IMPORTANT: Randomly choose ONE of these options for what to trace:
- Option A (50% chance): A short WORD related to the theme (2-4 letters, e.g., "SUN", "CAT", "STAR")
- Option B (50% chance): NUMBERS 1-5 (for ages 3-4) or 1-9 (for ages 5-7), showing 3-5 numbers to trace
⚠️ STRICT ACTIVITY RESTRICTION — THIS IS A TRACING WORKSHEET ONLY:
- DO NOT include any mazes, paths to follow, or puzzles
- DO NOT include any counting exercises with objects
- DO NOT include large coloring illustrations
- DO NOT include groups of objects to count
- DO NOT include any decorative shapes, swirls, or random elements
- The ONLY activity is tracing letters OR numbers along dotted lines
🔴 CRITICAL ALIGNMENT & QUALITY RULES — MUST FOLLOW EXACTLY:
BASELINE ALIGNMENT:
- ALL characters in a row MUST sit on the SAME horizontal baseline
- Use a consistent y-coordinate for the bottom of all characters in each row
- Characters must NOT float, sink, or be misaligned with each other
CHARACTER CONSTRUCTION (for both letters AND numbers):
- Use simple <path> elements with stroke-dasharray='8,8' for uniform dots
- Character stroke-width: 4px for clean, visible dots
- Character height: exactly 80px tall
- Character spacing: exactly 70px between character centers
- Use ONLY basic straight lines and simple curves — no fancy flourishes
DOT PATTERN RULES:
- stroke-dasharray='8,8' — uniform 8px dots with 8px gaps
- stroke='#000000' stroke-linecap='round' for round dots
- fill='none' — characters are outlines only, not filled
- Dots must be evenly spaced along the entire character path
FORBIDDEN ELEMENTS:
- Random decorative dots or shapes anywhere
- Swirls, flourishes, or artistic embellishments
- Uneven or inconsistent dot spacing
- Characters of different sizes in the same row
- Floating or disconnected character parts
- Any shapes not part of the traceable characters
- Background decorations or patterns
WORKSHEET STRUCTURE — CRITICAL SPACING:
- Title area (y=30-60): Small title as SOLID black text (NOT dotted), font-size 24px, centered at y=50
- For words: "Trace: [WORD]"
- For numbers: "Trace the Numbers"
- LEAVE EMPTY SPACE between y=60 and y=150 — NO content here!
- Row 1 (y=180-260): Full dotted characters to trace — tops at y=160, bottoms at y=260
- Row 2 (y=300-380): Same characters, slightly lighter (stroke='#888888')
- Row 3 (y=420-480): Empty baseline only (solid line at y=450, stroke-width='1', stroke='#CCCCCC')
- Baseline guides: Add thin gray lines under each character row
STYLE FOR NUMBERS (if tracing numbers):
- Simple, clear digit shapes: 1, 2, 3, 4, 5, 6, 7, 8, 9
- Consistent sizing and spacing
- School-style number forms
STYLE FOR LETTERS (if tracing words):
- Use basic school-style uppercase letters
- Simple straight lines and gentle curves
- Maximum 4 letters per word
${baseRules}
${ageRules(age)}
${jsonStructure('writing')}
`,
'find-way': (theme, age) => `
You are a puzzle designer creating fun maze worksheets for young children.
Theme: ${theme}
Age: ${age} years old
YOUR MISSION: Create a SIMPLE, LOGICAL, and clearly SOLVABLE maze for young children.
⚠️ STRICT ACTIVITY RESTRICTION — THIS IS A MAZE/PATH-FINDING WORKSHEET ONLY:
- DO NOT include any numbers, digits, or counting exercises
- DO NOT include any letters, words, or writing practice
- DO NOT include large coloring areas — the maze IS the main activity
- The ONLY activity is finding the path through the maze from start to finish
🔴 CRITICAL MAZE LOGIC RULES — MUST FOLLOW EXACTLY:
1. USE A SIMPLE GRID STRUCTURE: Build the maze on an invisible 5x5 or 6x6 grid
2. CORRIDORS MUST BE STRAIGHT: Only horizontal and vertical paths, meeting at 90° angles
3. PATH WIDTH: Exactly 40px wide corridors — consistent everywhere
4. WALLS: Solid filled rectangles (not lines), exactly 10px thick, black fill
5. ONE CLEAR SOLUTION: There must be exactly ONE path from start to finish — no alternate routes
6. DEAD ENDS: Maximum 2-3 short dead ends (1-2 cells deep only)
7. NO OVERLAPPING: Paths never cross or overlap — walls completely separate all corridors
8. NO AMBIGUITY: Every junction must have clear wall boundaries — no gaps or unclear areas
MAZE STRUCTURE (follow this pattern):
- Draw a rectangular outer border (10px thick black rectangle)
- Inside, create corridors by placing rectangular wall blocks
- Corridors are the WHITE SPACE between walls
- START: Top-left area with a small themed icon (arrow or character)
- FINISH: Bottom-right area with a themed goal icon (star, treasure, home)
- Solution path should have 4-6 turns maximum
SVG CONSTRUCTION METHOD:
1. Draw outer border: <rect x='10' y='10' width='480' height='480' fill='none' stroke='#000' stroke-width='10'/>
2. Add internal walls as filled black rectangles: <rect x='...' y='...' width='...' height='...' fill='#000'/>
3. Corridors are the remaining white space (no need to draw them)
4. Add START icon at entrance
5. Add FINISH icon at exit
FORBIDDEN IN MAZES:
- Curved or diagonal paths
- Walls that don't connect properly (gaps)
- Paths that seem to go through walls
- Multiple possible solutions
- Dead ends longer than 2 grid cells
- Unclear or ambiguous junctions
${baseRules}
${ageRules(age)}
${jsonStructure('find-the-way')}
`,
counting: (theme, age) => `
You are an educational illustrator creating counting practice worksheets for young children.
Theme: ${theme}
Age: ${age} years old
YOUR MISSION: Create a fun counting exercise where children count themed objects and write the number.
⚠️ STRICT ACTIVITY RESTRICTION — THIS IS A COUNTING WORKSHEET ONLY:
- DO NOT include any mazes, paths to follow, or puzzles
- DO NOT include any letters, words, or writing/tracing practice (except answer boxes)
- DO NOT include large coloring illustrations — only countable themed objects
- DO NOT show the answers/numbers already filled in — leave answer boxes EMPTY
- DO NOT include number recognition (showing big numbers) — this is COUNTING objects
- The ONLY activity is counting groups of objects and writing the total in empty boxes
- Focus EXCLUSIVELY on groups of themed objects to count with empty answer boxes
COUNTING WORKSHEET SPECIFIC RULES:
- Create 3-5 GROUPS of themed objects to count
- Each group should have a DIFFERENT quantity (e.g., 2, 4, 5, 7, 9)
- Quantities appropriate for age: 1-5 for age 3-4, 1-10 for age 5-7
- Objects within each group must be IDENTICAL and themed
- Add an EMPTY box or circle next to each group for writing the answer (no numbers inside!)
- Objects should be large enough to count easily with a finger point
LAYOUT:
- Use GRID LAYOUT: Groups in rows, empty answer boxes on the right
- Each row: [Group of objects] → [Empty answer box]
- Clear visual separation between different groups
COUNTING-FRIENDLY DESIGN:
- Space objects clearly within groups — no overlapping
- Use familiar arrangements (lines, dice patterns, pyramid stacks)
- Make objects touch-friendly for finger counting
- Vary positions slightly so kids must actually count (not memorize patterns)
${baseRules}
${ageRules(age)}
${jsonStructure('counting')}
`
};
/**
* Get the appropriate prompt for an activity type
*/
export function getPromptForActivity(activityType, theme, age) {
// Map internal IDs to prompt keys
const typeMap = {
'coloring': 'coloring',
'writing': 'writing',
'find-way': 'find-way',
'find-the-way': 'find-way',
'counting': 'counting'
};
const promptKey = typeMap[activityType] || 'writing';
const promptGenerator = activityPrompts[promptKey];
if (!promptGenerator) {
console.warn(`No prompt found for activity type: ${activityType}, falling back to writing`);
return activityPrompts.writing(theme, age);
}
return promptGenerator(theme, age);
}