Daily Inspiration
Daily Inspiration Delivers a daily 10-card mixed inspiration set: 3 videos, 3 Wikipedia article prompts, and 4 OpenMates feature tips, with zero LLM latency ...
Daily Inspiration
Delivers a daily 10-card mixed inspiration set: 3 videos, 3 Wikipedia article prompts, and 4 OpenMates feature tips, with zero LLM latency at display time.
Why This Exists
Provides curiosity-driven content from independent educators, journalists, documentary makers, and Wikipedia articles, plus static OpenMates feature tips. Content inspirations include a phrase, pre-written assistant response, and follow-up suggestions so users can start a chat instantly. Logged-out product feature cards use concise editorial headlines from product_features.yml; authenticated feature tips can deep-link to settings instead of creating chats.
How It Works
Generation Pipeline
Runs in app-ai-worker Celery container:
- Topic filtering – removes OpenMates refs, sensitive content, corporate/greenwashing framing via keyword blocklists in
generator.py - Brave Video Search – appends “educational independent creator” to bias toward independents; safesearch=strict, 20 results per slot
- YouTube-only + family-friendly filter – rejects non-YouTube and
family_friendly=False - Anti-corporate filter – seed blocklist (119 patterns in
corporate_channel_patterns.yml) + Mistral Small LLM classifier for remaining channels (fails open) - YouTube Data API enrichment – view count, duration, published_at, made-for-kids status
- Made-for-kids filter – rejects videos YouTube marks as Made for Kids before ranking or LLM selection
- Sort by view count – top 20 candidates per slot
- Main LLM call – single Mistral Small call for the 3 video slots; selects best videos and writes phrase/title/assistant_response/category/follow_up_suggestions
- Wiki generation – one cheap LLM call proposes Wikipedia article titles from the same recent topic pool, validates them via
batch_validate_topics(), then fetches summaries through the Wikimedia provider - Feature tips – four static OpenMates feature cards from
feature_suggestions.py, no LLM/API cost - Daily order – the 10-card set is shuffled once per user per UTC day before delivery and persisted in that order
Generation Triggers
| Trigger | When | Count | File |
|---|---|---|---|
| First paid request | After first paid request post-processing | 10 | daily_inspiration_tasks.py |
| Scheduled daily | 06:00 UTC Celery Beat | 10 if viewed_count > 0 | daily_inspiration_tasks.py |
| Default selection | 06:30 UTC Celery Beat | Mixed top 10 per language | default_inspiration_tasks.py |
Delivery
Authenticated users: Generated -> stored in Redis (7-day TTL) -> broadcast via WebSocket if online -> delivered on login if offline. Cross-device persistence via encrypted Directus user_daily_inspirations table.
Unauthenticated web users: The new-chat landing keeps its local six-slide OpenMates onboarding carousel. This guest-only source is never persisted as authenticated Daily Inspiration data.
Public and authenticated fallback clients: At 06:30 UTC, pool entries are scored per language (interaction_count / (age_hours + 1)) and a 3-video, 3-wiki, 4-feature target is written to daily_inspiration_defaults. GET /v1/default-inspirations?lang={code} exposes the credit-free public fallback with a 1-hour cache. Authenticated clients use it only when personalized IndexedDB, Phase 1, live WebSocket, and account API recovery provide no usable records.
Frontend
DailyInspirationBanner.svelte– carousel of up to 10 cardsdailyInspirationStore.ts– Svelte store for state/navigation and explicit guest/personalized/public/fallback source prioritydailyInspirationDB.ts– IndexedDB with AES-GCM encryption, 72h TTLproduct_features.yml– logged-out OpenMates feature headline registry- Chat creation:
handleStartChatFromInspiration()inActiveChat.svelte
Data Structures
Pydantic Models (schemas.py)
DailyInspirationVideo– youtube_id, title, thumbnail_url, channel_name, view_count, duration_seconds, published_atDailyInspirationWiki– title, wiki_title, description, thumbnail_url, wikidata_id, extractDailyInspirationFeature– feature_id, icon, title, description, settings_pathDailyInspiration– inspiration_id, phrase, title, assistant_response, category, content_type, video, wiki, feature, generated_at, follow_up_suggestions
Directus Tables
| Table | Purpose |
|---|---|
daily_inspiration_pool |
Shared cleartext pool, capped at 100 |
daily_inspiration_defaults |
Top 3 per language per day |
user_daily_inspirations |
Per-user encrypted records |
Cache Keys (Redis via cache_inspiration_mixin.py)
| Key | TTL | Purpose |
|---|---|---|
| Topic suggestions | 72h | 3-day rolling window of user interests |
| Paid request tracking | 48h | Eligibility for next-day generation |
| Pending delivery | 7 days | Offline user inspiration queue |
| Sync cache | 10 min | Deduplication during multi-device sync |
Edge Cases
- LLM classifier failure: Fails open – candidates proceed unfiltered rather than dropping all content
- Video cost remains capped: existing 3-video/day budget is unchanged
- Wiki cost: one small LLM call plus free Wikimedia API requests
- Feature cost: static/no external API calls
Related Docs
- Message Processing – topic extraction via post-processing
- E2E test:
frontend/apps/web_app/tests/daily-inspiration-chat-flow.spec.ts