Inspiration

Project located here: https://o2.agent9.dev/

When wildfire smoke rolled into my city, every app told me the same useless thing: a number. "AQI 175. Unhealthy." Okay — but the question I actually had was when does it get better? Can I run tonight? Keep the kids in tomorrow morning? None of them answered that.

And it isn't a rare problem anymore. More than 4 in 10 Americans — 44% of the country — live where air quality regularly hits unhealthy levels (American Lung Association, State of the Air 2026). Days before I built this, wildfire smoke pushed Minnesota's air into the Hazardous zone statewide — the worst smoke event on record. The smoke is here, it's getting worse, and the tools still only tell you it's bad right now.

O2 exists to answer the question the number can't: when does the air get better?

What it does

O2 is a wildfire-smoke and air-quality companion that forecasts when your air improves — not just how bad it is now.

  • Answers "when it gets better." It reads the next 48 hours of hourly air quality for your exact location and tells you, in plain language, the first hour conditions cross into a better category and the single cleanest window ahead.
  • A live smoke map. Watch modeled smoke drift across the country hour by hour, with the US (NWS NDGD) and Canadian (FireSmoke/BlueSky) models available alone or overlaid to see where they agree.
  • Active wildfires. Every fire on the map is a real incident from NIFC — click a dot or perimeter for its name, size, containment, and a search link, attributed to the National Interagency Fire Center.
  • A spoken briefing. Every location gets a validated, plain-language briefing read aloud by Deepgram Aura on Cloudflare Workers AI.
  • Email alerts. Get notified when your air crosses a line you set — when it turns unhealthy, and again when it's safe. Double opt-in, one-tap unsubscribe.
  • Works everywhere. O2 runs on modeled data (Open-Meteo / CAMS), so it forecasts air quality anywhere — including the roughly one-third of the country with no ground monitor nearby — all on the official US 0–500 AQI scale.

How I built it

I designed O2 with GPT-5.6 — the architecture, feature scope, safety boundaries, and diagrams — in one long session that produced a single handoff document. Then Codex built it from that document: the forecast engine, the AQI rules, the Deepgram Aura voice integration, and the alerts pipeline.

  • Frontend: TanStack Start (SSR) + React 19 + TypeScript, Tailwind CSS, Radix UI, Mapbox GL.
  • Edge/backend: Cloudflare Workers, Cloudflare D1 (SQLite) for subscriptions, Cloudflare Workers AI (Deepgram Aura aura-1) for the spoken briefing, Turnstile for anti-abuse, Resend for email.
  • Data: Open-Meteo on CAMS (air quality + forecast); NIFC WFIGS (fire perimeters & incidents); NWS NDGD and Canadian FireSmoke/BlueSky (surface smoke); NOAA Hazard Mapping System (written smoke narrative); NWS API (local alerts).

One deliberate constraint runs through everything: no language model writes the health advice. The categories, timing, and guidance are fixed rules in code, so the same conditions always produce the same answer. The only AI at request time is the voice — and it reads a script the code already wrote.

Challenges we ran into

  • A real bug Codex fixed on GPT-5.6: early on, O2 claimed wildfire smoke everywhere, because it matched a continent-wide text narrative to every location. Codex wrote the geometry — point-in-polygon plus a haversine distance check — that asks whether a plume is actually near your coordinates. Now it only mentions smoke when there's really smoke near you.
  • Smoke aloft vs. surface smoke: the map shows smoke anywhere in the air column; the AQI measures ground level. Reconciling those two honestly took care.
  • Trustworthy data: local monitors and other apps use different AQI scales — some extend past 1000 — while O2 stays on the official US EPA 0–500 scale via CAMS for one consistent, comparable reading nationwide.
  • Flaky upstreams: NOAA's smoke-narrative endpoint sits behind a WAF that blocks server requests; the fix was browser-like headers plus retries so the edge Worker can still fetch it.
  • Rendering & hydration: Mapbox WebGL, animated smoke layers, and server-vs-client time all behaving under SSR.

Accomplishments that we're proud of

  • It answers the question that matterswhen your air gets better — not just the current number.
  • Nationwide, monitor-free coverage from modeled data, so it works where instruments don't.
  • An honest, deterministic core: same reading, same answer, every time — no hallucinated health advice.
  • Real-time smoke drift plus a two-model (US + Canada) comparison.
  • On-edge spoken briefings via Deepgram Aura on Cloudflare Workers AI, with sourced facts and a smoke narrative straight from NOAA.

What we learned

  • Wildfire smoke is mostly PM2.5, carries coarser PM10, and its gases can raise ground-level ozone downwind — one plume can hit multiple pollutants.
  • AQI scales aren't universal — the same air can read 175 on the US scale and a far bigger number on an extended one.
  • Smoke you can see overhead isn't always smoke you're breathing — it has to mix down first, which is exactly what a forecast can anticipate.
  • For safety-critical information, determinism beats cleverness — keeping AI out of the health advice made the product more trustworthy.
  • A clean design → handoff → build flow (GPT-5.6 → Codex) turns an idea into shipped software fast.

What's next for O2 by Agent9.dev

  • Text (SMS) alerts — the same "your air just crossed a line" notifications, by text as well as email.
  • Global coverage — O2 already runs on the worldwide CAMS model, so forecasting air quality beyond North America is the natural next step.
  • Multi-location subscriptions — watch home, work, and a loved one's town from one account.
  • Sharper confidence — per-source freshness and source-disagreement penalties, so you can see exactly how sure each forecast is.

Built With

Share this project:

Updates

Submission history