# Persona Generation Guide `pkg/personagen` provides a complete pipeline for generating synthetic persona profiles with biological DNA, personality psychology, lifestyle preferences, a 20-position image matrix, and 4-motion-type video specs. ## Overview A `PersonaSpec` is the top-level output — it contains: - **CoreIdentity**: name, age, gender, ethnicity, occupation, location - **DNA**: immutable biological characteristics (face, body, voice) - **Psychology**: HEXACO personality profile, attachment style, values - **Lifestyle**: interests (5 categories), fashion sense (15 contexts), vacation style - **ImageMatrix**: 20-position image generation specs (4 tiers: Identity, Expressions, Angles, Context) - **Videos**: 4 video specs (smile_reveal, personality_moment, lifestyle, invitation) ## Generation Flow ``` POST /api/{service}/persona/generate → "persona_generate" job enqueued → 202 {jobId} → Worker picks up job → personagen.Service.GenerateSpec() → 5-stage LLM pipeline → personagen.Service.GenerateImages() → 20 image positions (position 1 = anchor first) → personagen.Service.GenerateVideo() → 4 video motion types → SSE events delivered to user: ``` ## 5-Stage Spec Pipeline | Stage | What it does | LLM calls | |-------|-------------|-----------| | 1 | Identity: name, age, ethnicity, occupation, location | 1 | | 2 | Psychology: HEXACO scores, attachment, values | 1 | | 3 | Lifestyle: interests, fashion context, vacation style | 1 | | 4 | Visual DNA: all face/body/voice characteristics | 1 | | 5 | Populate image matrix from lifestyle (no LLM needed) | 0 | Total: **4 LLM calls** per persona spec. ## Image Matrix Tiers | Tier | Positions | Focus | |------|-----------|-------| | 1 – Identity | 1–5 | Core look, position 1 is the anchor | | 2 – Expressions | 6–11 | Personality through facial expressions | | 3 – Angles | 12–16 | Camera angle variety | | 4 – Context | 17–20 | Situational lifestyle shots | **Position 1 is always generated first** and becomes the anchor image for all subsequent positions (passed as `ReferenceImage` to the mediagen provider). ## HEIA Prompt Structure Images use the HEIA (High-Engagement Influencer Aesthetic) prompt format: ``` [IDENTITY] 26-year-old Korean woman, 5'4" (163cm), slender build. [FACE] oval face with high cheekbones, defined jawline, almond-shaped dark brown eyes... [BODY] slender build, narrow shoulders, 0.72 WHR, upright posture. [POSE] mid distance, 3/4 angle, standing, soft gaze expression, slight over-shoulder turn. [CLOTHING] crisp white off-shoulder blouse, minimal gold jewelry — slim, structured. [SCENE] neutral light background, subtle gradient. [CONSTRAINTS] WOMAN SUBJECT ONLY. Human body has EXACTLY 2 arms, 2 legs, 10 fingers total... ``` ## SSE Events Subscribe to `user:` channel before calling the generate endpoint: ```json {"type": "persona_spec_started", "jobId": "...", "message": "Generating persona profile..."} {"type": "persona_spec_complete", "jobId": "...", "result": {"personaId": "ps_abc123"}} {"type": "persona_image_started", "jobId": "...", "result": {"position": 1}} {"type": "persona_image_progress", "jobId": "...", "progress": 45, "result": {"position": 9, "url": "..."}} {"type": "persona_image_complete", "jobId": "...", "progress": 100, "result": {"personaId": "..."}} {"type": "persona_video_started", "jobId": "...", "result": {"motionType": "smile_reveal"}} {"type": "persona_video_complete", "jobId": "...", "result": {"motionType": "smile_reveal", "url": "..."}} {"type": "persona_video_failed", "jobId": "...", "error": "smile_reveal video failed: ...", "result": {"motionType": "smile_reveal"}} {"type": "persona_failed", "jobId": "...", "error": "Spec generation failed: ..."} ``` ## Environment Requirements Both AI providers must be configured for persona generation to work: | Env Var | Purpose | |---------|---------| | `LAOZHANG_API_KEY` | Image and video generation (Flux, Kling) | | `GEMINI_API_KEY` | Text generation (Gemini) + additional media (Imagen, Veo) | These are auto-injected by rdev into every deployed service. Locally, source from `.secrets`. ## Using the Service Directly ```go // Create the service svc := personagen.New(textgenMgr, mediagenMgr, store, logger.Logger) // Generate a full persona spec (5-stage LLM pipeline) spec, err := svc.GenerateSpec(ctx, personagen.SeedParams{ Description: "confident Latina entrepreneur who loves fashion and travel", Gender: "woman", Name: "Sofia Reyes", // optional }) if err != nil { return err } // Generate all 20 images (position 1 first, sets anchor automatically) if err := svc.GenerateImages(ctx, spec, nil); err != nil { return err } // Generate a specific video videoSpec, err := svc.GenerateVideo(ctx, spec, persona.MotionSmileReveal) // Generate utility images avatarBytes, err := svc.GenerateAvatar(ctx, spec) bannerBytes, err := svc.GenerateBanner(ctx, spec, "lifestyle") ``` ## Fashion Contexts 15 named fashion contexts are available in `pkg/persona`: | Context Name | Style | |-------------|-------| | `classic_minimalist` | Clean lines, neutral palette | | `streetwear_chic` | Urban oversized fits, sneakers | | `bohemian_free_spirit` | Flowing fabrics, earth tones | | `athleisure_pro` | Performance fabrics, gym-to-street | | `business_casual` | Polished professional with comfort | | `romantic_feminine` | Florals, lace, pastels | | `edgy_alternative` | Dark palette, leather, hardware | | `coastal_casual` | Relaxed, beachy, linen | | `urban_professional` | Sharp city-dweller aesthetic | | `festival_glam` | Bold prints, glitter, maximalist | | `preppy_classic` | Collegiate, polo shirts, chinos | | `dark_academia` | Literary, tweed, earth tones | | `cottagecore` | Prairie dresses, pastoral romance | | `y2k_revival` | Low-rise, metallics, early 2000s | | `luxe_loungewear` | Elevated comfort in premium fabrics | Use `persona.AllFashionContexts()` for the full catalog or `persona.FashionContextFor(name)` for a single context. ## Motion Types | Motion Type | Description | Duration | Aspect | |------------|-------------|----------|--------| | `smile_reveal` | Warm genuine smile moment | 5s | 9:16 | | `personality_moment` | Expressive personality showcase | 8s | 9:16 | | `lifestyle` | Contextual lifestyle shot | 8s | 16:9 | | `invitation` | Direct-address to viewer | 5s | 9:16 | ## Errors | Error | Cause | |-------|-------| | `ErrAnchorNotSet` | `GenerateVideo()` called before position 1 image was generated | | `"mediagen not configured"` | No AI provider keys set | | `"stage N X: ..."` | LLM call or JSON parse failure in specgen pipeline |