yeah so ummm i kinda liked this girl and she'd text "sleeping in ur arms sounds rly good" then not reply for 6 hours. instead of going to therapy i built this.
You screenshot your DMs, a local vision model OCRs them, and a scoring algorithm turns each day of texting into a single number from -1.0 (cooked) to +1.0 (wedding). Then it runs actual Pearson correlations with p-values on your habits, because if the link between my double-texting and her ghosting isn't statistically significant, I'm choosing to ignore it. A local LLM reads the whole thing back to you like a sports commentator reviewing game tape.
Everything runs on your machine. The screenshots never leave the device, there's no API key, and there's no network call except to localhost:11434 where Ollama lives. Her texts are nobody else's business, including some cloud provider's.
"past vibe performance is not indicative of future results"
The fun part isn't the joke, it's that the stats are real and hand-rolled. The Pearson correlation coefficient and the two-tailed p-value (t-distribution via a regularized incomplete beta function, continued-fraction expansion) are written from scratch in pure Python with no numpy and no scipy. They match scipy.stats.pearsonr to within about 1e-10 on the cases I checked, which the test suite pins down so it stays that way.
On the bundled synthetic dataset (110 days, ~1,400 messages), the one feature that comes back significant is my own average message length: r = -0.37, p < 0.001. Longer texts from me correlate with worse days. The data politely told me to stop writing essays.
- Screenshot ingestion - drop chat screenshots from iMessage, Instagram, WhatsApp, Snapchat, or whatever, into
screenshots/. Theminicpm-vvision model reads each bubble and tags who said what (right-side bubbles = me, left-side = her). - Vibe scoring - a weighted score per day in
[-1.0, +1.0]built from response time, message-length ratio, enthusiasm markers, engagement, who texted first, and a ghost penalty. - Correlation analysis - Pearson
rand p-values for day-of-week, time-of-day, gap since last message, my message length, and double-texting, against the daily vibe score. - AI briefing - a local LLM (
qwen2.5:32b) reads your trends and patterns and delivers a sports-commentator-style daily briefing. - Terminal dashboard - an ASCII vibe-trajectory graph, today's score, a DEFCON 1-5 threat level, and a confidence breakdown.
- Reply suggestions - drafts ghost-proof next messages in your own texting style, with SAFE, BOLD, and WILDCARD options.
You need Python 3.8+ and Ollama for the OCR and LLM parts. The analytics layer (seeding, scoring, correlations) runs on pure standard library with no Ollama and no pip install.
# Try it on synthetic data first, no models needed:
python seed_mixed_signals.py # seeds ~1,400 fake messages over 110 days
python score_vibes.py # scores every day
python vibe_correlations.py # the statistics
# For the LLM features, install Ollama and pull the models:
ollama pull qwen2.5:32b # briefing + commentary
ollama pull minicpm-v:8b # screenshot OCR
ollama serve
python dashboard.py # the full dashboard with DEFCON level
python delulu_detective.py # the long-form AI briefing
python suggestion_engine.py # reply drafts in your style# drop .png/.jpg files into screenshots/, then:
python ingest.py # OCR -> parse -> insert -> rescore
python ingest.py --reset # wipe the db and start overProcessed screenshots move to screenshots/processed/. Everything is OCR'd locally and the originals are gitignored so they never end up in version control.
Each day's messages collapse into one score. Six factors, weighted:
| Factor | Weight | What it measures |
|---|---|---|
| Response time | 25% | how fast she replies |
| Length ratio | 20% | her message length vs mine |
| Ghost penalty | 15% | texting into the void with no reply |
| Initiation | 15% | who texted first |
| Enthusiasm | 15% | !, :), <3, repeated chars |
| Engagement | 10% | questions and "you/your" references |
The weights sum to 1.0 and the final score is clamped to [-1.0, +1.0]. One honest caveat: any day where she replies at least once carries a small fixed +0.3 "she didn't ghost" credit, so a normal two-sided conversation starts slightly positive. That's a deliberate choice, and it's documented in score_vibes.py.
screenshots/ --ingest.py--> mixed_signals.db --score_vibes.py--> daily_vibes
(minicpm-v OCR) (sqlite) (the algorithm) |
v
data_engine.py / pattern_detector.py (read + aggregate)
|
+-------------------------+-------------------------+---+
v v v
vibe_correlations.py dashboard.py suggestion_engine.py
(Pearson + p-values) (DEFCON + ASCII graph) (reply drafts, qwen2.5)
The data sits in a single SQLite file. Ingestion and the LLM stages talk to Ollama over HTTP on localhost; nothing else touches the network.
| File | Role |
|---|---|
ingest.py |
screenshot OCR pipeline (vision model) |
score_vibes.py |
the daily vibe-scoring algorithm |
vibe_correlations.py |
hand-rolled Pearson r + p-values |
data_engine.py |
trend, confidence score, correlation queries |
pattern_detector.py |
word impact, ghost triggers, timing patterns |
dashboard.py |
terminal dashboard, DEFCON level |
suggestion_engine.py |
reply drafting in your style |
delulu_detective.py |
long-form AI briefing |
seed_mixed_signals.py |
synthetic data seeder |
python -m pytest tests/ -q31 tests, runs in well under a second, no Ollama required. They cover the scoring functions, the correlation math (pinned against scipy-verified values), and an end-to-end run of the no-model analytics path: seed, score, then read trend, confidence, and correlations back out.
This is not financial advice. Past vibe performance is not indicative of future results. deluluisnotthesolulu is not a licensed therapist, relationship counselor, or functioning adult.
powered by love for juice wrld and a $600 mac mini