features

Odessa — Personalized Story Generator

"The human field beneath the signal."

Odessa reads a user's journal entries, life map, mood history, and personal context, then generates a personalized graphic novel story — with different names, fantastical settings, but emotional dynamics that mirror the user's real patterns. The goal: help people get unstuck through entertainment that resonates with them directly.

Named after the original Odessa prototype — the breathing field that quietly stewards human adaptability.

How it works

1. Data ingestion

Odessa reads (server-side, never sent externally as raw data):

SourceWhat it readsWhat it's used for
Journal entriesContent, mood, tags, @mentionsIdentifying themes, emotional patterns, relationships
Life Map nodesPeople, projects, topics, emotions, places + edgesMapping real people → fictional characters
Satisfaction/energyMood levels over timeDetermining emotional tone of the story
Weekly reviewWins, open loops, mood trendIdentifying what's unresolved
Family membersNames, relationships, agesAdding family dynamics to the narrative

The lookback window is user-configurable: 7 / 14 / 30 / 90 days / all time (default: 14 days).

2. Story seed generation

A single GPT-4o-mini call with a structured system prompt that instructs the LLM to:

  1. Identify the dominant emotional theme — what's stuck, what's thriving, what's unresolved
  2. Map real people to fictional characters — change names, keep relational dynamics. The inspired_by field is shown privately to the user.
  3. Choose a metaphorical setting — a fantastical world that mirrors the emotional landscape. Steampunk workshop for a builder. Underwater city for someone feeling submerged. A returning-light world for someone processing grief.
  4. Design a 3-act arc — Act 1 mirrors the current state. Act 2 explores what happens if the protagonist leans into the fear. Act 3 offers a resolution the user might not have considered.
  5. Generate the art style — matched to the emotional tone. Dark crosshatch for heavy themes. Warm watercolor for grief. Neon for excitement.

3. Story seed structure

interface StorySeed {
  title: string
  theme: string                    // "The tension between ambition and rest"
  genre: string                    // "Steampunk adventure"
  art_style: string                // DALL-E style prompt
  setting: string                  // Metaphorical world description
  tone: string                     // Narrative voice
  characters: Array<{
    name: string                   // Fictional name
    inspired_by: string            // "Mapped from: Owen (your son)"
    visual_description: string     // For DALL-E character consistency
    role_in_story: string
  }>
  narrative_arc: {
    act1: string                   // Setup — mirrors user's current state
    act2: string                   // Complication — leaning into the fear
    act3: string                   // Resolution — a new perspective
  }
  opening_prompt: string           // First scene to kick off the chat
  resonance_note: string           // Why this story (addressed to user)
}

4. Flow: seed → graphic novel

  1. User visits /dashboard/odessa
  2. Optionally sets a focus ("I can't stop thinking about...") and lookback window
  3. Clicks "Generate my story seed" → sees the seed card with characters, arc, resonance note
  4. Clicks "Start this story →" → system creates a graphic_novel notebook pre-configured with the seed's art style, characters, setting, tone, and opening conversation
  5. User lands in the graphic novel editor with the opening prompt pre-loaded
  6. Co-development begins through the existing chat → panels → DALL-E pipeline

Architecture

User clicks "Generate"
        ↓
POST /api/odessa/generate-seed
        ↓
odessa.ts gatherUserContext()
  → fetches journal entries, life map, satisfaction, weekly review, family
        ↓
odessa.ts generateStorySeed()
  → GPT-4o-mini with structured JSON output
  → returns StorySeed
        ↓
User reviews the seed card
        ↓
POST /api/odessa/create-story
  → creates a graphic_novel notebook with the seed as config
  → returns notebook_id
        ↓
User redirected to /dashboard/entries/new?notebook={id}
  → GraphicNovelEditor opens with opening prompt pre-loaded
  → co-development begins

Privacy

  • Odessa reads journal data server-side. Raw journal content is never sent to external services — the GPT call sends only excerpts (first 300 chars per entry) + mood + tags + mentions.
  • The StorySeed is the only artifact. It contains no real names (only inspired_by hints shown privately to the user).
  • The graphic novel itself (panels, images, narration) is stored as standard journal entries in the user's own notebook.
  • Deleting the notebook deletes the story. No external copies.

Story lengths

LengthPagesPanelsTimeScene structure
Flash (default)3~102-4 min1 page per act
Short Story9~308-15 min3 scenes per act (deepen world → escalate → climax → resolution)
NovelComing soon (will require job queue for 30+ minute generation)

Short Story sub-prompts are structured for proper narrative pacing: Act 1 deepens the world, Act 2 escalates through failure, Act 3 resolves with an image echoing the opening.

Endpoints

EndpointAuthDescription
POST /api/odessa/generate-seedRequiredReads user data, returns a StorySeed. Accepts { focus?, lookback_days? }
POST /api/odessa/create-storyRequiredTakes a StorySeed, creates a graphic_novel notebook, returns notebook_id
POST /api/odessa/generate-full-storyRequiredTakes a StorySeed + { length: 'flash' | 'short_story' }, creates notebook, auto-generates all pages with DALL-E illustrations
POST /api/odessa/next-episodeRequiredGenerates next episode for an existing Odessa story. Reads journal delta since last episode, computes character stats, feeds into narrative engine
POST /api/odessa/resolve-branchRequiredRecords user's branch choice at a narrative decision point
GET /api/odessa/character-statsRequiredReturns live CharacterStats (energy, resilience, connection, clarity, momentum) derived from 14-day activity window
GET /api/odessa/story-state/:idRequiredReturns persisted story state, character stats, and seed for a notebook

Files

FilePurpose
apps/backend/src/services/odessa.tsAnalysis engine: data ingestion + GPT story seed generation
apps/backend/src/routes/odessa.tsREST endpoints
apps/frontend/src/app/dashboard/odessa/page.tsxDashboard launch page
apps/frontend/src/app/odessa/page.tsxPublic landing page
apps/frontend/src/components/notebooks/CharacterStatsCard.tsxCharacter stats bar display (notebook page + Odessa dashboard)

Character stats

Character stats mirror the user's real-life patterns into their story character's attributes. Computed from a 14-day rolling window:

StatSourceInterpretation
Energy (1-10)satisfaction_quick_values.energy_level averageHigh = character is vibrant/proactive; low = drained/slow
Resilience (1-10)family_routine_checkins done rateHigh = recovers quickly; low = fragile, overwhelmed
Connection (1-10)Unique @mentions across journal entriesHigh = rich relationships/allies; low = isolation
Clarity (1-10)Mood variance (lower = higher clarity)High = sees path ahead; low = fog/confusion
Momentum (1-10)user_tasks completion rateHigh = things are moving; low = stuck

Stats are injected into the generateNextEpisode() GPT system prompt with behavioral descriptors. When stats change between episodes, the delta is noted so GPT can narrate the shift (e.g., "energy rose from 3 to 7 — the character gains strength"). Stats persist on StoryState.character_stats between episodes.

Connection to the broader platform

Odessa is the narrative layer of HiveJournal's "Free the Energy" philosophy:

  • The journal is where you measure your friction (what's draining energy, what's stuck)
  • JQ is the companion that helps you process in real-time
  • The Life Map is the graph of everything you care about
  • Odessa is where all of that becomes a story — because sometimes the only way to see a pattern is to watch a character live through it

The name echoes the original Odessa prototype: "a breathing field — a structure for those who rebuild, remember, and reweave." Now it rebuilds through narrative.

Odessa — Docs | HiveJournal