PYTHIA: an ambient news monitor powered by an LLM
TL;DR
PYTHIA is an ambient news monitor: it ingests feeds, asks an LLM to rate their criticality, and deforms a sphere on a dedicated screen when something steps out of the ordinary.
In Westworld, Rehoboam is a giant black sphere that watches the world and computes its divergences. I always found the object more fascinating than the plot. So I built it, in a much more modest form. PYTHIA runs on a dedicated screen in a corner of the apartment: it ingests feeds, asks an LLM to rate their criticality, and deforms a sphere when something steps out of the ordinary. No interaction, no authentication, no buttons. An object you look at, not one you use.
Why build a screen that does nothing?
That is exactly the point. A classic dashboard asks you to go check it, to read graphs, to interpret. PYTHIA does the opposite: it stays silent as long as everything is nominal, and only catches the eye when an event deserves attention. The sphere spins slowly, almost still. When a divergence arrives, it slows, freezes, then deforms at the emission angle of the event. The strength of the deformation tracks the criticality. You sense that something is happening before you have even read the text.
This is what I call an ambient object. It lives in the periphery of attention. Most of the time it says nothing, and that is exactly what I want from it.
An LLM as a classification engine, not a chatbot
The core of PYTHIA is not a conversation. Every event (an RSS headline, an up/down transition from Uptime Kuma, a webhook) is sent to an OpenAI-compatible endpoint with a strict instruction: return JSON only. No explanation, no markdown, just a structured object with a criticality score from 1 to 10, a category, a summary and a location.
The scale runs from NOMINAL (1 to 3) to CRITICAL DIVERGENCE (10), passing through DIVERGENCE and INTERVENTION IN PROGRESS. The evaluator checks that the category actually matches the criticality range, and retries the model if it does not. Reasoning models sometimes slip blocks of thought in before the answer: a cleanup step strips them out, and a regex fallback recovers the JSON when direct parsing fails. Three attempts, then the event is dropped. Better a missing data point than a wrong one shown on a big screen.
The LLM is therefore just a classifier. All the value lives in that constraint: I do not ask it to be clever, I ask it to be consistent.
Any LLM will do, even one running on a Jetson Orin Nano Super
The first version ran the model locally. I started on a NUC, then moved to a Jetson board for GPU inference. The commits from that period tell the struggle: dropping the context to 2048 tokens, capping the outputs, disabling reasoning mode, switching to streaming to avoid timeouts on slow hardware. A lot of energy spent squeezing a big model into a thermal envelope.
But that struggle missed the point. The job is narrow: read a short text, return a small JSON object with a score and a category. It does not need a frontier model, and it does not need much compute. Almost any LLM handles it, even a small one running locally on a Jetson Orin Nano Super. Today PYTHIA points at a free OpenRouter model, mostly for convenience, but nothing forces that choice.
That is the real payoff of going through an OpenAI-compatible API: the model becomes a commodity. Switching from a free cloud endpoint to a local board is one environment variable. The lesson I keep: when the task is this undemanding, portability through an API contract matters far more than the model behind it.
The sphere that deforms, without a 3D library
Visually, it is a geodesic sphere rendered in Canvas 2D. No Three.js, no WebGL. A Fibonacci-spiral node distribution, a proximity mesh, a hand-rolled projection inside the animation loop, a veil of dust and a frost rim. The whole thing reacts to four states: idle, analyzing, divergence, return to calm. A critical event stays on screen for 35 seconds, a minor one for 8, and the pending queue is sorted by descending criticality.
Around it, a discreet HUD shows the time, system metrics (CPU, RAM, disk, plus GPU and temperatures when the machine exposes them), the health of each source and the LLM model in use. The aesthetic is monochrome, deliberately cold. It is an instrument, not a demo.
What is left, and what is good enough
PYTHIA is in maintenance mode today, and that is good news. Deployment is fully automated: a push to main runs the backend and frontend tests on a self-hosted runner, rebuilds the containers, waits for the health check and runs smoke tests. Adding a source means writing a class that inherits from BaseSource and registering it. Nothing is hardcoded, everything goes through config.
I never tried to turn it into a product. No database (an in-memory queue of the last 100 events is enough), no authentication (it is a local network tool), no feature I would not use myself. The object does what I wanted: turn a stream of information into a calm presence that only stirs when the world diverges.
Sometimes the best sign that a project is finished is that you no longer want to touch it. You just want to watch it run.
The code is open source: github.com/ycnslh/pythia.