▶ Try it live in your browser, nothing to install. Sample content; connect your own sources by running it locally.
A single, streamlined dashboard for everything you need to keep up with (news, academic papers, YouTube, sports), pulled from the sources you connect and laid out as adaptable content blocks.
- Adaptable blocks UI. You choose what shows up. Describe an interest in plain English ("latest Fireship videos", "recent papers on AI in medicine"), and an agent finds, ranks, and populates a block with it. Drag, resize, rearrange.
- Nothing to set up. Papers, YouTube, news, sports, job listings (via Seek, AU/NZ roles) and general web search all read public sources. No API keys, no accounts. Connect Google only if you want your own inbox in there.
- Your briefing. Instead of ten tabs, one agent-written paragraph per page that summarizes what's new and worth your attention.
- Your AI subscription, not an API bill. All AI runs headless through the CLI of whichever provider you already use: Claude (Claude Code), ChatGPT (Codex CLI), or Gemini (Gemini CLI, free with a Google account). No API key, no per-token charges. (An Anthropic API key works as an optional fallback.)
You type one sentence. Three steps run behind it.
flowchart LR
Q["<b>you type</b><br/>'emails from monash uni'"] --> S["<b>supervisor</b><br/>which source?<br/>what search terms?"]
S --> F["<b>connector</b><br/>fetches from<br/>Gmail / arXiv / RSS / …"]
F --> C["<b>critic</b><br/>are these any good?"]
C -->|approved| B["<b>block</b><br/>appears on your grid"]
C -->|"weak: retry with better terms<br/>(max 2 rounds)"| F
1. The supervisor decides where to look. An LLM reads your request and returns
structured output: which source, what to actually search for, how many items, and
a short block title. "emails from monash uni" becomes source gmail, search
terms from:monash.edu, 3 items. Picking the terms is its own skill: Gmail
requires every word to match, so a casual "uni" finds nothing.
2. A connector fetches. Plain HTTP against free, keyless APIs wherever possible (OpenAlex for papers, Google News RSS, ESPN, Seek, and YouTube's public upload feeds). Only Gmail needs your own OAuth token, because only Gmail reads something private.
3. The critic checks the results. A second LLM call reviews what came back and drops anything off topic. If the whole set is weak, it rewrites the search terms and the loop runs again, capped at two rounds so it cannot spin.
Two guard rails sit around that loop, because a self-correcting agent can make things worse: a refinement returning fewer results than the round before it is rejected and the previous set restored, and pruning can never leave a block with fewer items than you asked for.
Every step streams to the browser live over Server-Sent Events, so you watch the agent decide instead of staring at a spinner.
The briefing is deliberately one LLM call. An earlier version fanned out (summarize each block, then combine), costing N+1 calls per briefing. On a subscription metered by request rather than by token, that is the wrong shape. A whole page is a few hundred short lines, comfortably inside a single call.
No API key, by design. app/agents/llm.py shells out to whichever provider
CLI you already have logged in and parses structured JSON back, so inference
bills to a subscription you are already paying for. Anyone who clones this gets
the full agentic version for free. The tradeoff is real: a CLI call takes about
20 seconds against roughly 2 for the API, there is no token streaming, and it
cannot scale to a multi-user server. For a single-user local app that trade is
worth making, and an API key still works as a fallback.
| Layer | Choice |
|---|---|
| Frontend | React 19 + Vite + TypeScript + Tailwind v4 |
| Blocks | react-grid-layout (drag/resize) + zustand |
| Backend | FastAPI (Python) + SQLite |
| Agents | LangGraph: supervisor routes → connectors fetch → critic verifies |
| LLM | Your AI subscription: Claude, ChatGPT, or Gemini via their CLIs, no API key |
| Auth | Google OAuth, for Gmail only — nothing else needs an account |
frontend/ React app (the dashboard + blocks)
backend/ FastAPI: integrations, agents, API
app/integrations/ where content comes FROM (youtube, gmail, papers, news, espn, …)
app/agents/ LangGraph agent pipeline + briefing
scripts/ dev helpers (scripts/dev.sh runs everything)
Four, plus one AI CLI. On macOS:
brew install node python uv # runtimes + the Python package manager
npm install -g pnpm # the Node package managerElsewhere: Node 20+, Python 3.12+, then
curl -LsSf https://astral.sh/uv/install.sh | sh # uv
npm install -g pnpm # pnpmCheck they're all there:
node -v && pnpm -v && python3 -V && uv --versionpnpm is npm's job done differently. latent uses it because it blocks package install scripts by default, which is the main way a compromised dependency runs code on your machine. uv is the same idea for Python: faster than pip, and it pins an exact dependency tree.
ONE of Claude Code (Claude subscription), Codex CLI (ChatGPT subscription), or Gemini CLI (free Google account).
Install it, then run it once and log in with the account you already have:
npm install -g @anthropic-ai/claude-code
claude # opens a browser; log in, then quit with /exitlatent never sees that credential. It shells out to whichever CLI is on your PATH and inherits the session. Skip this step and blocks still fill, but routing falls back to keyword matching instead of the agent.
./scripts/dev.sh # backend on :8000, frontend on :5173, Ctrl+C stops bothOpen http://localhost:5173. Everything works immediately except Gmail,
which reads your own inbox and so needs your consent: copy .env.example to
.env (repo root) and follow docs/oauth-setup.md.
PolyForm Noncommercial 1.0.0. You're welcome to clone this, run it, learn from it, and modify it for personal or research use. Commercial use is not permitted.
Required Notice: Copyright Riddhi Sawant (https://github.com/rid-saw/latent)
