v0.7-learning·local-first · MIT · Python + TypeScript

Your inbox, triaged
on your machine.

Winnow is a self-hosted Gmail triage agent. A small classifier on your laptop handles 80%+ of routing in milliseconds. An LLM sees only the cases the classifier isn't sure about — and only if you opt in with your own API key.

200 synthetic emails·real live classifier in your browser session·pre-recorded LLM responses·zero visitor cost
architecture

Two tiers. One decision per email.

Existing "AI inbox" tools are either hosted SaaS that see all your email, or thin wrappers that call an LLM on every message. Winnow does neither.

Gmailincoming emailvia Pub/SubTIER 1 — LOCAL, ~FREEscikit-learn + MiniLMengineered features + 384-dim embeddings~5 ms per email, CPU-onlyhandles 80%+ of routingconfidentuncertainDECISION FINALroute to lane, doneno network, no LLM costTIER 2 — LLM, OPT-INPydanticAI agentAnthropic / OpenAI / Ollamatriage + draft, your key, your machine
tier 1 · local · ~free
scikit-learn LogReg over engineered features + MiniLM subject embeddings. Retrains nightly on your own drag actions.
tier 2 · LLM · opt-in
PydanticAI agent with structured output. Escalated only when tier 1's confidence falls below your threshold. Your key, your provider, your machine.
learning loop
Every action — archive, star, drag between lanes, edit draft — becomes a labeled training example the classifier will see tomorrow.
evals

Numbers, not vibes.

Tier 1 baseline, measured by 5-fold cross-validation on the current 200-email synthetic corpus. The full harness (pure-LLM vs pure-classifier vs tiered on a held-out realistic set with per-1000-email cost + latency) lands with v1.0.

laneprecisionrecalllatency (p50)cost / 1k emails
needs_you1.001.00~5 ms$0.00
informational1.001.00~5 ms$0.00
hidden1.001.00~5 ms$0.00

honest caveat: 100% on synthetic data is a plumbing check, not a quality claim. The synthetic ground truth is deterministic from category, and the sender-domain features leak that signal. The v1.0 eval uses noised labels + held-out real Gmail categories.

how the demo works

$0, guaranteed. Honest about it.

live in your browser
Tier 1 classifier

Runs genuine inference on every card. Retrains on your drags within your session. Session state is namespaced by cookie; nothing bleeds between visitors.

pre-recorded
Tier 2 LLM responses

Every "ask LLM" click resolves to a committed fixture, generated once against a real Anthropic call. The demo simulates the real latency (~1.2 s) and streams the response. Zero API calls happen when you click.

why the split matters

The classifier is free to run for real — CPU only, no API. The LLM tier is where the money would go, so the demo hard-codes it: every tier-2 response is a packages/seed-data/llm-responses/{seed_id}.json file committed to the repo. Novel emails you add during the session return a graceful "run locally with your own key" card instead. This is the whole point of the two-tier architecture in one sentence.

explicitly out of scope

What Winnow won't do

  • · Multi-account support (one Gmail, one owner)
  • · Non-Gmail providers (Fastmail, Outlook, etc.)
  • · Team or shared inboxes
  • · Mobile app
  • · Calendar integration
  • · Auto-sending replies (drafts only)
  • · Live LLM calls in this public demo
  • · Hosting Winnow-as-a-service for other people's inboxes