Eko — Project Context

You are assisting with Eko, a knowledge platform that builds verified, structured fact cards from multiple sources. Users learn through interactive challenges (quizzes, recall, conversational AI) powered by spaced repetition.

Core Loop

Sources → Facts → Validation → Cards → Learning

Three Content Pipelines

PipelineSourceOutputTrigger
NewsNews APIs (NewsAPI, GNews, TheNewsAPI)Facts from clustered articlesCron (every 15 min)
EvergreenAI generationTimeless knowledge factsCron (daily)
SeedCurated entries + API importsBootstrapped topic factsManual/batch

Data Flow (6 Phases)

  1. Ingestion — Fetch articles → deduplicate → cluster into stories
  2. Extraction — AI extracts structured facts from story clusters, scored for notability
  3. Validation — 4-phase pipeline: structural → internal consistency → cross-model → evidence corroboration
  4. Challenge Generation — Pre-compute challenge content per fact across multiple styles
  5. Publication — Validated facts with challenge content become visible in feed
  6. Interaction — Users engage via card interactions with spaced repetition scheduling

Technology Stack

  • Runtime: Bun, Turborepo monorepo
  • Language: TypeScript, Zod schemas for all contracts
  • Frontend: Next.js 16 (App Router), Tailwind v4, shadcn/ui
  • Backend: Supabase (Postgres + RLS), Drizzle ORM
  • Queue: Upstash Redis (11 queue types with DLQ, 3-attempt retry)
  • AI: Vercel AI SDK v6 with 3-tier model routing (default/mid/high) across 7 providers
  • Workers: 3 Bun queue consumers (worker-ingest, worker-facts, worker-validate)
  • Billing: Stripe (Free + Eko+ plans)
  • Quality: Biome (lint/format), Vitest (tests)

Monorepo Structure

apps/
  web/              — Authenticated app (app.eko.day)
  public/           — Marketing site (eko.day)
  admin/            — Admin dashboard (admin.eko.day)
  worker-ingest/    — News fetch, clustering, image resolution
  worker-facts/     — AI fact extraction, evergreen, challenge content
  worker-validate/  — Multi-tier fact validation

packages/
  ai/               — AI model routing, fact extraction, validation
  config/           — Environment configuration and model registry
  db/               — Supabase client, Drizzle ORM schema
  queue/            — Upstash Redis queue client
  shared/           — Zod schemas, TypeScript types, entitlements
  stripe/           — Stripe billing integration
  ui/               — Shared UI components

System Invariants

  1. Fact-first — Facts are the atomic unit; everything flows from structured, schema-validated facts
  2. Verification before publication — No fact reaches the public feed without validation
  3. Source attribution — Every fact traces to source articles and validation evidence
  4. Schema conformance — Facts validate against fact_record_schemas.fact_keys
  5. Cost-bounded AI — All AI calls have model routing, budget caps, and cost tracking
  6. Public feed / gated detail — Feed is public; full detail requires subscription
  7. Topic balance — Daily quotas per topic category prevent content monoculture

AI Model Routing

Three tiers with DB-driven configuration:

  • Default (~92% of calls): Cost-optimized model (currently Gemini 3 Flash Preview)
  • Mid: Structure changes, complex page types, high-change scenarios
  • High: Opus escalation for pricing/legal/API pages with significant changes (capped at 20/day)

Key Database Entities

  • stories — Clustered news articles
  • fact_records — Core facts with status machine (pending_validation → validated/rejected → archived)
  • fact_record_schemas — Per-topic schema definitions (fact_keys + card_formats)
  • fact_challenge_content — Pre-computed challenge content per fact and style
  • card_interactions — User engagement with spaced repetition fields
  • topic_categories — Hierarchical topic tree with daily quotas
  • seed_entry_queue — Seeding pipeline input queue

Queue Types (11)

ingest_news, cluster_stories, extract_facts, import_facts, validate_fact, generate_evergreen, resolve_image, explode_category_entry, find_super_facts, generate_challenge_content, send_sms

When Tradeoffs Appear

Prefer: correctness > auditability > safety > cost control

Commands (always use bun, never npm/yarn/pnpm)

  • bun run dev — Start all apps
  • bun run build — Build all
  • bun run lint / bun run typecheck / bun run test — Quality checks
  • bun run ci — Full CI validation
  • bun run db:types — Regenerate TypeScript types from Supabase

Reel — Video Generation Platform

Reel is a standalone Tauri 2.x desktop app (/Users/jonathansteele/code/reel/) for AI-powered marketing video generation. It is the video production arm of Eko — turning Eko's verified fact cards into broadcast-quality marketing videos.

Relationship to Eko

Eko generates thousands of verified fact cards across 10 categories daily. These facts serve as source content for Reel's video pipeline. A single fact card enters Reel's Stage 1 (Extraction) and emerges from Stage 5 (Render) as a broadcast-quality marketing video ready for paid social, organic content, or product marketing.

Eko Fact Cards → Reel Extraction → Script → Visual + Audio → Render → Marketing Videos

The 5-Stage Pipeline

StageNameServiceDuration
1ExtractionGemini 2.5 Flash~5-15s
2ScriptGemini 2.5 Flash~10-30s
3VisualRunway Gen-4.5Variable
4AudioElevenLabsVariable
5RenderRunPod (RTX 4090)Variable

Stages 1-4 run locally on the desktop app. Stages 3 and 4 run in parallel. Stage 5 dispatches to a RunPod serverless worker. Intermediate assets transit through Cloudflare R2.

14 Video Styles (4 Groups)

  • Narration-First (6): narration-cinema (default), internal-dialogue, scenario-dramatization, comparison-contrast, data-storytelling, explainer-walkthrough
  • Short-Form (2): product-teaser, feature-highlight-reel
  • UI Capture (2): ui-demo-flow, bug-recreation-capture
  • Talking Head (4, require HeyGen): talking-head-presenter, interview-testimonial, social-proof-montage, before-after-reveal

Brand Preset System

A preset is a portable directory defining a brand's entire video identity: tokens, voice configuration, voice cast, audio/visual config, prompt templates, and brand assets. Reel ships with the eko example preset.

presets/your-brand/
  preset.yaml           # Master brand config (id, tokens, voice_cast, defaults)
  voices/               # Voice profiles per voice group
  config/               # audio.yaml, visual.yaml, motion.yaml, pacing.yaml, etc.
  assets/               # Logos, fonts, sounds
  prompts/              # AI prompt templates for extraction and script stages

Character Studio

In-app wizard (/characters/new) for creating AI actors with consistent visual identity:

  1. Define Archetype — role, age range, traits, voice group
  2. Visual Description — archetype prompt, wardrobe, features
  3. Generate Anchors — 20 candidates via Flux 2 Pro, select 3-5
  4. Train LoRA — locks visual identity (~2-5 min, ~$1.20)
  5. Expand Library — generate expressions, poses, lifestyle scenes
  6. Map Presence — drag images to face/hands/wardrobe/environment slots

4 Voice Groups, 8 Actors:

Voice GroupRoleActors
ALEXPrimary NarratorEKO-A01 (Founder/Visionary)
MAYATech ProfessionalEKO-A02 (Analyst), EKO-A05 (Creator/Marketer)
JAMESBusiness ExecutiveEKO-A03 (Manager), EKO-A06 (Small Biz Owner), EKO-A07 (Educator)
SOFIARelatable EverypersonEKO-A04 (Young Professional), EKO-A08 (Everyday Customer)

Eko Brand Context in Reel

The eko preset encodes the full Eko brand voice and identity:

  • Brand voice: Playful, curious, wonder-driven, confident
  • Core promise: "The world is full of things worth knowing."
  • 10 content categories: Sports, History, Science, Culture, Records, Geography, Current Events, Technology, Animals, Art
  • 8 challenge formats: Big Fan Of, Know A Lot About, Repeat After Me, Good With Dates, Degrees of Separation, Used To Work There, Partial Pictures, Originators
  • Anti-pattern vocabulary: Avoid "AI", "trivia", "algorithm", "content", "consume", "users", "gamification", "curated", "engagement", "quiz" — use Eko-specific replacements instead

Tech Stack

LayerTechnologies
ShellTauri 2.x (Rust backend, ~5 MB binary)
FrontendReact 19, Vite 6, Tailwind CSS v4, shadcn/ui
StateZustand (UI) + TanStack Query (async)
DatabaseSQLite (bundled rusqlite, 10 tables)
AIGemini 2.5 Flash, Runway Gen-4.5, ElevenLabs, fal.ai
RenderingRunPod (RTX 4090), Remotion, FFmpeg 6.x+
StorageCloudflare R2
ToolingTypeScript 5.7, Biome, Vitest 3, Bun

Key Codebase Locations

PathPurpose
src/React 19 frontend (file-based routing)
src-tauri/src/commands.rsIPC command handlers
src-tauri/src/db/SQLite schema + queries (10 tables)
src-tauri/src/api/API clients (Gemini, Runway, ElevenLabs, RunPod, R2)
src-tauri/src/pipeline/5-stage pipeline orchestration
src-tauri/src/preset/YAML preset loader and validator
packages/reel-schemas/Shared Zod schemas (@reel/schemas)
apps/worker-reel-render/RunPod serverless worker (Bun + FFmpeg)
styles/14 YAML video style definitions
presets/eko/Eko brand preset

Development Commands (always use bun)

bun tauri dev          # Start Tauri app (hot reload)
bun run dev            # Frontend only
bun run build          # TypeCheck + Vite build
bun run test           # Run all tests (Vitest)
bun run lint           # Biome check (read-only)
bun run check          # Biome check + auto-fix
cargo check            # Type check Rust code (from src-tauri/)

Build Status

Phase 0 complete — app shell, settings, doctor checks, preset loader, 14 video styles, FFmpeg sidecar, CI, Gemini integration.

Next up: Phase 1 — Extraction and Script pipeline (Stages 1-2).

PhaseFocusStatus
0Shell and infrastructureComplete
1Extraction and Script pipeline (Stages 1-2)Next
2Wizard UI, API clients, Character StudioPlanned
3Visual and Audio pipeline (Stages 3-4)Planned
4Remotion compositions, render pipeline, exportPlanned
5Batch system, polish, extensionsPlanned

Per-video cost: ~$0.30-0.60 at scale. Monthly cost: ~$20-82 without HeyGen.